表單請求送出後,經曆了Struts2的類型轉換與輸入校驗階段之後,開始調用具體業務方法。但有時我們需要在執行業務方法之前先進 行比如登陸驗證之類的判斷。隻有登陸過的使用者才能進行業務方法調用。這時需要用到Struts2攔截器Interceptor。
以下以添加一個使用者為操作例子介紹struts2攔截器用法的簡單例子,
struts.xml配置:
<?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>
<package name="default" extends="struts-default">
<interceptors>
<!--定義登陸驗證攔截器-->
<interceptor name="myLogin" class="com.test.interceptor.LoginInterceptor"></interceptor>
</interceptors>
<!--定義全局跳轉頁-->
<global-results>
<result name="login" type="redirect">/login.jsp</result>
</global-results>
<action name="insertUser" class="com.test.action.UserAction" method="insertUser">
<result name="success">/success.jsp</result>
<result name="input">/index.jsp</result>
<result name="failure">/index.jsp</result>
<!--放入上面自定義權限驗證的攔截器-->
<interceptor-ref name="myLogin"></interceptor-ref>
<!--放入了自定義的攔截器後,必須顯式地設定struts2預設的攔截器棧-->
<interceptor-ref name="defaultStack"></interceptor-ref>
</action>
</package>
</struts>
當執行insertUser()業務方法之前被自定義的myLogin攔截器攔截進入到LoginInterceptor類進行登入驗證。
LoginInterceptor.java:
public class LoginInterceptor extends AbstractInterceptor {
public String intercept(ActionInvocation invocation) throws Exception{
//獲得Session對象
Map session = invocation.getInvocationContext().getSession();
//判斷session中是否有資訊
if(session.get("username") == null){
//無資訊傳回配置檔案中<global-results>配置的頁面
return Action.LOGIN;
}else{
//有資訊繼續執行後續操作
return invocation.invoke();
}
}
}
注:struts2許多功能比如自動類型轉換正是因為在其預設的攔截器棧裡有類型轉換的攔截器。通常情況下在<action/>中無需顯式地設定預設的攔截器棧。但像本例那樣當使用者在<action/>中放入了自定義的攔截器的時候,就必須顯式地設定預設的攔截器棧了。
開發中通常自定義多個攔截器棧,分别用以不同子產品。而将其中一個設定為預設的攔截器棧來代替Struts2原先的預設攔截器棧。如下:
<interceptors>
<!-- 自定義的攔截器 -->
<interceptor name="mylogin" class="com.htdz.action.interceptor.LoginInterceptor" />
<!-- 登入的攔截器棧loginStack攔截器棧-->
<interceptor-stack name="loginStack">
<interceptor-ref name="mylogin" />
<interceptor-ref name="defaultStack" />
</interceptor-stack>
<!--防止表單重複送出的tokenStack攔截器棧-->
<interceptor-stack name="tokenStack">
<interceptor-ref name="mylogin" />
<interceptor-ref name="token" />
<interceptor-ref name="defaultStack" />
</interceptor-stack>
</interceptors>
<!-- 将loginStack攔截器棧設定作為預設的攔截器棧 -->
<default-interceptor-ref name="loginStack" />
這之後,本例的<action/>就無需顯式地配置攔截器了,因為loginStack已作為所有<action/>預設攔截器棧。
而在其他需要控制使用者重複重新整理的<action/> 配置中則使用<interceptor-ref name="tokenStack" />即可,其不僅包含了登入校驗和原先的defaultStack攔截器棧,還包含了防重複重新整理的token攔截器