Struts 2 攔截器之示例:使用攔截器完成權限控制
前面介紹了一些攔截器的配置和基本的使用方法,所以這次將介紹攔截器的實用功能。
實用攔截器完成權限控制
當瀏覽者需要執行某個操作時,應用需要先檢查瀏覽者是否登錄,以及是否有足夠的權限來執行該操作。
本示例要求用戶登錄且必須為指定用戶名才可以查看系統中的某個試圖,否則用戶直接轉入到登錄界面。
檢查用戶是否登錄,通常都是跟蹤用戶的Session來完成的,通過ActionContext即可訪問到session的屬性,攔截器的interceptor方法的invocation參數可以很輕易地訪問到請求相關的ActionContext實例。
權限檢查攔截器類代碼如下:
public class AuthorityInterceptor extends AbstractInterceptor{ //攔截Action處理的攔截方法 @Override public String intercept(ActionInvocation invocation) throws Exception { //取得請求相關的ActionContext實例 ActionContext ctx = invocation.getInvocationContext(); Map session = ctx.getSession(); //取出名為user的session屬性 String user = (String) session.get("user"); //如果沒有登錄或者登錄所用的用戶名不是chenssy,則返回重新登錄 if(user!=null&&user.equals("chenssy")){ return invocation.invoke(); } //沒有登錄,將服務器提示設置成一個HttpServletRequest屬性 ctx.put("tip", "您還沒有登錄,請輸入chenssy登錄系統"); return Action.LOGIN; } }
實現了上面的權限攔截器,就可以在所需要實現權限的Action中引用上面的攔截器。
為了使用該攔截器,在struts.xml配置文件中定義如下配置片段
<!-- 定義用戶攔截器 --> <interceptors> <!-- 定義一個名為authority的攔截器--> <interceptor name="authority" class="com.app.interceptor.AuthorityInterceptor"> </interceptor> </interceptors>
定義了該攔截器后,就可以在Action中應用該攔截器了。配置如下:
<action name="viewBook"> <result name="success">/viewBook.jsp</result> <interceptor-ref name="authority"></interceptor-ref> </action>
上面的Action沒有指定class屬性,默認使用ActionSupport類,該類的execute方法返回success視圖名。所以配置該Action時,只需要指定一個結果映射:success。
考慮到這個攔截器的重復使用,可能多個Action都需要跳轉到login邏輯視圖,故將login的結果映射定義成一個全局結果映射。配置如下:
<!-- 定義全局Result --> <global-results> <!-- 當返回login視圖名時,轉入到login頁面 --> <result name="login">/login.jsp</result> </global-results>
當瀏覽者直接向該Action發送請求時,將會出現如下效果:
為了避免在每個Action中重復配置該攔截器,可以將該攔截器配置成一個默認攔截器棧,這個默認攔截器棧應該包含default-stack攔截器棧和權限檢查攔截器。
定義自己的默認攔截器棧的配置如下:
<interceptors> <!-- 定義權限檢查攔截器 --> <interceptor name="authority" class="com.app.interceptor.AuthorityInterceptor"></interceptor> <!-- 定義一個包含權限檢查的攔截器棧 --> <interceptor-stack name="mydefault"> <!-- 包含默認攔截器 --> <interceptor-ref name="default-stack"></interceptor-ref> <!-- 包含authority攔截器 --> <interceptor-ref name="authority"></interceptor-ref> </interceptor-stack> </interceptors>
一旦定義了上面的mydefault攔截器棧,我們就可以使用該攔截棧了
<default-interceptor-ref name="mydefault" />
一旦在某個包下定義了該默認攔截器棧,那么在該包下所有的Action都會自動增加權限檢查功能。對于那些不需要使用權限控制的Action,我們可以將他們定義在另外的包中。這個包中依然使用Struts 2原有的默認攔截棧,將不會有權限控制功能
讀李剛《輕量級 Java EE企業應用實戰》