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
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...