Struts2自定義攔截器驗證登錄


【Struts2】☆★之Struts2自定義攔截器驗證登錄


       在實際項目中我們的方法都是需要驗證登錄狀態的,所以在使用Struts2框架的項目中,自定義攔截器是一個不錯的選擇,本文就簡單介紹如何使用攔截器,對全局方法進行驗證登錄狀態!


第一步搭建Struts2開發環境


第二步:編寫一個Action方法


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
package csg.struts2.action;
/**
 *
 * @author 小夜的傳說
 * @2014-4-18
 * @struts
 * @csg.struts2.action
 * @StrutsAction
 * @2014-4-18上午1:03:37
 */
public class StrutsAction {
    private String message;
    public String getMessage() {
        return message;
    }
    public void setMessage(String message) {
        this.message = message;
    }
    public String execute() {
        message = "execute方法";
        return "success";
    }
    public String addUI() {
        message = "addUI方法";
        return "success";
    }
}


第三步寫一個jsp視圖模仿登錄狀態,只要訪問這個jsp了,就把用戶信息放在Session中代表已經登錄,可以操作action方法,沒有訪問這個jsp代表沒有登錄,不可以操作任何方法


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>攔截器</title>
    <meta http-equiv="pragma" content="no-cache">
    <meta http-equiv="cache-control" content="no-cache">
    <meta http-equiv="expires" content="0">
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
  </head>
  <body>
    <%
    request.getSession().setAttribute("user", "login");
    %>
    用戶已登錄
  </body>
</html>


第四步:配置struts.xml文件,先測試方法


1
2
3
4
5
6
7
8
9
10
11
12
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
    "http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
    <package name="struts2" namespace="/test" extends="struts-default">
        <!-- 通配符形式訪問action -->
        <action name="list_*" class="csg.struts2.action.StrutsAction" method="{1}">
            <result name="success">/WEB-INF/page/success.jsp</result>
        </action>
    </package>
</struts>


第五步:部署到服務器上直接訪問:http://127.0.0.1:8080/struts/test/list_addUI.action

會打印出addUI方法!ok,下面就是寫一個攔截器了!


第六步:編寫登錄攔截器


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
package csg.struts2.interceptor;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.Interceptor;
/**
 *
 * @author 小夜的傳說
 * @2014-4-18
 * @struts
 * @csg.struts2.interceptor
 * @LoginInterceptor
 * @2014-4-18上午1:03:29
 */
public class LoginInterceptor implements Interceptor {
    // 方法在攔截器被垃圾回收之前調用,用來回收init方法初始化的資源
    public void destroy() {
    }
    // 方法在攔截器被創建之後,在對Action鏡像攔截之前調用,使用這個方法主要是給攔截器做類似初始化的操作
    public void init() {
    }
    public String intercept(ActionInvocation invocation) throws Exception {
        Object user = ActionContext.getContext().getSession().get("user");
        if (user != null) {
            // 如果user不爲null,代表用戶已經登錄,允許執行action中的方法 這個結果就代表返回驗證通過
            return invocation.invoke();
        else {
            //提示用戶登錄,我這裏直接提示,在實際項目中,肯定會返回到登錄頁面
            ActionContext.getContext().put("message""你沒有登錄");
            return "success";
        }
    }
}


第七步:最重要的,我們要在寫好的struts.xml文件中,配置我們寫好的這個攔截器,這一步,我會寫的很詳細,看懂的童鞋,攔截器基本上可以很好掌握


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
    "http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
    <package name="struts2" namespace="/test" extends="struts-default">
        <interceptors>
            <interceptor name="logininterceptor" class="csg.struts2.interceptor.LoginInterceptor"/>
            <!-- 自定義一個攔截器棧,下面你攔截只需要用這個棧名字就行了 -->
            <interceptor-stack name="loginstack">
            <!-- 這個是系統攔截器棧,不這樣寫,就是當你單獨一個action引用攔截器的時候就無法使用攔截器的中的核心功能 -->
            <interceptor-ref name="defaultStack"/>
            <!-- 這個引用你自己寫的攔截器 -->
            <interceptor-ref name="logininterceptor" />
            </interceptor-stack>
        </interceptors>
        <!-- 這樣寫的意思是 在這個package包下面的所有action方法都需要攔截器 -->
        <default-interceptor-ref name="loginstack"></default-interceptor-ref>
        <!-- 全局視圖,這個就是說攔截到你沒登錄的時候提示你登錄 ,你做的話可以提示返回登錄界面-->
        <global-results>
            <result name="success">/WEB-INF/page/message.jsp</result>
        </global-results>
        <!-- 通配符形式訪問action -->
        <action name="list_*" class="csg.struts2.action.StrutsAction" method="{1}">
            <result name="success">/WEB-INF/page/success.jsp</result>
            <!-- 也可以這樣寫 ,但是這樣寫就比較麻煩了,假如你下面還有action,這樣你就每個action都需要引用,所以我注掉了-->
            <!-- <interceptor-ref name="loginstack"></interceptor-ref> -->
        </action>
    </package>
</struts>


第八步:解析


1、爲什麼<interceptor-ref name="defaultStack"/>

因爲Struts2攔截器是個很奇詭的東西,當你自定義攔截器之後,在某個方法引用自己編寫的攔截器之後,那麼Struts許多的核心攔截器將無法使用,所以我們我們一般將自己寫的攔截器和這個系統攔截器棧一起組成一個棧,這樣就可以繼續使用Struts2的攔截器了

可以參照struts源代碼,在struts2-core-2.3.16.1.jar下面有個struts-default.xml文件,搜索defaultStack

如圖:

wKioL1NQlPyzngGjAAKpjquV0yo427.jpg


2、配置全局攔截器的優缺點<default-interceptor-ref name="loginstack"></default-interceptor-ref>

假如,你某一個action方法需要另一個攔截器,但是其他方法不需要,這樣你就需要在這個action中單獨引用,注意,當你引用了這個攔截器之後,你定義的這個全局攔截器對於這個方法就會失效,所以一定要再次引用一次這個全局攔截器



3、爲什麼系統攔截器棧寫在你定義的攔截器之前

1
2
3
4
<!-- 這個是系統攔截器棧,不這樣寫,就是當你單獨一個action引用攔截器的時候就無法使用攔截器的中的核心功能 -->
            <interceptor-ref name="defaultStack"/>
            <!-- 這個引用你自己寫的攔截器 -->
            <interceptor-ref name="logininterceptor" />


因爲Struts在實例化的過程中讀取的xml是從上到下的這樣方式,所以本着項目安全角度,我們先讓系統執行Struts2核心攔截器,然後再執行自己寫的攔截器。當然你反過來寫也行,但是可能有些自己寫的複雜的攔截器在系統攔截器沒實例化之前,會失效。


4、本文詳細對於Struts2攔截器的基本原理進行了簡單解析,如果有哪位童鞋有意見,歡迎舉手!Thank you!



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章