Web項目的WEB-INF目錄使用說明以及重定向與轉發


寫這篇文章的原因是看到了Tomcat下面的Webapps下面的,就想看一下。

總結一下這篇文章的內容:

WEB-INF下面的內容都是只能由服務器級別才能訪問,客戶端並不能訪問。什么是客戶端級別?什么是服務器級別呢?

轉發就是服務器級別,瀏覽器的地址不會變,因為,客戶端發送一個請求,服務器受理之后,發現要請求內容還要再去別的請求,那么轉發就是服務器自己去處理完成。不麻煩客戶端(瀏覽器)了,所以客戶端上面的地址欄不會改變。

 

 

 

重定向:就是客戶端級別的。服務器收到請求后,發現還要去請求別的內容,但是服務器自己不想處理,那么就告訴客戶端,你自己去處理吧,那么客戶端就去請求那個別的內容了。所以客戶端(瀏覽器)地址欄就會改變了。

------------------------------------------------------------------------------------------------------------------------------------------------------

 

 

 

 

以下的內容來自:博客轉載自:http://ykyfendou.iteye.com/blog/2094317

 

 

 

在web項目中,為了安全,可能需要把jsp文件放在WEB-INF目錄下,這樣如果我們的頁面中出現超鏈接a標簽或者js的location.href去直接轉向到WEB-INF下的某一個jsp頁面,那么就會引用不到,因為這樣的請求方式是客戶端的請求,而WEB-INF頁面只對服務端開放,對客戶端是不可見的。這時候我們可以使用action,來進行轉向,我們先去請求一個action,然后由這個action分發到這個WEB-INF下的頁面就可以了。我們可以自己定義一個類似struts1的DispatcherAction的一個action來分發頁面。

 

 

由於WEB-INF下對客戶端是不可見的,所以相關的資源文件,如css,javascript和圖片等資源文件不能放在WEB-INF下,那么如何從WEB-INF下引用非WEB-INF下的文件,以及js,html的frame的框架如何去訪問WEB-INF下的jsp呢?

 

下面對WEB-INF目錄的一些問題進行詳細說明:

 

以一個項目為例:

如下這樣一個代碼目錄:我們把除index.jsp外其他的jsp文件放在WEB-INF下,把css,javascript,圖片放在了webRoot(WebContent)目錄下,然后main.jsp是一個frame的html框架,包含了main1.jsp和main2.jsp兩個文件。

 

1、index.jsp頁面訪問css,js,圖片等文件的時候,自然不用說,因為它不在WEB-INF下,正常的訪問即可:

Html代碼:

<link href="css/login_css.css" rel="stylesheet" type="text/css">

<script type="text/javascript" src="js/login_js.js"></script>

<img alt="" src="image/1.jpg">

 

 

 

2、register.jsp頁面去訪問css,js和圖片的時候,也是不需要添加WEB-INF目錄的,也就是忽略WEB-INF目錄,訪問的時候和index.jsp頁面所在的路徑訪問資源文件是一樣的:

Html代碼:

<link href="css/register_css.css" rel="stylesheet" type="text/css">

<script type="text/javascript" src="js/register_js.js"></script>

<img alt="" src="image/2.jpg">

 

 

3、register.jsp頁面去轉向index.jsp頁面,即注冊頁面有一個鏈接,轉向到登錄界面,由於index.jsp頁面沒有在WEB-INF下,所以可以直接訪問index.jsp頁面的路徑,

 

 register.jsp:

html代碼:

<tr>

    <td></td>

    <td colspan="2" style="float: left; ">

        <button type="button" >注冊</button>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

        <button type="button"  onclick="goLogin()">去登錄</button>

    </td>

</tr>

 

 

在register.jsp頁面中定義了一個botton,然后響應一個onclick事件,

我們在register_js.js中定義這個goRegister ()的js事件:

 

regitster_js.js:

 js代碼:

function goLogin(){

    location.href="index.jsp";

}

 

 

這樣就可以訪問到WebContent目錄中的index.jsp頁面了。

 

4、index.jsp(登錄頁面)有一個鏈接,指向register頁面,如果點擊鏈接,就跳轉到register.jsp中進行注冊,因為register.jsp在WEB-INF下,所以不可以直接使用a標簽去訪問WEB-INF路徑下的文件:

Html代碼:

<a href="WEB-INF/register/register.jsp">去注冊</a>

,或者js的location.href去訪問:

js代碼:

function goRegister(){  

    location.href="WEB-INF/register/register.jsp";

}

這樣兩種方式都是直接請求了WEB-INF路徑,都是無法跳轉的。

 

我們可以建立一個action,struts的action中沒有DispatcherAction,但是我們可以通過通配符來讓一個action的不同方法返回不同的頁面,然后我們去請求這個action中的相應方法即可由這個action從服務器端請求到WEB-INF下的頁面了:

 

下面詳細說明如果進行自定義的分發action來進行頁面的分發:

 

DispatcherAction.java:

package com.yun.test.webinf.action;

import com.opensymphony.xwork2.ActionSupport;
publicclass DispatcherAction extends ActionSupport{
    public String goRegister(){

        return"goRegister";

    }
}

這個action中,我們定義了一個goRegister的方法,這個方法沒有任何邏輯代碼,只是返回一個字符串,然后在struts.xml中我們讓這個字符串指向我們要訪問的WEB-INF下的register.jsp頁面:

 

struts.xml:

 

<action name ="dispatcher" class="com.yun.test.webinf.action.DispatcherAction" >

    <result name ="goRegister">WEB-INF/register/register.jsp</result >

    <result name ="input">/index.jsp</result >

</action >

 

 

然后我們可以在頁面中進行請求DispatcherAction的goRegister方法,然后這個action的goRegister方法就會把頁面轉向到WEB-INF下的register.jsp頁面了:

我們在index.jsp中定義了一個botton,然后給這個botton注冊一個點擊事件:

 

 

index.jsp:

 

 Html代碼:

<tr>

    <td></td>

    <td colspan="2" style="float: left; ">

        <button onclick="checkValues()">登錄</button>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

        <button type="button" id="button1" onclick="goRegister()">去注冊</button>

    </td>

</tr>

 

在index_js.js中定義這個點擊事件為location.href到定義的action的goRegister.action方法中:

login_js.js:

 JS代碼:

function goRegister(){  
  
    location.href="dispatcher!goRegister.action";  
  
}

當然,也可以直接在頁面中使用a標簽來請求這個action的goRegister方法:

    <a href="dispatcher!goRegister.action">去注冊</a>

這樣我們就可以通過action的轉發,成功的請求道WEB-INF下的jsp文件了。

 

 

注意請求action的方式,dispatcher!goRegister.action  這個!是一個分發字符,!之前的部分是action的名字,!之后的部分是這個action的某個我們要請求的方法的名字。然后這個action中必須要定義一個同名的方法,就不需要使用execute方法了。然后這個同名方法,返回的是一個String字符串,這個字符串在struts.xml中指向為我們想要跳轉的路徑。這就是一個請求分發的action。

我們還可以自己定義分發的分隔符,可以是下划線等,分發action詳見Struts2實現分發的action一節

 

 

5、jsp頁面中的frame框架中想把多個WEB-INF下的頁面設置為框架的內容的時候,即使main.jsp和main1.jsp,main2.jsp同在WEB-INF目錄下,也不可以直接去指定WEB-INF路徑,如:

 

<frameset cols="30%,70%">

    <frame src="main/main1.jsp">

    <frame src="main/main1.jsp">

</frameset>

這樣還是不能訪問,也必須使用服務端的action分發的方式進行指定jsp文件的路徑。

 

 

代碼如下:

 

main.jsp:

<%@ page language="java" contentType="text/html; charset=UTF-8"

    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>main</title>
</head>
<frameset cols="30%,70%">

    <frame src="dispatcher!goMain1.action">

    <frame src="dispatcher!goMain2.action">

</frameset>
</html>

struts.xml:

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE struts PUBLIC

    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"

    "http://struts.apache.org/dtds/struts-2.0.dtd">

    

<struts >

    <package name ="test" extends ="struts-default" >

        <action name ="dispatcher" class ="com.yun.test.webinf.action.DispatcherAction" >

            <result name ="goRegister">WEB-INF/register/register.jsp</result >

            <result name ="goMain1">WEB-INF/main/main1.jsp</result >

            <result name ="goMain2">WEB-INF/main/main2.jsp</result >

            <result name ="input">/index.jsp</result >

        </action >

        <action name ="login" class ="com.yun.test.webinf.action.LoginAction" >

            <result name ="success">WEB-INF/main.jsp</result >

            <result name ="input">/index.jsp</result >

        </action >

        <action name ="register" class ="com.yun.test.webinf.action.RegisterAction" >

            <result name ="success">WEB-INF/main.jsp</result >

            <result name ="input">WEB-INF/register/register.jsp</result >

        </action >
  </package>
<!-- 定義struts標簽為無默認樣式 -->

    <constant name="struts.ui.theme" value="simple" />

</struts>

 

 

DispatcherAction.java:

package com.yun.test.webinf.action;

import com.opensymphony.xwork2.ActionSupport;

publicclass DispatcherAction extends ActionSupport{
    public String goRegister(){
        return"goRegister";

    }

    public String goMain1(){
        return"goMain1";
    }

    public String goMain2(){

        return"goMain2";

    }
}

這樣,這個main頁面就可以通過action分發使用frame框架了。

 

 

 

6、同在WEB-INF目錄下的register.jsp和main.jsp中怎么跳轉呢?我們會在register.jsp中提交表單,然后在action中進行處理,如果注冊成功,會跳轉到main頁面,這時的跳轉也會涉及到WEB-INF目錄,因為目標路徑main.jsp也在WEB-INF下,所以我們在跳轉的時候也必須寫上WEB-INF的目錄路徑才可以,而且必須是請求分發,而不能是redirct的方式。

 

如代碼:

 

 

register.jsp:

<%@ page language="java" contentType="text/html; charset=UTF-8"

    pageEncoding="UTF-8"%>

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<html>

<head>

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">

<title>register</title>

<link href="css/register_css.css" rel="stylesheet" type="text/css">

<script type="text/javascript" src="js/register_js.js"></script>

</head>

<body>
    <div id="content" >

    <form action="register.action" id="registerForm"  method="post">
        <table>

            <tr>

                <td width="150px;" style="text-align:center; ">注冊名</td>

                <td width="80px;" style="text-align: left;"><input type="text" name="user.username"  id="username" ></td>

                <td width="400px;" style="text-align: left;"><font color="red">* 請輸入用戶名</font></td>

            </tr>

            <tr>

                <td width="100px;" style="text-align:center; ">注冊密碼</td>

                <td width="80px;" style="text-align: left;"><input type="password" name="user.password" size="22" id="password"></td>

                <td width="400px;" style="text-align: left;"><font color="red">* 請輸入密碼</font></td>

            </tr>

            <tr>

                <td></td>

                <td colspan="2" style="float: left; ">

                    <button type="button"  onclick="checkValues()">注冊</button>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;

                    <button type="button"  onclick="goLogin()">去登錄</button>

                </td>

            </tr>

        </table>

 

     </form>

    </div>

    <img alt="" src="image/2.jpg">

</body>

</html>

 

struts.xml:

 

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE struts PUBLIC

    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"

    "http://struts.apache.org/dtds/struts-2.0.dtd">
<struts >

    <package name ="test" extends ="struts-default" >

        <action name ="dispatcher" class ="com.yun.test.webinf.action.DispatcherAction" >

            <result name ="goRegister">WEB-INF/register/register.jsp</result >

            <result name ="goMain1">WEB-INF/main/main1.jsp</result >

            <result name ="goMain2">WEB-INF/main/main2.jsp</result >

            <result name ="input">/index.jsp</result >

        </action >

        <action name ="login" class ="com.yun.test.webinf.action.LoginAction" >

            <result name ="success">WEB-INF/main.jsp</result >

            <result name ="input">/index.jsp</result >

        </action >

        <action name ="register" class ="com.yun.test.webinf.action.RegisterAction" >

            <result name ="success">WEB-INF/main.jsp</result >

           <result name ="input">WEB-INF/register/register.jsp</result >

        </action >

 

    </package>

 

    <!-- 定義struts標簽為無默認樣式 -->

    <constant name="struts.ui.theme" value="simple" />

</struts>

 

 

RegisterAction.java:

 

package com.yun.test.webinf.action;

import com.opensymphony.xwork2.ActionSupport;

import com.yun.test.webinf.entity.User;
public class RegisterAction extends ActionSupport{
         private User user;
         public void setUser(User user) {
                   this.user = user;

         }

         public User getUser() {
                   return user;

         }

         @Override

         public String execute() throws Exception {

                   if("lisi".equals(user.getUsername())&&"lisi".equals(user.getPassword())){

                            return SUCCESS;

                   }

                   return INPUT;

         }

         

}

 

接下來對WEB-INF頁面中的注意事項進行說明:

 

1. 把頁面資源文件只能放在WebContent目錄內,,如 CSS,JS,image等.不能放在WEB-INF下,因為WEB-INF是對客戶端隱藏的,所以放在WEB-INF下會造成頁面的布局等文件引用不到的情況。

 

2. 頁面文件一般放在WEB-INF目錄下面,這樣可以限制訪問,提高安全性.如JSP,html文件,放在WEB-INF目錄下就可以避免客戶端直接在地址欄上輸入路徑進行訪問了。基於不同的功能 ,把JSP 放置在WEB-INF下的不同的目錄中。

 

 

3. 只能用轉向方式來訪問WEB-INF目錄下的JSP,不用采用重定向的方式請求該目錄里面的任何資源。

  

4.轉向方式:

4.1、請求轉發:

如struts.xml文件中配置

<result name ="goMain2">WEB-INF/main/main2.jsp</result >

或在Action中寫

request.getRequestDispatcher("/WEB-INF/main/main2.jsp").forward(request, response);

的方式都是服務器讀取了該頁面內容,並發送到客戶端的,客戶端的地址不變,然后內容跳轉了。這樣的方式是可以訪問到WEB-INF目錄下的jsp文件的。

 

4.2、重定向方式:

如struts.xml文件中配置 

<result name ="goMain2" type="redirect">WEB-INF/main/main2.jsp</result >

 或在action中

response.sendRedirect("WEB-INF/main/main2.jsp ");

都屬於重定向的方式,重定向的含義就是服務器把地址發給客戶端,讓客戶端去訪問,這樣還是在客戶端訪問的WEB-INF目錄,所以是無法訪問到WEB-INF目錄下的jsp文件的。

 

 

 

 

5、有一些標簽,也是可以訪問到WEB-INF目錄中的文件的,如果符合要求的情況下也可以使用,如:

<jsp:forward page = "/WEB-INF/jsp/test/test.jsp" />

<a href="javascript:<jsp:forward page='WEB-INF/xxxx.jsp'/>"></a>

<jsp:include page="WEB-INF/xxx.jsp">

都是可以訪問WEB-INF下的jsp文件的。但是局限性很大,還是建議使用action分發的方式。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM