前言
攔截器體系是struts2框架的重要組成部分,不夸張的說,沒有攔截器體系,也就沒有這么好用的struts2框架了。在struts2框架中,大量的攔截器完成了很多基礎的功能,比如,params攔截器負責解析http請求的參數,并設置action的屬性;servlet-config攔截器直接將http請求中的httpservletrequest實例和httpservletresponse實例傳給action;fileupload攔截器則負責解析請求參數中的文件域,并將一個文件域設置成action的三個屬性......這一切的一切都是由內建的攔截器來完成的。所以,掌握了struts2中攔截器的使用原理與方式,也就把握住了struts2框架的“命脈”。
但是學習struts2到現在,除了在web.xml中配置了一個strutsprepareandexecutefilter過濾器外,還沒有接觸其它的什么攔截器,那為什么我們的應用能夠很好的運行呢?實際上,struts2已經默認啟用了大量通用的攔截器,只要配置action的package繼承了struts-default包,這些攔截器就會起作用。下面來看看struts2內建的攔截器。
struts2內建的攔截器
在struts2框架中有很多內建的攔截器,這些攔截器幾乎完成了struts2框架70%的工作,包括解析請求參數,將請求參數賦值給action屬性等,struts2這種靈巧的設計,很大程度上得益于攔截器的設計;當需要擴展struts2功能時,只需要提供對應攔截器,并將它配置在struts2容器中即可。
這些內建的攔截器以name-class對的形式配置在struts-default.xml文件中,其中name是攔截器名字,就是以后使用該攔截器的唯一標識;class則指定了該攔截器的實現類。對于這些內建的攔截器的詳細介紹,請參見官方文檔。
配置攔截器
在struts.xml文件中定義攔截器只需為攔截器類指定一個攔截器名,就完成了攔截器定義。定義攔截器使用<interceptor.../>,例如:
1
2
3
4
|
<!-- 通過指定攔截器名和攔截器實現類來定義攔截器 --> <interceptor name= "攔截器名" class = "攔截器實現類" > <param name= "參數名" >參數值</param> </interceptor> |
除此之外,還可以把多個攔截器連在一起組成攔截器棧,在攔截器中使用<interceptor-ref .../>來定義攔截器引用。例如:
1
2
3
4
5
|
<interceptor-stack name= "攔截器棧一" > <interceptor-ref name= "攔截器一" /> <interceptor-ref name= "攔截器二" /> ... </interceptor-stack> |
從程序結構上來看,攔截器棧由多個攔截器組成;但是從程序功能上來說,攔截器棧和攔截器是一樣的,它們包含的方法都會在action的execute方法執行之前自動執行。所以,我們完全可以把攔截器棧當成一個更大的攔截器。
由于攔截器棧和攔截器是一致的,所以攔截器棧中又可以包含攔截器棧,例如:
1
2
3
4
|
<interceptor-stack name= "攔截器棧二" > <interceptor-ref name= "modeldriven" /> <interceptor-ref name= "攔截器棧一" /> </interceptor-stack> |
使用攔截器
一旦定義了攔截器棧和攔截器后,就可以使用這個攔截器棧或攔截器來攔截action了,攔截器的攔截行為將會在action的execute方法執行之前被執行。
通過使用<interceptor-ref .../>元素可以在action內使用攔截器,在action中使用攔截器的配置語法與配置攔截器棧時引用攔截器的語法完全一樣。例如:
1
2
3
4
5
6
7
8
9
10
11
12
|
<action name= "login" class = "com.jellythink.practise.loginaction" > <result name= "error" >/error.jsp</result> <result name= "success" >/welcome.jsp</result> <!-- 攔截器棧 --> <interceptor-ref name= "defaultstack" /> <!-- 攔截器 --> <interceptor-ref name= "test1" /> <!-- 帶參數的攔截器 --> <interceptor-ref name= "test2" > <param name= "key" >動態參數</param> </interceptor-ref> </action> |
這樣配置完成以后,在執行downloadaction之前,這三個攔截器都會起作用。
配置默認攔截器
當配置一個包時,可以為其指定默認攔截器。一旦為某個包指定了默認的攔截器,如果該包中的action沒有顯式指定攔截器,則默認的攔截器將會起作用。但是,一旦我們為該包中的action顯式應用了某個攔截器,則默認的攔截器不會起作用;如果該action需要使用該默認攔截器,則必須手動配置該攔截器的引用。
只有當action中沒有顯式應用攔截器時,該action所在包的默認攔截器才會生效。
配置默認攔截器使用<default-interceptor-ref.../>元素,該元素作為<package.../>元素的子元素使用,為該包下的所有action配置默認的攔截器。例如:
1
|
< default -interceptor-ref name= "默認攔截器" /> |
也可以為默認攔截器指定參數,例如:
1
2
3
|
< default -interceptor-ref name= "默認攔截器" > <param name= "參數名" >參數值</param> </ default -interceptor-ref> |
在struts-default.xml文件中,配置了一個名為struts-default的抽象包,在該包中定義了名為defaultstack的默認攔截器引用。當我們定義的包繼承struts-default包時,也繼承了它的默認攔截器棧:defaultstack,這也意味著,如果我們不為action顯式地應用攔截器,則defaultstack攔截器棧會自動生效。
自定義攔截器
1>.添加一個類,讓它繼承abstractinterceptor類,或者實現interceptor接口
1
2
3
4
5
6
7
8
9
10
|
public class timeinterceptor extends abstractinterceptor { /** * 攔截器的核心方法intercept的返回值是一個字符串 */ @override public string intercept(actioninvocation invocation) throws exception { // todo auto-generated method stub return "login" ; } } |
2>.在struts.xml的package中添加interceptors子節點,并在它下面添加interceptor節點
1
2
3
4
5
|
< package name= "goods" namespace= "/goods" extends = "common-pkg" > <interceptors> <interceptor name= "timeinterceptor" class = "com.wskj.struts2.interceptor.timeinterceptor" ></interceptor> </interceptors> </ package > |
3>.在想被攔截的action節點下添加子節點interceptor-ref
1
2
3
4
|
<action name= "list_category" class = "com.wskj.struts2.controller.categoryaction" method= "list" > <interceptor-ref name= "timeinterceptor" ></interceptor-ref> <result name= "list" type= "dispatcher" >/pages/category/list.jsp</result> </action> |
總結
這篇文章對stuts2中的核心——攔截器進行了一個初步的總結,在后面的文章中,我們會實現一個我們自己的攔截器,并將這篇文章中總結的知識點進行運用。
好了,以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對服務器之家的支持。
原文鏈接:https://www.jellythink.com/archives/303