對於須要登錄驗證、權限驗證等功能的網站,每一次請求,每個action都寫一段驗證的代碼,未免顯得冗餘且不易維護。struts2提供了攔截器interceptor,爲這些頁面提供一個切面,或者說公共組件,以達到易維護、提升代碼重用率的目的。struts默認的interceptor有不少,就不去一一列舉,這裏從自定義攔截器開始學習。apache
一、定義一個自定義攔截器: jsp
import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.interceptor.AbstractInterceptor; public class MyInterceptor extends AbstractInterceptor { public String intercept(ActionInvocation invocation) throws Exception { String output = "Pre-Processing"; System.out.println(output); String result = invocation.invoke(); output = "Post-Processing"; System.out.println(output); return result; } }
二、修改struts.xml,在package中聲明和使用攔截器MyInterceptor學習
<package name="suibian" extends="struts-default"> <!--聲明自定義的攔截器--> <interceptors> <interceptor name="myinterceptor" class="com.owlforest.home.interceptor.MyInterceptor" /> </interceptors> <action name="hello" class="com.owlforest.home.action.HelloWorldAction" method="excute"> <!--使用自定義攔截器--> <interceptor-ref name="myinterceptor" /> <interceptor-ref name="params"/> <result name="success">/HelloWorld.jsp</result> </action> </package>
該攔截器在com.owlforest.home.action.HelloWorldAction執行先後會生效,爲了便於理解,附上該Action的代碼:測試
import com.opensymphony.xwork2.ActionSupport; public class HelloWorldAction extends ActionSupport { private String name; public String excute(){ System.out.println("excute"); return "success"; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
三、執行程序網站
程序實現參照Struts2學習:HelloWorldui
執行action事後可查看控制檯輸出,看到下面的信息後及說明生效。this
四、對於一個struts.xml裏面的package,可能有多個action,多個action可能會用到一系列的相同的interceptor,若是每一個action都要寫一系列相同的攔截器,則很難維護。struts2提供了攔截器棧,來幫助整合這些攔截器,達到複用的目的。rest
爲了方便理解,我寫了兩個自定義的攔截器MyInterceptor和SecInterceptorcode
import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.interceptor.AbstractInterceptor; public class MyInterceptor extends AbstractInterceptor { public String intercept(ActionInvocation invocation) throws Exception { String output = "Pre-Processing 攔截器MyInterceptor"; System.out.println(output); String result = invocation.invoke(); output = "Post-Processing 攔截器MyInterceptor"; System.out.println(output); return result; } }
import com.opensymphony.xwork2.ActionInvocation; import com.opensymphony.xwork2.interceptor.AbstractInterceptor; public class SecInterceptor extends AbstractInterceptor { public String intercept(ActionInvocation invocation) throws Exception { String output = "Pre-Processing SecInterceptor"; System.out.println(output); String result = invocation.invoke(); output = "Post-Processing SecInterceptor"; System.out.println(output); return result; } }
配置struts.xmlxml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd"> <struts> <!-- 設置struts是否爲開發模式,默認爲false,測試階段通常設爲true. --> <constant name="struts.devMode" value="true"/> <package name="suibian" extends="struts-default"> <interceptors> <interceptor name="myinterceptor" class="com.owlforest.home.interceptor.MyInterceptor" /> <interceptor name="secinterceptor" class="com.owlforest.home.interceptor.SecInterceptor" /> <interceptor-stack name="myinterceptorstack"> <interceptor-ref name="myinterceptor" /> <interceptor-ref name="secinterceptor" /> </interceptor-stack> </interceptors> <action name="hello" class="com.owlforest.home.action.HelloWorldAction" method="excute"> <interceptor-ref name="myinterceptorstack"/> <interceptor-ref name="params"/> <result name="success">/HelloWorld.jsp</result> </action> </package> </struts>
五、由於攔截器和攔截器棧是在package中聲明使用的,做用域僅在當前聲明的package中,對於一些驗證、異常相關的攔截器,須要在全局、也就是全部的package中都能使用,這種須要定義一個全局的package,使相應的action對應的package繼承自該全局package便可。以下:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd"> <struts> <!-- 設置struts是否爲開發模式,默認爲false,測試階段通常設爲true. --> <constant name="struts.devMode" value="true"/> <!--全局的package--> <package name="commominterceptor" extends="struts-default"> <interceptors> <interceptor name="myinterceptor" class="com.owlforest.home.interceptor.MyInterceptor" /> <interceptor name="secinterceptor" class="com.owlforest.home.interceptor.SecInterceptor" /> <interceptor-stack name="myinterceptorstack"> <interceptor-ref name="myinterceptor" /> <interceptor-ref name="secinterceptor" /> </interceptor-stack> </interceptors> </package> <!--繼承自commominterceptor的package--> <package name="suibian" extends="commominterceptor"> <action name="hello" class="com.owlforest.home.action.HelloWorldAction" method="excute"> <interceptor-ref name="myinterceptorstack"/> <interceptor-ref name="params"/> <result name="success">/HelloWorld.jsp</result> </action> </package> </struts>
攔截器棧與全局攔截器的運行效果以下: