Web專案的WEB-INF目錄使用說明
在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
- <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"
- <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>
- <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:
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:
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>
- <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方法:
Html程式碼- <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路徑,如:
Html程式碼- <frameset cols="30%,70%">
- <frame src="main/main1.jsp">
- <frame src="main/main1.jsp">
- </frameset>
這樣還是不能訪問,也必須使用服務端的action分發的方式進行指定jsp檔案的路徑。
程式碼如下:
main.jsp:
Html程式碼- <%@ 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程式碼- <?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:
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:
Html程式碼- <%@ 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>
- <button type="button" onclick="goLogin()">去登入</button>
- </td>
- </tr>
- </table>
- </form>
- </div>
- <img alt="" src="image/2.jpg">
- </body>
- </html>
struts.xml:
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:
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檔案中配置
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檔案中配置
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目錄中的檔案的,如果符合要求的情況下也可以使用,如:
Html程式碼- <js