1、Struts2實現原理:
當請求到達Struts 2的ServletDispatcher時,Struts 2會查找配置文件,並根據其配置實例化相對的攔截器對象,然後串成一個列表(list),最後一個一個地調用列表中的攔截器,如圖所示。
2、Struts2默認的所有攔截器:
- <interceptor-stack name="defaultStack">
- <interceptor-ref name="exception"/><!-- 用於捕獲異常 -->
- <interceptor-ref name="alias"/>
- <interceptor-ref name="servletConfig"/><!-- 將源於Servlet API的各種對象注入到Action -->
- <interceptor-ref name="i18n"/>
- <interceptor-ref name="prepare"/>
- <interceptor-ref name="chain"/>
- <interceptor-ref name="scopedModelDriven"/>
- <interceptor-ref name="modelDriven"/>
- <interceptor-ref name="fileUpload"/><!-- 將文件和元數據從多重請求轉換為常規請求 -->
- <interceptor-ref name="checkbox"/>
- <interceptor-ref name="multiselect"/>
- <interceptor-ref name="staticParams"/><!-- 將在配置文件中配置的參數注入到Action中對應的屬性 -->
- <interceptor-ref name="actionMappingParams"/>
- <interceptor-ref name="params"><!-- 將請求的數據設置到Action中的屬性上 -->
- <param name="excludeParams">dojo\..*,^struts\..*,^session\..*,
- ^request\..*,^application\..*,^servlet(Request|Response)\..*,parameters\...*</param>
- </interceptor-ref>
- <interceptor-ref name="conversionError"/>
- <interceptor-ref name="validation"><!-- 執行數據驗證 -->
- <param name="excludeMethods">input,back,cancel,browse</param>
- </interceptor-ref>
- <interceptor-ref name="workflow"><!-- 當數據驗證錯誤時,提供終止流程的功能 -->
- <param name="excludeMethods">input,back,cancel,browse</param>
- </interceptor-ref>
- <interceptor-ref name="debugging"/>
- </interceptor-stack>
在struts-default.xml中已經配置了以上的攔截器。如果您想要使用上述攔截器,只需要在應用程序struts.xml文件中通過“<include file="struts-default.xml" />”將struts-default.xml文件包含進來,並繼承其中的struts-default包(package),最後在定義Action時,使用“<interceptor-ref name="xx" />”引用攔截器或攔截器棧(interceptor stack)。一旦您繼承了struts-default包(package),所有Action都會調用攔截器棧 ——defaultStack。當然,在Action配置中加入“<interceptor-ref name="xx" />”可以覆蓋defaultStack。
3、Struts2為我們提供了一個Interceptor接口,該接口源代碼如下:
- publicinterface Interceptor extends Serializable {
- void destroy();
- void init();
- String intercept(ActionInvocation invocation) throws Exception;
- }
1) init():在攔截器執行之前調用,主要用於初始化系統資源。
2) destroty():與init()對應,用於攔截器執行之後銷毀資源。
3) intercept():攔截器的核心方法,實現具體的攔截操作。與action一樣,該方法也返回一個字符串作為邏輯視圖。如果攔截器成功調用了action,則返回該action中execute()方法返回的邏輯視圖,反之,則返回一個自定義的邏輯視圖。
Struts2還為我們提供了一個AbstractInterceptor類,該類的init()和destroy()都是空實現。我們開發自己的攔截器只需要繼承這個類就行了。
4、下面以一個登錄的例子為例自定義攔截器:
首先自定義一個攔截器類,該類可以實現Interceptor接口或繼承AbstractInterceptor類:
- public class PermissionInterceptor implements Interceptor {
-
- @Override
- public void destroy() {
- // TODO Auto-generated method stub
- }
- @Override
- public void init() {
- // TODO Auto-generated method stub
- }
- @Override
- public String intercept(ActionInvocation invocation) throws Exception {
- // TODO Auto-generated method stub
- ActionContext cont=ActionContext.getContext();
- Object obj=cont.getSession().get("user");
- if(obj!=null){
- return invocation.invoke();
- }
- cont.getSession().put("message", "非法跳轉,請先登錄!");
- return "login";
- }
- }
在struts.xml配置攔截器:
- <struts>
- <package name="base" extends="struts-default">
- <global-results><!-- 定義全局視圖 -->
- <result name="login" type="redirect" >/login.jsp</result>
- </global-results>
- </package>
-
- <package name="default" namespace="/test" extends="base">
- <interceptors>
- <interceptor name="permission" class="org.han.interceptor.PermissionInterceptor" />
- <interceptor-stack name="permissionStack"><!-- 攔截器棧 -->
- <interceptor-ref name="defaultStack" />
- <interceptor-ref name="permission" /><!-- 如果需要加載默認攔截器,自定義攔截器要放默認攔截器後面 -->
- </interceptor-stack>
- </interceptors>
- </package>
- </struts>