亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 開發 > Java > 正文

Struts2攔截器Interceptor的原理與配置實例詳解

2024-07-13 10:13:56
字體:
來源:轉載
供稿:網友

一、Struts2攔截器原理:

Struts2攔截器的實現原理相對簡單,當請求struts2的action時,Struts 2會查找配置文件,并根據其配置實例化相對的    攔截器對象,然后串成一個列表,最后一個一個地調用列表中的攔截器。

比如:應用要求用戶登陸,且必須為指定用戶名才可以查看系統中某個視圖資源;否則,系統直接轉入登陸頁面。對于上面的需求,可以在每個Action的執行實際處理邏輯之前,先執行權限檢查邏輯,但這種做法不利于代碼復用。因為大部分Action里的權限檢查代碼都大同小異,故將這些權限檢查的邏輯放在攔截器中進行將會更加優雅。

PS:

1. Struts2攔截器是在訪問某個Action或Action的某個方法,字段之前或之后實施攔截,并且Struts2攔截器是可插拔的,攔截器是AOP的一種實現.

2. 攔截器棧(Interceptor Stack)。Struts2攔截器棧就是將攔截器按一定的順序聯結成一條鏈。在訪問被攔截的方法或字段時,Struts2攔截器鏈中的攔截器就會按其之前定義的順序被調用。

二、Struts2 攔截器接口實現:

Struts2規定用戶自定義攔截器必須實現com.opensymphony.xwork2.interceptor.Interceptor接口。該接口聲明了3個方法,其中,init和destroy方法會在程序開始和結束時各執行一遍,不管使用了該攔截器與否,只要在struts.xml中聲明了該Struts2攔截器就會被執行。intercept方法就是攔截的主體了,每次攔截器生效時都會執行其中的邏輯。

void init();void destroy();String intercept(ActionInvocation invocation) throws Exception;

1:所有攔截器都使用接口Interceptor ,Action去實現這個接口;

  • Init()方法:在服務器起動的時候加載一次,并且只加載一次;
  • Destroy()方法:當攔截器銷毀時執行的方法;
  • Interceptor()方法:其中里邊有一個參數invocation;
public String intercept(ActionInvocation invocation) throws xception {System.out.println("interceptor!!");String result=invocation.invoke();return result;}

其中intercept方法是攔截器的核心方法,所有安裝的攔截器都會調用之個方法。在Struts2中已經在struts-default.xml中預定義了一些自帶的攔截器,如timer、params等。如果在<package>標簽中繼承struts-default,則當前package就會自動擁有struts-default.xml中的所有配置。

Invocation.invoke()是如果只有一個攔截器執行完這個方法后,會返回給視圖,如果有多個攔截器,它順序的執行完所有的攔截器,才返回給視圖,也就是調用后面的action繼續執行。

二、Struts2 攔截器詳細配置:

默認攔截器是在不設置任何攔截器的時候,給予默認設置的,當只要設置任何一個攔截器就會覆蓋掉默認攔截器, 故此,我們需要手動設置

一旦實現了檢查攔截器,就可以在所有需要實現權限控制的Action中復用上面的攔截器。

為了使用該攔截器,首先在struts.xml文件中定義攔截器,定義攔截器的配置片段如下:

<!-- 用戶攔截器定義在該元素下 --> <interceptors> <!-- 定義了一個名為authority的攔截器 --> <interceptor name="authority" class="lee.AuthorityInterceptor"/> </interceptors> 定義了該攔截器之后,可以在Action中應用該攔截器,應用該攔截器的配置片段如下: <!-- 定義一個名為viewBook的Action,其實現類為ActionSupport --> <action name="viewBook"> <!-- 返回success視圖名時,轉入/WEB-INF/jsp/viewBook.jsp頁面 --> <result>/WEB-INF/jsp/viewBook.jsp</result> <!-- 攔截器一般配置在result元素之后! --> <interceptor-ref name="defaultStack"/> <!-- 應用自定義攔截器 --> <interceptor-ref name="authority"/> </action> 

上面名為viewBook的Action,沒有指定class屬性,默認使用ActionSupport類,配置該Action時,只是指定了一個Result,指定返回success字符串時,系統將轉入/WEBINF/jsp/viewBook.jsp頁面。但并為未配置login視圖對應的JSP頁面。

考慮到這個攔截器的重復使用,可能在多個Action都需要跳轉到login邏輯試圖,故將login Result定義成一個全局Result。

下面是配置login Result的配置片段:

<!-- 定義全局Result --><global-results><!-- 當返回login視圖名時,轉入/login.jsp頁面 --><result name="login">/login.jsp</result></global-results>

經過上面的配置,如果瀏覽者在瀏覽器中直接發送viewBook請求,將會轉入如圖所示的頁面。

這種通過攔截器進行權限控制的方式,顯然具有更好的代碼復用。

如果為了簡化struts.xml文件的配置,避免在每個Action中重復配置該攔截器,可以將該攔截器配置成一個默認攔截器棧(這個默認攔截器棧應該包括default-stack攔截器棧和權限檢查攔截器)。

定義自己的默認攔截器棧的配置片段如下:

<interceptors><!-- 定義權限檢查攔截器 --><interceptor name="authority" class="lee.AuthorityInterceptor"/><!-- 定義一個包含權限檢查的攔截器棧 --><interceptor-stack name="mydefault"><!-- 定義攔截器棧包含default-stack攔截器棧 --><interceptor-ref name="default-stack"/><!-- 定義攔截器棧包含authority攔截器 --><interceptor-ref name=" authority"/></interceptor- stack ></interceptors>

一旦定義了上面的mydefault攔截器棧,這個攔截器棧包含了權限檢查攔截器和系統默認的攔截器棧。如果將這個攔截器棧定義成默認攔截器,則可以避免在每個Action需要重復定義權限檢查攔截器。

下面是定義默認攔截器的配置片段:

<default-interceptor-ref name="mydefault"/>

一旦在某個包下定義了上面的默認攔截器棧,在該包下的所有Action都會自動增加權限檢查功能。對于那些不需要使用權限控制的Action,將它們定義在另外的包中——這個包中依然使用系統原來的默認攔截器棧,將不會有權限控制功能。

PS:攔截器,攔截器棧和默認的攔截器之間的關系

1:攔截器和攔截器棧是一個級別的,也就是說一個攔截器棧中包括許多攔截器, 一個攔截器棧中還可以包括許多攔截器棧,配置如下方式:

<interceptors><!-- 先定義攔截器 --><interceptor name="myInterceptor" class="com.struts2.interceptor.MyInterceptor"><!-- 指定系統初始化給攔截器的參數 --><param name="hello">張--</param></interceptor><!-- 加到自己設置的攔截器棧里邊去 --><interceptor-stack name="myStack"><interceptor-ref name="myInterceptor"></interceptor-ref><interceptor-ref name="defaultStack"></interceptor-ref></interceptor-stack></interceptors>

攔截器的使用:

1.先定義;

2.在引用使用;

<interceptor name="myInterceptor" class="com.struts2.interceptor.MyInterceptor"><interceptor-ref name="myInterceptor"></interceptor-ref>

2:struts2中有一個系統默認的攔截器棧是 defaultStack,如果你手動引用自己的攔截器,系統默認的攔截器棧將不起作用;這樣必需手動引入系統的攔截器棧

<interceptor-ref name="defaultStack"></interceptor-ref>

如果想改變系統默認的攔截器棧,可以這樣配置:

<default-interceptor-ref name="myStack"></default-interceptor-ref>

其中myStack是自己定義的攔截器棧名字;

如果攔截器棧中有多個攔截器,在執行action之前的順序跟配置攔截器的順序一致,而在action之后執行的順序是相反的;
PS:最后還附加一點過濾器的東西

過濾器,是在java web中,你傳入的request,response提前過濾掉一些信息,或者提前設置一些參數,然后再傳入servlet或者struts的 action進行業務邏輯,比如過濾掉非法url(不是login.do的地址請求,如果用戶沒有登陸都過濾掉),或者在傳入servlet或者 struts的action前統一設置字符集,或者去除掉一些非法字符

攔截器,是在面向切面編程的就是在你的service或者一個方法,前調用一個方法,或者在方法后調用一個方法比如動態代理就是攔截器的簡單實現,在你調用方法前打印出字符串(或者做其它業務邏輯的操作),也可以在你調用方法后打印出字符串,甚至在你拋出異常的時候做業務邏輯的操作。

攔截器與過濾器的區別 :

      1、攔截器是基于java的反射機制的,而過濾器是基于函數回調。

      2、攔截器不依賴與servlet容器,過濾器依賴與servlet容器。

      3、攔截器只能對action請求起作用,而過濾器則可以對幾乎所有的請求起作用。

      4、攔截器可以訪問action上下文、值棧里的對象,而過濾器不能訪問。

      5、在action的生命周期中,攔截器可以多次被調用,而過濾器只能在容器初始化時被調用一次

      6、執行順序 :過濾前 - 攔截前 - Action處理 - 攔截后 - 過濾后。

過濾是一個橫向的過程,首先把客戶端提交的內容進行過濾(例如未登錄用戶不能訪問內部頁面的處理);過濾通過后,攔截器將檢查用戶提交數據的驗證,做一些前期的數據處理,接著把處理后的數據發給對應的Action;Action處理完成返回后,攔截器還可以做其他過程(還沒想到要做啥),再向上返回到過濾器的后續操作。

一個Filter 可負責攔截多個請求或響應:一個請求或響應也可被多個請求攔截。

創建一個Filter 只需兩個步驟:

(1)創建Filter 處理類:

(2)在web.xml 文件中配置Filter 。

創建Filter 必須實現javax.servlet.Filter 接口,在該接口中定義了三個方法。

      • void init(FilterConfig config) : 用于完成Filter 的初始化。

      • void destroy() : 用于Filter 銷毀前,完成某些資源的回收。

      • void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) : 實現過濾功能,該方法就是對每個請求及響應增加的額外處理。

過濾器Filter也具有生命周期:init()->doFilter()->destroy(),由部署文件中的filter元素驅動。在servlet2.4中,過濾器同樣可以用于請求分派器,但須在web.xml中聲明,<dispatcher>INCLUDE或FORWARD或REQUEST或ERROR</dispatcher>該元素位于filter-mapping中。

實例教程

下面寫一個自定義攔截器的例子,判斷用戶是否登錄,就是檢查當前用戶的session中的user屬性是否為空,如果為空,就跳到登錄頁面,否則,繼續執行.

1.編寫攔截器,在interceptor包下常見一個java類,名為LoginInterceptor,繼承AbstractInterceptor:

public class LoginInterceptor extends AbstractInterceptor{ @Override public String intercept(ActionInvocation invocation) throws Exception {  //得到攔截到的action的名稱,看是否是login,當是login的時候,不用進行下面的檢測了,直接執行下一個攔截器  String actionName=invocation.getProxy().getActionName();  if("login".equals(actionName)){   return invocation.invoke();       }  //如果不是login.則判斷是否已登錄,及檢測session中key為user的值是否存在,如果不存在,跳回到登錄頁面  String user=(String)invocation.getInvocationContext().getSession().get("user");  if(user==null){   System.out.println("未登錄");   return "login";  }  //進行到這里.說明用戶已登錄,則跳轉到下一個攔截器  return invocation.invoke(); }}

2,在struts.xml中配置interceptor,主要特別注意的是,當使用了自定義的攔截器后,默認攔截器將不起作用,默認攔截器實在struts-default.xml中配置的,當引用了自定義攔截器,又想使用struts2提供的默認攔截器功能,需要手動配置:這里我將默認攔截器和我寫的進行登錄權限驗證的攔截器,寫到一個攔截器棧里,然后調用這個默認攔截器棧:

<package name="default" namespace="/" extends="struts-default">   <interceptors>    <!-- 配置自定義的攔截器-->   <interceptor name="checkLogin" class="com.wang.interceptor.LoginInterceptor"/>    <!--配置一個攔截器棧,里面包含自己定義的攔截器和defaultStack默認攔截器-->         <interceptor-stack name="myStack">    <interceptor-ref name="defaultStack"></interceptor-ref>    <interceptor-ref name="checkLogin"></interceptor-ref>   </interceptor-stack>  </interceptors>    <!--引用默認的攔截器(棧)-->  <default-interceptor-ref name="myStack"></default-interceptor-ref>      <!--配置一個全局結果集-->     <global-results>   <result name="login">/login.jsp</result>  </global-results>  <action name="login" class="com.wang.action.LoginAction" >   <result>/succ.jsp</result>   <result name="error">/login.jsp</result>  </action> </package>

這里我使用了默認攔截器標簽,即相當于在每個action標簽下,使用了 <interceptor-ref name="myStack"></interceptor-ref>.jsp頁面和LoginAction類這里就省略了.

再來介紹一下方法攔截器,方法攔截器比action攔截器控制的更加精細,大體實現方式和action攔截器相同,不同的是它繼承的是MethodFilterInterceptor類,重寫的是doInterceptor()方法,在struts.xml的配置上也有些不同,大體是這樣:

<interceptor-ref name="methodInterceptor">   <!--配置被攔截的方法-->   <param name="includeMethods">methodA,methodsB</param>   <!--配置不被攔截的方法--><param name="excludeMethods">methodsC,methodsD</param> </interceptor-ref>

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對VeVb武林網的支持。


注:相關教程知識閱讀請移步到JAVA教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产亚洲精品高潮| 亚洲人成电影网站色www| 九九九热精品免费视频观看网站| 国产精品激情av电影在线观看| 国产成人精品久久二区二区| 欧美激情视频在线观看| 美日韩精品免费观看视频| 91精品久久久久久综合乱菊| 中文在线不卡视频| 高清一区二区三区四区五区| 91sao在线观看国产| 国产a∨精品一区二区三区不卡| 日韩在线观看免费全集电视剧网站| 国产99久久久欧美黑人| 久久高清视频免费| 成人激情视频在线播放| 中文国产成人精品久久一| 亚洲另类欧美自拍| 国产精品久久久久久久一区探花| 91精品国产乱码久久久久久蜜臀| 4438全国成人免费| 欧美国产乱视频| 韩国国内大量揄拍精品视频| 欧洲永久精品大片ww免费漫画| 国产在线不卡精品| 日韩69视频在线观看| 国产丝袜一区二区三区免费视频| 国产精品免费在线免费| 欧美黄色www| 性欧美暴力猛交69hd| 91精品国产91久久久久久最新| 精品国产依人香蕉在线精品| 欧美在线亚洲一区| 欧美黑人极品猛少妇色xxxxx| 懂色av中文一区二区三区天美| 最近2019中文字幕在线高清| 亚洲精品久久久久久久久久久久久| 91久久久久久久| 98精品国产高清在线xxxx天堂| 欧美性猛交视频| 国产精品对白刺激| 日韩欧美在线免费观看| 最近2019中文免费高清视频观看www99| 久久久久久久电影一区| 欧美日韩在线视频首页| 日韩精品一区二区视频| 日韩大胆人体377p| 国产suv精品一区二区三区88区| 精品亚洲永久免费精品| 日韩欧美在线视频观看| 亚洲第一精品夜夜躁人人躁| 亚洲最大的av网站| 国产精品视频精品视频| 日韩电影免费观看在线| 亚洲精品影视在线观看| 欧美小视频在线| 欧美日韩成人免费| 亚洲国产精品高清久久久| 日韩高清免费观看| 亚洲大胆美女视频| 中文亚洲视频在线| 亚洲精美色品网站| 91久久精品久久国产性色也91| 国产成人精品免高潮在线观看| 最近2019年好看中文字幕视频| 成人免费福利在线| 日韩av在线一区二区| 久久久久久一区二区三区| 国产精品成人av在线| 亚洲国产精品成人va在线观看| 亚洲综合中文字幕在线观看| 亚洲精品98久久久久久中文字幕| 清纯唯美亚洲激情| 26uuu另类亚洲欧美日本一| 在线日韩中文字幕| 91国偷自产一区二区三区的观看方式| 亚洲午夜久久久影院| 亚洲第一色在线| 这里只有精品视频在线| 欧美精品一区三区| 亚洲专区在线视频| 中文字幕亚洲综合久久筱田步美| 91精品国产91久久久久久吃药| 亚洲三级av在线| 中文字幕日韩av电影| 亚洲网址你懂得| 亚洲91精品在线观看| 国产精品影院在线观看| 欧美在线一区二区视频| 国产91成人在在线播放| 欧美激情精品久久久久久久变态| 成人有码在线视频| 亚洲精品视频二区| 久久精品91久久香蕉加勒比| 成人福利网站在线观看| 成人黄色片网站| 亚洲国产精品悠悠久久琪琪| 欧美影院久久久| 91精品国产91久久久久福利| 福利一区福利二区微拍刺激| 国产在线精品一区免费香蕉| 91精品国产91久久久| 亚洲人精选亚洲人成在线| 国产精品露脸自拍| 国产精品96久久久久久又黄又硬| 久久精品99久久久久久久久| 久久69精品久久久久久国产越南| 日韩暖暖在线视频| 国产91精品在线播放| 日韩一区二区福利| 久久久久免费精品国产| 97视频免费在线观看| 午夜免费久久久久| 亚洲精品suv精品一区二区| 91av在线免费观看视频| 欧美激情精品久久久久久免费印度| 97成人精品视频在线观看| 成人在线播放av| 日韩在线视频导航| 国产美女精品免费电影| 亚洲日本中文字幕| 亚洲男人天堂古典| 亚洲第一中文字幕| 欧美最顶级的aⅴ艳星| 欧美日韩国产丝袜另类| 性色av一区二区三区在线观看| 欧美精品福利视频| 亚洲午夜精品视频| 久久在线免费视频| 亚洲天堂日韩电影| 国产精品美女www| 国产欧美日韩精品丝袜高跟鞋| 久久久中文字幕| 亚洲精品wwww| 日韩69视频在线观看| 欧美精品免费看| 精品一区二区电影| 91国产视频在线| 国产99在线|中文| 亚洲精品福利视频| 亚洲国产精品大全| 亚洲大胆人体在线| 日韩成人xxxx| 国产精品视频永久免费播放| 国产精品三级久久久久久电影| 蜜臀久久99精品久久久无需会员| 国产成人精品一区二区| 尤物精品国产第一福利三区| 日韩高清av在线| 色噜噜久久综合伊人一本| 91av免费观看91av精品在线| 久久久久免费视频| 国产精品国语对白| 日韩欧美中文第一页| 久久人人97超碰精品888| 91久久精品日日躁夜夜躁国产| 91在线观看免费高清| 不卡av在线播放| 欧美在线免费观看| 日韩在线小视频| 青青草国产精品一区二区| 九九九久久国产免费| 韩日欧美一区二区| 欧美激情欧美激情在线五月|