Struts2入門(二)——配置攔截器

1、前言

以前便了解過,Struts 2的核心控制器是一個Filter過濾器,負責攔截全部的用戶請求,當用戶請求發送過來時,會去檢測struts.xml是否存在這個action,若是存在,服務器便會自動幫咱們跳轉到指定的處理類中去處理用戶的請求,基本流程以下:html

該流程筆者理解是基本流程,。若是有不對的地方,請下方留言。我會改正。謝謝;java

好,接着往下講:apache

注意:在struts.xml中,配置文件必須有該請求的處理類才能正常跳轉,同時,返回SUCCESS字符串的類,必須繼承ActionSupport,若是你沒有繼承,那麼就返回"success",一樣可以跳轉到jsp邏輯視圖,可是必須確保你struts.xml有<result name="success">xx.jsp</result>,該標籤,具體操做在上一篇文章有介紹過簡單例子。服務器

1.一、瞭解攔截器jsp

什麼是攔截器,它的做用是什麼?ide

攔截器,實際上就是對調用方法的改進。測試

做用:動態攔截對Action對象的調用,它提供了一種機制可使開發者能夠定義在一個action執行的先後執行的代碼,也能夠在一個action執行前阻止其執行。同時也是提供了一種能夠提取action中可重用的部分的方式。ui

攔截器的執行順序:this

在執行Action的execute方法以前,Struts2會首先執行在struts.xml中引用的攔截器,在執行完全部引用的攔截器的intercept方法後,會執行Action的execute方法。 spa

2、實際操做

2.一、自定義攔截器

新建一個類繼承AbstractInterceptor。

package com.Interceptor;

import java.util.Date;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;

public class MyInterceptor extends AbstractInterceptor {
    private String name;//該屬性與struts.xml中的<param name="name">簡單攔截器</param>一致,也就是說該name的值是簡單攔截器
    public void setName(String name) {
        this.name = name;
    }

    //攔截action請求
    @Override
    public String intercept(ActionInvocation arg0) throws Exception {
        //取得被攔截的action
        LoginAction action = (LoginAction)arg0.getAction();
        System.out.println(name+":攔截器的動做------"+"開始執行登陸action的時間爲:"+new Date());
        long start = System.currentTimeMillis();
        /*
         * ActionInvocation.invoke()就是通知struts2接着幹下面的事情
         * 好比 調用下一個攔截器 或 執行下一個Action
         * 就等於退出了你本身編寫的這個interceptor了
         * 在這裏是去調用action的execute方法,也就是繼續執行Struts2 接下來的方法*/
        String result = arg0.invoke(); 
        System.out.println(name+":攔截器的動做------"+"執行完登陸action的時間爲:"+new Date());
        long end = System.currentTimeMillis();
        System.out.println(name+":攔截器的動做------"+"執行完該action的時間爲:"+(end-start)+"毫秒");
        
        System.out.println(result);    //輸出的值是:success
        return result;
    }
}
/**
 * 該頁面的效果以下:
 * 簡單攔截器:攔截器的動做------開始執行登陸action的時間爲:Mon Oct 24 19:06:17 CST 2016
         用戶名:admin,密碼:123
         簡單攔截器:攔截器的動做------執行完登陸action的時間爲:Mon Oct 24 19:06:18 CST 2016
         簡單攔截器:攔截器的動做------執行完該action的時間爲:1130毫秒
   success

 * */

 

在struts.xml中配置

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
    "http://struts.apache.org/dtds/struts-2.5.dtd">
<struts>
    
    <!--簡單的攔截器  -->
    <package name="Interceptor" extends="struts-default" namespace="/ac">
        <!-- 跳轉前攔截 -->
        <interceptors>
            <!-- 聲明簡單的過濾器 -->
            <interceptor name="Inter" class="com.Interceptor.MyInterceptor">
                <!--傳遞name的參數  -->
                <param name="name">簡單攔截器</param>
            </interceptor>
        </interceptors>
        <action name="loginaction" class="com.Interceptor.LoginAction">
            <result name="success">/Interceptor/welcome.jsp</result>
            <result name="input">/Interceptor/error.jsp</result>
            <!--注意:若是不加默認的攔截器的話,那麼類型轉換不會執行,也就是說不會把文本上的值賦值給實體類  -->
            <interceptor-ref name="defaultStack"/>
            
            <!-- 簡單的過濾器,定義在這裏告訴攔截器在此處action執行 -->
            <interceptor-ref name="Inter">
            </interceptor-ref>
        </action>
    </package>
</struts>    

struts.xml解析:

<interceptors>:表示聲明攔截器

<interceptor>: 表示定義一個攔截器

<param>:給該攔截器一個參數,屬性爲name

<interceptor-ref name="">:表示該攔截器在這個action中使用。

 

新建LoginAction類,繼承ActionSupport

package com.Interceptor;

import com.opensymphony.xwork2.ActionSupport;

//action類處理
public class LoginAction extends ActionSupport {
    private String username;
    private String pwd;
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public String getPwd() {
        return pwd;
    }
    public void setPwd(String pwd) {
        this.pwd = pwd;
    }
    //默認執行execute方法
    public String execute(){
        System.out.println("用戶名:"+username+",密碼:"+pwd);
        return SUCCESS;
    }

 

新建jsp視圖界面

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="/struts-tags" prefix="s"%>    
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>簡單的登陸攔截</title>
</head>
<body>
    <!--若是在struts.xml中,package包中有配置namespace的話,那麼在此處就應該配置。否則會報404錯誤  -->
    <s:form action="loginaction" namespace="/ac"> 
          <s:textfield label="User Name" name="username"/>
          <s:password label="Password" name="pwd" />
           <s:submit/>
      </s:form>  
</body>
</html>

(代碼筆者測試沒問題)

 

2.二、過濾方法:

攔截器不只能夠定義多個攔截,還能夠指定攔截特定的方法。

struts.xml的配置

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"
    "http://struts.apache.org/dtds/struts-2.5.dtd">
<struts>
    
    <!--簡單的攔截器  -->
    <package name="Interceptor" extends="struts-default" namespace="/ac">
        <!-- 跳轉前攔截 -->
        <interceptors>
            <!-- 聲明方法過濾器 -->    
            <interceptor name="myMethod" class="com.Interceptor.MyMethodInterceptor">
                <param name="name">方法過濾攔截器</param>
            </interceptor>
        </interceptors>
        <action name="loginaction" class="com.Interceptor.LoginAction" method="method1"> <!-- 若是是攔截方法的話,改成method="method2" -->
            <result name="success">/Interceptor/welcome.jsp</result>   <!-- /Interceptor是筆者文件夾。別弄錯了-->
            <result name="input">/Interceptor/error.jsp</result>
            <!--注意:若是不加默認的攔截器的話,那麼類型轉換不會執行,也就是說不會把文本上的值賦值給實體類  -->
            <interceptor-ref name="defaultStack"/>
            
            
            <!-- 方法過濾器 -->
            <interceptor-ref name="myMethod">
                <param name="name">更名後的方法過濾器</param>
                 <param name="includeMethods">method1,method3</param>  <!--表示該方法不被攔截-->
                <param name="excludeMethods">method2</param>           <!--表示該方法被攔截  -->
            </interceptor-ref>
        </action>
    </package>
</struts>    

 

修改LoginAction類

package com.Interceptor;

import com.opensymphony.xwork2.ActionSupport;

//action類處理
public class LoginAction extends ActionSupport {
    private String username;
    private String pwd;
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public String getPwd() {
        return pwd;
    }
    public void setPwd(String pwd) {
        this.pwd = pwd;
    }
//    過濾的方法
  public String method1() throws Exception {  
        System.out.println("Action執行方法:method1()");  
        return SUCCESS;  
    }  
    public String method2() throws Exception {  
        System.out.println("Action執行方法:method2()");  
        return SUCCESS;  
    }  
 
    public String method3() throws Exception {  
        System.out.println("Action執行方法:method3()");  
        return SUCCESS;  
    }  
    
}

 

新建MyMethodInterceptor類繼承MethodFilterInterceptor

MethodFilterInterceptor類表示你定義的攔截器支持方法過濾。

package com.Interceptor;

import java.util.Date;

import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.MethodFilterInterceptor;

//過濾方法
public class MyMethodInterceptor extends MethodFilterInterceptor {
    private String name;
    public void setName(String name) {
        this.name = name;
    }
    @Override
    protected String doIntercept(ActionInvocation arg0) throws Exception {
        //取得被攔截的action
        LoginAction action = (LoginAction)arg0.getAction();
        System.out.println(name+":攔截器的動做------"+"開始執行登陸action的時間爲:"+new Date());
        long start = System.currentTimeMillis();
        String result = arg0.invoke(); 
        System.out.println(name+":攔截器的動做------"+"執行完登陸action的時間爲:"+new Date());
        long end = System.currentTimeMillis();
        System.out.println(name+":攔截器的動做------"+"執行完該action的時間爲:"+(end-start)+"毫秒");
        
        System.out.println(result);    //輸出的值是:success
        return result;
    }

}

至於jsp視圖,同樣,不須要改變。

獲得的結果能夠看出來:

當method="method1"或者是method="method3"的時候,會自動去執行MyMethodInterceptor 的方法doIntercept,而後跳轉到welcome.jsp界面。

當method="method2"的時候,控制檯會出現 Action執行方法:method2(),以後便被攔截了。

以上就是攔截方法的基本代碼,例子很簡單,可是重在理解。

可能筆者疑惑,爲何須要過濾方法呢?由於攔截器它會自動攔截全部的方法,回形成資源的損耗,因此有些方法咱們能夠指定不被攔截。

 

2.三、監聽過濾器:

在攔截器中,execute方法執行以前或者以後的方法都被攔截在intercept方法中,這些的結構不夠明白,咱們能夠定義監聽,雖然好像沒什麼用,可是瞭解一下也挺不錯的。

實現攔截器的監聽結果必須實現PreResultListener接口。

 

package com.Interceptor;

import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.PreResultListener;

//過攔截器配置一個監聽器
public class MyPreResultListener implements PreResultListener {
    //定義處理Result以前的行爲
    @Override
    public void beforeResult(ActionInvocation arg0, String arg1) {
        System.out.println("返回的邏輯視圖爲:"+arg1);
    }
}

 

而後MyMethodInterceptor類修改成:

package com.Interceptor;

import java.util.Date;

import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.MethodFilterInterceptor;

//過濾方法
public class MyMethodInterceptor extends MethodFilterInterceptor {
    private String name;
    public void setName(String name) {
        this.name = name;
    }
    @Override
    protected String doIntercept(ActionInvocation arg0) throws Exception {

        //將一個攔截結果的監聽器註冊給攔截器
        arg0.addPreResultListener(new MyPreResultListener());
        System.out.println("execute方法被調用以前的攔截");
        //調用下一個攔截器或者action的執行方法
        String result = arg0.invoke();
        System.out.println("execute方法被調用以後的攔截");
        return result;
    }

}

 

以上就是攔截器基本知識,若是有錯誤的地方,請指正。謝謝。

相關文章
相關標籤/搜索