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

来源:http://www.cnblogs.com/IT-1994/archive/2016/10/25/5997079.html
-Advertisement-
Play Games

一、前言 之前便瞭解過,Struts 2的核心控制器是一個Filter過濾器,負責攔截所有的用戶請求,當用戶請求發送過來時,會去檢測struts.xml是否存在這個action,如果存在,伺服器便會自動幫我們跳轉到指定的處理類中去處理用戶的請求,基本流程如下: 該流程筆者理解是基本流程,。如果有不對 ...


一、前言

之前便瞭解過,Struts 2的核心控制器是一個Filter過濾器,負責攔截所有的用戶請求,當用戶請求發送過來時,會去檢測struts.xml是否存在這個action,如果存在,伺服器便會自動幫我們跳轉到指定的處理類中去處理用戶的請求,基本流程如下:

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

好,接著往下講:

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

1.1、瞭解攔截器

什麼是攔截器,它的作用是什麼?

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

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

攔截器的執行順序:

在執行Action的execute方法之前,Struts2會首先執行在struts.xml中引用的攔截器,在執行完所有引用的攔截器的intercept方法後,會執行Action的execute方法。 

二、實際操作

2.1、自定義攔截器

新建一個類繼承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.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.3、監聽過濾器:

在攔截器中,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;
    }

}

 

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


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 1、用戶發送請求到前端控制器(DispatcherServlet); 2、前端控制器轉發請求到處理器映射器(HandlerMapping); 3、處理器映射器將攔截的Action返回到前端控制器; 4、前端控制器將攔截的Action請求處理器適配器(HandlerAdapter); 5、處理器適配器 ...
  • 1.輸入參數為單個值 delete from MemberAccessLog where accessTimestamp = #value# delete from MemberAccessLog where accessTimestamp = #value# 2.輸入參數為一個對象 ... ...
  • ord('a');//=>97 返回小寫a 的ascii碼值97 chr(97);//=>a 返回ascii碼表上的97對應的 小寫a ...
  • dedecms 基本包含了一個常規網站需要的一切功能,擁有完善的中文學習資料,很容易上手。學會dedecms 的模板修改、欄目新增、內容模型新增和常用的標簽調用方法後,即便我們不懂 php 語言也能獨立完成一個網站了。 在百度網盤中分享,織夢CMS模板製作手冊 http://pan.baidu.co ...
  • 回到目錄 一般sso的說明 在Lind.DDD框架里,有對單點登陸的集成,原理就是各個網站去sso網站統一登陸授權,之後在sso網站將登陸的token進行存儲,存儲方式隨你(cache,redis,mongodb,file),之後業務平臺在訪問資源時,如果這些資源需要用戶登陸才能訪問,就會去sso網 ...
  • 一、前言 筆者一直覺得,學習一個知識點,你首先要明白,這東西是什麼?有什麼用?這樣你才能瞭解。好了,不說廢話。 1.1、類型轉換為何存在?什麼是類型轉換? 在MVC框架中,都是屬於表示層解決方案,都需要負責收集用戶請求的參數,並且將請求參數傳給應用的控制器組件,但是,這裡有一個問題,客戶端提交的請求 ...
  • 設計模式系列-01-開篇 設計模式系列-02-創建模式-簡單工廠 文字恐懼者請看腦圖 http://naotu.baidu.com/file/7cdf927d18994f1543651245cac6c538?token=6dd2bea9552cf4f1 1.設計模式 設計模式(Design patt ...
  • 前言 在解決了上一次關於超級話題積分bug後,又接到超級話題簽到提醒的產品需求。這是一篇偏於技術實現的文章,講述的比較籠統,業務圍繞超級話題的簽到提醒進行展開。如果,您對超級話題簽到提醒的技術背景與實現感興趣,那麼這篇文章希望對你有幫助。 產品 最近,在忙活超級話題的簽到提醒產品的開發。首先,這是第 ...
一周排行
    -Advertisement-
    Play Games
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...