Struts2攔截器
一、內容提要
1.攔截器的概念及應用
2.STRUTS2自帶的攔截器
3.自定義攔截器
4.自定義攔截器的應用
二、攔截器的概念及應用
攔截器(Interceptor)是Struts2的一個重要特性。Struts2框架的大多數核心功能都是通過攔截器來實現的,像避免表單重復提交、類型轉換、對象組裝、驗證、文件上傳等,都是在攔截器的幫助下實現的。攔截器之所以稱為“攔截器”,是因為它可以在Action執行之前或執行之後攔截調用。
Struts2將它的核心功能放到攔截器中實現而不是分散到Action中實現,有利於系統的解耦,使得功能的實現類類似於個人電腦的組裝,變成了可插拔的。需要某個功能就“插入”一個攔截器,不需要某個功能就“拔出”。
攔截器應用:
- 為action動態添加輸入驗證
- 對象組裝(也就是進行數據類型轉換)
- 權限控制
- 日誌記錄等
三、STRUTS2自帶的攔截器
Struts2本身提供了很多的攔截器,這些攔截器已經在struts-default.xml文件中定義,在Web應用程序中可以直接引用這些攔截器。這也是為什麽struts配置文件裏經常有這樣一個屬性extends="struts-default",加載Struts2本身提供的攔截器。
具體情況如下:
序號 |
攔截器名稱 |
作用 |
1 |
alias |
在請求之間轉換名字不同的相似參數 |
2 |
chain |
將所有的屬性從前一個Aciotn復到當前Action中 |
3 |
params |
最基本的一個攔截器,負責解析HTTP請求中的參數,並將參數值設置成Action對應的屬性值 |
4 |
cookie |
基於cookie的名/值設置Action的屬性 |
5 |
conversionError |
將類型轉換錯誤從ActionContext中取出,添加到Action字段錯誤中 |
6 |
createSession |
自動創建一個HttpSession對象 |
7 |
debugging |
當struts.devMode屬性設置為true,才有,用於調試 |
8 |
execAndWait |
可以用於防止後臺Action Http請求超時 |
9 |
exception |
提供了異常處理的核心功能 |
10 |
fileUpload |
用於對文件上傳提供支持 |
11 |
i18n |
用於支持國際化 |
12 |
timer |
負責輸出action的執行時間,用於分析action |
13 |
token |
檢查傳到Action的token值的有效性,防表單重復提交 |
四、自定義攔截器
作為“框架(framework)”,可擴展性是不可或缺的,因為世上沒有放之四海而皆準的東西。雖然,Struts 2為我們提供如此豐富的攔截器實現,但是這並不意味我們失去創建自定義攔截器的能力,恰恰相反,在Struts 2自定義攔截器是相當容易的一件事。
在Struts2中編寫攔截類,有如下二種方式:
實現Interceptor此接口
繼承AbstractInterceptor類(一般會選擇此種方式)
案例:
編寫攔截器類:
註意:在編寫攔截器時要註意,攔截器必順是無狀態的,換句話 說,在攔截器類中不應該有實例變量。這是因為struts2對每一個Action的請求使用的是同一個攔截器實例來處理,如果攔截器有狀態,在多線程並發情況下,攔截器的狀態將不可預測。
package com.silvan.interceptor;
import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.interceptor.AbstractInterceptor;
public class AroundInterceptor extends AbstractInterceptor {
public void init() { System.out.println("這是一個初始化方法"); }
public String intercept(ActionInvocation invocation) throws Exception { String result = ""; System.out.println("我是在action的execute方法執行之前動作"); result = invocation.invoke(); System.out.println("我是在action的execute方法執行之後動作"); return result; }
public void destroy() { System.out.println("這是一個清理方法"); } } |
Struts.xml配置攔截器
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" "http://struts.apache.org/dtds/struts-2.3.dtd"> <struts> <package name="InterceptorDemo" extends="struts-default"> <!--在這裏定義攔截器 --> <interceptors> <interceptor name="around" class="com.silvan.interceptor.AroundInterceptor" /> </interceptors> <action name="interceptor" class="com.silvan.action.InterceptorAction"> <result>/index.jsp </result> <!--在這裏使用攔截器,當使用自定義的攔截器後,默認的攔截器將失效,這樣原本struts提供的攔截器功能就會失效,比如用於類型轉換的params攔截器 --> <interceptor-ref name="around"/> </action> </package> </struts> |
Action類
public class InterceptorAction extends ActionSupport { private int id; private String userName; @Override public String execute() throws Exception { System.out.println("執行interceptor Action……"); return SUCCESS; } Get/set…… } |
頁面顯示Login
<form action="interceptor"> <table> <tr><td>編號:<input type="text" name="id" value="1"></td></tr> <tr><td>姓名:<input type="text" name="userName" value="ross"></td></tr> <tr><td><input type="submit" value="submit"></td></tr> </table> </form> |
返回顯示index
<body> 編號:<s:property value="id"/><br/> 用戶名:<s:property value="userName"/> </body> |
當自定義了攔截器後,默認的攔截器將失效, index頁面取不到登錄的值,所以需要引入默認的攔截器。配置如下:
Struts.xml配置攔截器
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" "http://struts.apache.org/dtds/struts-2.3.dtd"> <struts> <package name="InterceptorDemo" extends="struts-default"> <!--在這裏定義攔截器 --> <interceptors> <interceptor name="around" class="com.silvan.interceptor.AroundInterceptor" /> <!-- 定義攔截器棧 --> <interceptor-stack name="myStack"> <!--引用攔截器 --> <interceptor-ref name="around"></interceptor-ref> <!-- 引入默認的攔截器 --> <interceptor-ref name="defaultStack"></interceptor-ref> </interceptor-stack> </interceptors> <!—針對包引用攔截器,這樣就不僅僅對某個action起作用 --> <!-- <default-interceptor-ref name="mystack"/> --> <action name="interceptor" class="com.silvan.action.InterceptorAction"> <result>/index.jsp </result> <!—引用攔截器棧 --> <interceptor-ref name="myStack"/> </action> </package> </struts> |
Struts.xml配置多個攔截器方式:
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" "http://struts.apache.org/dtds/struts-2.3.dtd"> <struts> <package name="InterceptorDemo" extends="struts-default"> <!--在這裏定義攔截器 --> <interceptors> <interceptor name="around" class="com.silvan.interceptor.AroundInterceptor" /> <interceptor name="around1" class="com.silvan.interceptor.AroundInterceptor1" /> <!-- 定義攔截器棧 --> <interceptor-stack name="myStack"> <!--引用攔截器 --> <interceptor-ref name="around"></interceptor-ref> <interceptor-ref name="around1"></interceptor-ref> <!-- 引入默認的攔截器 --> <interceptor-ref name="defaultStack"></interceptor-ref> </interceptor-stack> </interceptors> <!-- <default-interceptor-ref name="mystack"/> --> <action name="interceptor" class="com.silvan.action.InterceptorAction"> <result>/index.jsp </result> <interceptor-ref name="myStack"/> </action> </package> </struts> |
五、練習
需求分析
在一個系統中,如果用戶沒有選擇登錄系統就直接使用相應的資源,從常理上來講這是不允許的。也就是說在當用戶訪問受保護資源時,攔截器截獲用戶請求,判斷用戶是否已經登錄,如果沒有登錄,則向用戶顯示登錄頁面,請求用戶登錄如果用戶已經登錄,則向用戶顯示資源。
Action
public String execute() throws Exception { System.out.println("執行interceptor Action……"); if(userName!=null){ ActionContext context = ActionContext.getContext(); Map<String,Object> session = context.getSession(); session.put("userName", userName); } return SUCCESS; } |
Interceptor
public String intercept(ActionInvocation invocation) throws Exception { String result = ""; System.out.println("我是在action的execute方法執行之前動作"); String user =(String) ActionContext.getContext().getSession().get("userName"); if(user!=null && "".equals(user)){ System.out.println("非法訪問……"); return "error_login"; } result = invocation.invoke(); System.out.println("我是在action的execute方法執行之後動作"); return result; } |
配置
<!-- <global-results name="error_login">/login.jsp</global-results> --> <!-- <default-interceptor-ref name="mystack"/> --> <action name="interceptor" class="com.silvan.action.InterceptorAction"> <result>/index.jsp </result> <result name="error_login">/login.jsp</result> <interceptor-ref name="myStack"/> </action> |
Struts2攔截器