Struts2 06--系統攔截器防止數據重復提交
一.攔截器簡要概述
攔截器,在AOP(Aspect-Oriented Programming)中用於在某個方法或字段被訪問之前,進行攔截然後在之前或之後加入某些操作。攔截是AOP的一種實現策略。
在Webwork的中文文檔的解釋為——攔截器是動態攔截Action調用的對象。它提供了一種機制可以使開發者可以定義在一個action執行的前後執行的代碼,也可以在一個action執行前阻止其執行。同時也是提供了一種可以提取action中可重用的部分的方式。 談到攔截器,還有一個詞大家應該知道——攔截器鏈(Interceptor Chain,在Struts 2中稱為攔截器棧Interceptor Stack)。攔截器鏈就是將攔截器按一定的順序聯結成一條鏈。在訪問被攔截的方法或字段時,攔截器鏈中的攔截器就會按其之前定義的順序被調用。 1.攔截器的實現原理: 大部分時候,攔截器方法都是通過代理的方式來調用的。Struts 2的攔截器實現相對簡單。當請求到達Struts 2的ServletDispatcher時,Struts 2會查找配置文件,並根據其配置實例化相對的攔截器對象,然後串成一個列表(list),最後一個一個地調用列表中的攔截器。 2.攔截器的配置 Struts 2已經為我們提供豐富多樣的,功能齊全的攔截器實現。大家可以至struts2的jar包內的struts-default.xml查看關於默認的攔截器與攔截器鏈的配置。
二.系統默認攔截器
功能說明:
攔截器 |
名字 |
說明 |
Alias Interceptor |
alias |
在不同請求之間將請求參數在不同名字件轉換,請求內容不變 |
Chaining Interceptor |
chain |
讓前一個Action的屬性可以被後一個Action訪問,現在和chain類型的result(<result type=”chain”>)結合使用。 |
Checkbox Interceptor |
checkbox |
添加了checkbox自動處理代碼,將沒有選中的checkbox的內容設定為false,而html默認情況下不提交沒有選中的checkbox。 |
Cookies Interceptor |
cookies |
使用配置的name,value來是指cookies |
Conversion Error Interceptor |
conversionError |
將錯誤從ActionContext中添加到Action的屬性字段中。 |
Create Session Interceptor |
createSession |
自動的創建HttpSession,用來為需要使用到HttpSession的攔截器服務。 |
Debugging Interceptor |
debugging |
提供不同的調試用的頁面來展現內部的數據狀況。 |
Execute and Wait Interceptor |
execAndWait |
在後臺執行Action,同時將用戶帶到一個中間的等待頁面。 |
Exception Interceptor |
exception |
將異常定位到一個畫面 |
File Upload Interceptor |
fileUpload |
提供文件上傳功能 |
I18n Interceptor |
i18n |
記錄用戶選擇的locale |
Logger Interceptor |
logger |
輸出Action的名字 |
Message Store Interceptor |
store |
存儲或者訪問實現ValidationAware接口的Action類出現的消息,錯誤,字段錯誤等。 |
Model Driven Interceptor |
model-driven |
如果一個類實現了ModelDriven,將getModel得到的結果放在Value Stack中。 |
Scoped Model Driven |
scoped-model-driven |
如果一個Action實現了ScopedModelDriven,則這個攔截器會從相應的Scope中取出model調用Action的setModel方法將其放入Action內部。 |
Parameters Interceptor |
params |
將請求中的參數設置到Action中去。 |
Prepare Interceptor |
prepare |
如果Acton實現了Preparable,則該攔截器調用Action類的prepare方法。 |
Scope Interceptor |
scope |
將Action狀態存入session和application的簡單方法。 |
Servlet Config Interceptor |
servletConfig |
提供訪問HttpServletRequest和HttpServletResponse的方法,以Map的方式訪問。 |
Static Parameters Interceptor |
staticParams |
從struts.xml文件中將<action>中的<param>中的內容設置到對應的Action中。 |
Roles Interceptor |
roles |
確定用戶是否具有JAAS指定的Role,否則不予執行。 |
Timer Interceptor |
timer |
輸出Action執行的時間 |
Token Interceptor |
token |
通過Token來避免雙擊 |
Token Session Interceptor |
tokenSession |
和Token Interceptor一樣,不過雙擊的時候把請求的數據存儲在Session中 |
Validation Interceptor |
validation |
使用action-validation.xml文件中定義的內容校驗提交的數據。 |
Workflow Interceptor |
workflow |
調用Action的validate方法,一旦有錯誤返回,重新定位到INPUT畫面 |
Parameter Filter Interceptor |
N/A |
從參數列表中刪除不必要的參數 |
Profiling Interceptor |
profiling |
通過參數激活profile |
三.使用系統攔截器完成登錄的防止數據重復提交(token)
1).頁面引用ognl標簽,采用from表單提交
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib uri="/struts-tags" prefix="s" %> <!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>Insert title here</title> </head> <body> <s:form action="token.action" method="post"> <s:token></s:token> <s:textfield name="username"></s:textfield> <s:password name="pwd"></s:password> <s:submit value="提交"></s:submit> </s:form> </body> </html>
2).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="tokenpackage" extends="struts-default"> <action name="token" class="com.action.TokenAction"> <!-- 配置令牌 --> <interceptor-ref name="token"></interceptor-ref> <!-- 引入默認的攔截器 默認的攔截器會幫你把action轉換到action類中 --> <interceptor-ref name="defaultStack"></interceptor-ref> <result name="success"> /success.jsp</result> <!-- 當在session中已經找到相同的值得時候,進行跳轉 --> <result name="invalid.token">/error.jsp</result> </action> </package> </struts>
3).TokenAction:
package com.action; import javax.servlet.http.HttpServletRequest; import org.apache.struts2.ServletActionContext; import com.opensymphony.xwork2.ActionSupport; public class TokenAction extends ActionSupport { @Override public String execute() throws Exception { HttpServletRequest request = ServletActionContext.getRequest(); String name=request.getParameter("username"); String pwd=request.getParameter("pwd"); System.out.println(name+"---"+pwd); return SUCCESS; } }
當你登錄的時候,如果你提交兩次相同的數據,就會進入error.jsp的界面。會提醒你不要重復提交數據。對了,當你使用攔截器時在web.xml中配置的過濾器中還需要加上
<filter-name>stuts2</filter-name> <url-pattern>*.jsp</url-pattern>
因為攔截器只可以攔截action,而過濾器可以過濾任何內容,比如講html jsp servlet 圖片的路徑等。
再附上一張token工作原理圖:
Struts2 06--系統攔截器防止數據重復提交