日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【struts2】struts2拦截器

發布時間:2024/4/14 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【struts2】struts2拦截器 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

struts2提供面向切面(AOP)編程的機制,攔截器便是一種成熟的AOP編程思想的實現,它提供一種機制使開發者能把相對獨立的代碼抽象出來,配置到action前后執行。攔截器interceptor類似于Filter,在執行action方法前后執行。

就像多個Filter組成了Filter鏈,多個攔截器也組成了攔截器鏈。struts2中稱攔截器鏈為攔截器棧。攔截器棧是按順序配置的多個攔截器,在執行action前后被依次調用

攔截器是用于在Action或者某個方法調用之前進行特定的處理的對象,類似于過濾器,是一個特殊的Servlet。攔截器主要用于在調用Action或Action方法之前做輸入校驗、權限驗證,字符編碼轉換等一些通用操作。多個攔截器構成攔截器棧。Struts2中有一個默認的攔截器棧,在每個Action調用之前執行。

攔截器有三個對象:被攔截對象,攔截器對象本身,代理。

真正執行的不想目標對象,而代理。

攔截器要實現Interceptor接口,默認實現攔截器時繼承AbstractInterceptor類,而很少直接繼承Interceptor接口。

1、類攔截器和方法攔截器:

(1)、針對Action進行攔截處理的攔截器是類攔截器,是一種粗粒度的攔截器。

攔截器是一種特殊的Servlet,與過濾器類似,其init()和destroy()方法只執行一次。而intercepte()方法是action每次執行時都會執行一次。

(2)、只對Action中某個特定方法進行攔截處理的攔截器就是方法攔截器,方法攔截器與類攔截器不同,它繼承MethodFilterInterceptor類,實現doIntercepte()方法。

2、配置類攔截器

(1)、在Struts2的配置文件struts.xml中的<package>元素標簽下添加:

<interceptors> <interceptor name=”攔截器名稱” class=”攔截器的全路徑”> <!--給攔截器配置參數,如果攔截器不需要參數,下面這句就不需要了--> <param name=”參數名稱”>參數值</param> </interceptor ></interceptors>

注意:在配置攔截器時傳遞了參數,需要在攔截器中定義和參數名稱相同的屬性,并且生成set和get方法。定義時為默認參數,攔截器引用時參數為動態參數,動態參數覆蓋默認參數。

(2)、對Action引入攔截器:

在Struts2的配置文件struts.xml中要引入攔截器的Action的<action>元素標簽下添加:

<interceptor-ref name=”攔截器名稱”/> <!-- 默認攔截器--> <interceptor-ref name="defaultStack" />

3、配置方法攔截器:

(1).在Struts2的配置文件struts.xml中的<package>元素標簽下添加內容,與配置類攔截器相同。

(2)、Action中引入方法攔截器:

在Struts2的配置文件struts.xml中要引入攔截器的Action的<action>元素標簽下添加:

<interceptor-ref name=”方法攔截器名稱”> <!--對該Action要引入的方法攔截器的方法--> <param name=”includeMethods”>Action方法1,Action方法2,…</param> <!-- 對該Action要排除的方法攔截器的方法--> <param name=”excludeMethods”>Action方法3,Action方法4,…</param> </interceptor-ref>

注意:include的優先級高于exclude。

4、配置攔截器棧

多個攔截器構成攔截器棧。

(1).攔截器棧定義方法:

在Struts2的配置文件struts.xml中的<package>元素標簽下添加:

<interceptor-stack name=”攔截器棧名稱”> <interceptor-ref name=”攔截器名稱”> <interceptor-stack>

注意:攔截器棧中可以包含攔截器和攔截器棧。

(2)、在Action中引入攔截器棧:

和引入攔截器相同

<interceptor-ref name=”攔截器棧名稱”/> <!-- 默認攔截器--> <interceptor-ref name="defaultStack" />

注意:,Struts2的Action配置了一個默認的攔截器棧,如果在Action中引入了自定義的攔截器或者攔截器棧之后,默認的Struts2默認的攔截器和攔截器棧就不會自動添加到該Action上,如果想使用默認的攔截器和攔截器棧就必須手動添加。

==========================================

實例一、timer計時攔截器

==========================================

timer攔截器能夠統計每個action方法運行所需要的時間。它的原理是在action執行前開啟記錄一下時間,action執行后再記錄一下時間,然后計算兩個時間差,并將時間差打印出來(在Filter中也能實現類似的功能)。下面使用timer攔截器統計一個action的運行時間。

TimerAction.java

package com.lmb.struts2.action;import com.opensymphony.xwork2.ActionSupport;public class TimerAction extends ActionSupport{@Overridepublic String execute() throws Exception {Thread.sleep(1000);//線程沉睡一秒鐘return SUCCESS;//返回成功頁面} }

該action非常簡單,讓當前線程沉睡1秒鐘,模擬一下繁忙的業務。action配置中要配置上timer攔截器

struts.xml

<package name="main" extends="struts-default"><!-- 定義一個package--><!-- 使用timer.action測試攔截器 --><action name="timer" class="com.lmb.struts2.action.TimerAction" ><interceptor-ref name="timer"></interceptor-ref><!-- 配置Timer攔截器 --><interceptor-ref name="defaultStack" /><result name="success">/timerSuccess.jsp</result></action> </package>

注意:package需要繼承struts-default才能使用struts2里的攔截器,因為time計時器是配置在struts-default包里的。

部署后訪問http://localhost:8080/struts2/timer.action,控制臺會輸出如下信息:

信息:Executed action [//timer!execute] took 1032 ms.

顯示的是執行timer!execute所消耗的時間(1032毫秒)。第一次訪問時由于需要加載攔截器,消耗的時間可能要多一些。顯示action執行的時間,在粗略的估計系統性能時很有用

==========================================

實例二、token防重復提交攔截器

==========================================

如果網絡不好,提交數據后可能就沒有反應了。這時候用戶不知道數據是否提交到服務器了,往往還會單擊提交按鈕再提交一次。對于某一些應用,例如:網絡購物、銀行轉賬等,重復提交會導致非常嚴重的后果。

token攔截器用于保證表單只被提交一次,如果再次提交表單,攔截器會攔截該請求,防止提交重復數據。它的原理是,顯示表單的時候,在session中對該表單做一個標記,該標記只能使用一次,使用過后就失效了,從而保證表單最多只提交一次數據。重復提交數據會因為標記已失效而提交失敗。

下面用token攔截器測試下面的TokenAction,保證在提交該表單數據時只能提交一次。TokenAction中有一個NAMES屬性,用來存儲提交過的所有數據。重復提交數據時,如果能提交進來,NAMES中將會積累重復的數據,以此來判斷數據時候被重復提交。

TokenAction.java

package com.lmb.struts2.action;import java.util.ArrayList; import java.util.List; import com.opensymphony.xwork2.Action; import com.opensymphony.xwork2.ActionSupport;public class TokenAction extends ActionSupport{//static屬性,模擬數據庫,用來存儲提交過的所有數據public static final List<String> NAMES=new ArrayList<String>();private String name;@Overridepublic String execute(){NAMES.add(name);//添加到NAMES中return Action.SUCCESS;//返回成功頁面}public void setName(String name){//name屬性的setter方法this.name=name;}public static List<String> getNAMES(){//name屬性的getter方法return NAMES;}}

action代碼沒有什么特別之處,就是普通的action,沒有任何特殊處理。token攔截器是配置式使用的,只需要在action中配置一下即可

struts.xml

<action name="token" class="com.lmb.struts2.action.TokenAction" ><!-- token攔截器 --><interceptor-ref name="token" /><!-- basicStack攔截 --><interceptor-ref name="basicStack" /> <interceptor-ref name="defaultStack" /><result>/tokenSuccess.jsp</result><result name="input">/tokenInput.jsp</result><result name="invalid.token">/tokenInvalid.jsp</result><!-- 如果重復提交數據,struts2將轉到該頁面 --> </action>

代碼中配置了token攔截器和basicStack攔截器棧。basicStack是幾個常用的攔截器的集合。basicStack是必須配置的攔截器,如果不配置,struts2就不會自動向action賦值。action中還必須配置一個名為invalid.token的result頁面。如果重復提交數據,struts2將轉到該頁面中,該結果也是必須要配置的。

tokenInput.jsp

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%> <%@ taglib uri="/struts-tags" prefix="struts" %><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html><body><struts:form action="token"><struts:token /> <!-- 非常重要的token標記 --><struts:label value="避免重復輸入"></struts:label><struts:textfield name="name" label="請輸入姓名"></struts:textfield><struts:submit name="提交"></struts:submit></struts:form></body> </html>

JSP輸入頁面也需要添加一個<struts:token />標簽。該標簽會在session中生成所在表單的標識,該標簽一定要添加在Form中,否則該攔截器無效。

輸入姓名那個,然后單擊“提交“按鈕提交數據后,會轉到成功頁面,并提示已經提交的所有數據。成功頁面的代碼如下:

tokenSuccessjsp

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%> <%@ taglib uri="/struts-tags" prefix="struts" %><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html><body>已輸入的姓名:<struts:property value="NAMES"/><br><br><a href="tokenInput.action">&lt;&lt;重新輸入</a></body> </html>

提交完成后,單擊瀏覽器的”刷新“按鈕。瀏覽器會彈出對話框,詢問是否要重新提交數據。單擊”是“按鈕,瀏覽器會重新提交數據,然后轉到tokenInvalid.jsp頁面,提示輸入無效。

tokenInvalid.jsp

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%> <%@ taglib uri="/struts-tags" prefix="struts" %><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html><body>輸入無效。<br><a href="tokenInput.action">&lt;&lt;重現輸入</a></body> </html>

==========================================

實例三、execAndWait執行等待攔截器

==========================================

如果某個action運行時間比較長,瀏覽器會因為等待服務器響應而長時間顯示空白。這比較令人煩,如果能顯示一個服務器正忙的頁面就好了。execAndWait攔截器就是實現這種效果的。execAndWait攔截器接受請求后,能判斷上一個請求是否處理完畢。如果已經處理完畢,則顯示結果頁面,否則顯示等待頁面

WaitAction.java

package com.lmb.struts2.action;import com.opensymphony.xwork2.ActionSupport;public class WaitAction extends ActionSupport{@Overridepublic String execute() throws Exception {Thread.sleep(10000);//沉睡10秒鐘,模擬大數據量處理return SUCCESS;//返回成功頁面} }

代碼讓action所在的線程沉睡10秒,模擬業務處理繁忙。在10秒鐘之內,將會顯示等待頁面。execAndWait攔截器配置在action中。配置如下:

struts.xml

<action name="wait" class="com.lmb.struts2.action.WaitAction" ><interceptor-ref name="completeStack" /><!-- completeStack攔截器 --><interceptor-ref name="execAndWait" /><!-- execAndWait屬性 --><interceptor-ref name="defaultStack" /><result>/waitSuccess.jsp</result><result name="wait">/wait.jsp</result> </action>

action配置了completeStack攔截器棧與execAndWait攔截器,還配置了一個名為wait的JSP頁面。如果action繁忙,就顯示wait頁面。

wait.jsp

<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%> <%@ taglib uri="/struts-tags" prefix="struts" %><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html><body>頁面提交(下載)中。。。請等待。。。<script type="text/javascript">setTimeout("location = location;",1000);//1秒鐘后刷新本頁</script></body> </html>

wait頁面每隔一秒鐘刷新一次,直至顯示成功頁面。在瀏覽器中進行訪問,前10秒鐘會一直顯示等待頁面。

這是顯示繁忙頁面的簡單方式,是struts2內置的解決方案。實際上較多的使用Ajax技術來實時顯示繁忙頁面。Ajax能做到頁面無刷新,并能通過進度條實時顯示進度

==========================================

實例四、自定義的權限驗證攔截器

==========================================

攔截器可以自由擴展。所有的攔截器都實現自Interceptor接口。實現自定義攔截器也要實現Interceptor接口。一般直接繼承AbstractInterceptor抽象類即可。

本例使用自定義攔截器判斷用戶是否登錄。邏輯很簡單,就是檢查當前用戶session中的account屬性是否為空。如果為空,則轉到登錄頁面,否則繼續執行。

自定義攔截器AuthenticationInterceptor.java:

package com.lmb.struts2.interceptor;import java.util.Map; import com.opensymphony.xwork2.Action; import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.interceptor.AbstractInterceptor;public class AuthenticationInterceptor extends AbstractInterceptor{@Overridepublic String intercept(ActionInvocation invocation) throws Exception {//通過invocation獲取本次調用的上下文Map<String, Object> sessionValues=invocation.getInvocationContext().getSession();String account=(String) sessionValues.get("account");//從session中取值if (account == null) {//如果為空return Action.LOGIN;//則返回登陸頁面}return invocation.invoke();//否則,正常運行}}

以上代碼會在action被調用之前運行。如果驗證通過,代碼invocation.invoke()會繼續調用action。攔截器需要在package中定義。然后將該攔截器配置在AuthenticationAction(該action代碼略)中。如果已經登錄,該AuthenticationAction會顯示一句話,表示驗證通過。否則,會被攔截器攔截,返回登錄頁面(登陸頁面是<global-results>中配置的全局<result/>)。

struts.xml

<package name="main" extends="struts-default"><!-- 定義一個package--><global-results> <!-- 所有的全局result--><result name="login">/login.jsp</result> <!-- 名為login的result--></global-results><interceptors><interceptor name="authentication" class="com.lmb.struts2.interceptor.AuthenticationInterceptor"></interceptor></interceptors><action name="authentication" class="com.lmb.struts2.action.AuthenticationAction" ><!-- action實現類 --><!-- 自定義authentication攔截器 --><interceptor-ref name="authentication" /><interceptor-ref name="defaultStack" /><result>/authenticationSuccess.jsp</result></action> </package>

注意:

1、關于攔截器的使用,以下是要注意的問題:

a、在struts.xml中配置攔截器時要先配置在全局Result之前!!

b、一定要注意!!使用自定義攔截器的action一定也要配置默認攔截器的引用,因為默認攔截器包含了參數的讀取、session的管理等功能。 <interceptor-ref name="defaultStack" />

c、一定要注意,攔截器只能攔截action,無法攔截所有的請求,如JSP頁面的訪問!!!!,如果想攔截對JSP頁面的訪問可以使用過濾器來完成。

2、使用攔截器之后如何將有關攔截器驗證情況的信息帶回到相應的JSP頁面???

攔截器中可寫出如下代碼:

ActionSupport action=(ActionSupport)invocation.getAction(); action.addActionMessage("您還沒有登錄或者登陸已經超時,請重新登陸!(要展示的有關攔截器驗證情況的信息)");

在前臺的JSP頁面中通過${ action.actionMessages }取得該提示信息。

總結

以上是生活随笔為你收集整理的【struts2】struts2拦截器的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。