Struts2 攔截器

攔截器的概念是Servlet篩檢程式或JDK代理類一樣的。攔截器允許橫切功能分開實現的動作,以及框架。使用攔截器,可以實現如下:

  • 提供預處理行動之前被稱為邏輯。

  • 提供後處理邏輯動作後被調用

  • 捕獲異常,這樣可以進行替代處理。

Struts2框架提供的許多功能都使用攔截實現的例子包括異常處理,檔上傳,生命週期回調和驗證等事實上作為Struts2的基礎,其功能攔截,這可能有7或8攔截器分配給每個動作。

Struts2框架的攔截器:

Struts 2框架提供了良好的箱攔截列表來預先設定的,並準備使用。下麵列出了幾個重要的攔截:

SN 攔截器 & 描述
1 alias
Allows parameters to have different name aliases across requests.
2 checkbox
Assists in managing check boxes by adding a parameter value of false for check boxes that are not checked.
3 conversionError
Places error information from converting strings to parameter types into the action's field errors.
4 createSession
Automatically creates an HTTP session if one does not already exist.
5 debugging
Provides several different debugging screens to the developer.
6 execAndWait
Sends the user to an intermediary waiting page while the action executes in the background.
7 exception
Maps exceptions that are thrown from an action to a result, allowing automatic exception handling via redirection.
8 fileUpload
Facilitates easy file uploading.
9 i18n
Keeps track of the selected locale during a user's session.
10 logger
Provides simple logging by outputting the name of the action being executed.
11 params
Sets the request parameters on the action.
12 prepare
This is typically used to do pre-processing work, such as setup database connections.
13 profile
Allows simple profiling information to be logged for actions.
14 scope
Stores and retrieves the action's state in the session or application scope.
15 ServletConfig
Provides the action with access to various servlet-based information.
16 timer
Provides simple profiling information in the form of how long the action takes to execute.
17 token
Checks the action for a valid token to prevent duplicate formsubmission.
18 validation
Provides validation support for actions

請看Struts 2文檔的完整細節上面提到的攔截。會告訴如何使用Struts應用程式在一個攔截器。

如何使用攔截器?

讓我們來看看如何使用已有的攔截,我們的“Hello World”程式。我們將使用計時器來測量過了多長時間執行操作方法,其目的是攔截。同時使用params攔截器,其目的是發送請求參數的動作。您可以嘗試不使用這個攔截您的示例中會發現,沒有被設置name屬性,因為參數是無法達到動作。

我們將繼續HelloWorldAction.java,web.xml 的helloWorld.jsp 和 index.jsp 檔,因為他們已經建立了範例章節,但讓我們如下修改struts.xml檔,添加一個攔截器


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
   "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
   "http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
   <constant name="struts.devMode" value="true" />
   <package name="helloworld" extends="struts-default">
      <action name="hello"
         class="com.zaixian.struts2.HelloWorldAction"
         method="execute">
         <interceptor-ref name="params"/>
         <interceptor-ref name="timer" />
         <result name="success">/HelloWorld.jsp</result>
      </action>
   </package>
</struts>

右鍵點擊專案名稱,並單擊 Export > WAR File 創建一個WAR檔。然後部署在Tomcat 的webapps目錄下這個WAR。最後,啟動Tomcat伺服器和嘗試訪問URL http://localhost:8080/HelloWorldStruts2/index.jsp。這會給你以下畫面:

Hello World Input

現在,在給定的文本框中輸入單詞,並單擊“Say Hello按鈕執行已定義的動作。現在,如果將檢查生成的日誌,會發現下麵的文字:


INFO: Server startup in 3539 ms
27/08/2011 8:40:53 PM
com.opensymphony.xwork2.util.logging.commons.CommonsLogger info
INFO: Executed action [//hello!execute] took 109 ms.

這裏底行,正在生成因為這告訴動作發生要執行的總共為 109ms定時器的攔截器。

創建自定義的攔截器

在應用程式中使用自定義的攔截器是一種優雅的方式提供橫切的應用功能。創建一個自定義攔截器是很容易的,需要擴展的介面,下麵的Interceptor介面:


public interface Interceptor extends Serializable{
   void destroy();
   void init();
   String intercept(ActionInvocation invocation)
   throws Exception;
}

正如其名稱所表明的,init()方法提供了一種方法來初始化攔截器,並destroy() 方法提供了一種工具攔截清理。不同的行動,攔截被重用跨請求和需要是線程安全的,尤其是intercept() 方法。 

ActionInvocation對象可以訪問運行時環境。它允許訪問的動作本身和方法調用的動作,並確定動作是否已被調用。

如果不需要初始化或清除代碼,可以擴展AbstractInterceptor類。這提供了一個默認的無操作實現的init()和 destroy()方法。

創建攔截器類:

讓我們創建Java資源 MyInterceptor.java> src 檔夾:


package com.zaixian.struts2;

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

public class MyInterceptor extends AbstractInterceptor {

   public String intercept(ActionInvocation invocation)throws Exception{

      /* let us do some pre-processing */
      String output = "Pre-Processing";
      System.out.println(output);

      /* let us call action or next interceptor */
      String result = invocation.invoke();

      /* let us do some post-processing */
      output = "Post-Processing";
      System.out.println(output);

      return result;
   }
}

就像看到的,實際行動將使用攔截器執行invocation.invoke()調用。所以,可以做一些前處理和一些處理後,根據需要。

該框架本身啟動的過程中,在第一次調用ActionInvocation對象的invoke()。每次 invoke()被調用,ActionInvocation的諮詢的狀態和執行為准攔截接下來。通過請求流以下數據圖顯示了相同的概念:

ActionInvocation

創建動作類:

讓我們創建一個Java檔HelloWorldAction.java的Java下Java Resources > src下麵給出的內容包名為 com.zaixian.struts2。

package com.zaixian.struts2;

import com.opensymphony.xwork2.ActionSupport;

public class HelloWorldAction extends ActionSupport{
   private String name;

   public String execute() throws Exception {
      System.out.println("Inside action....");
      return "success";
   }

   public String getName() {
      return name;
   }

   public void setName(String name) {
      this.name = name;
   }
}

在前面的例子中,我們已經看到,這是一個相同的類。我們有標準的“名稱”屬性的getter和setter方法​​,並返回字串“success”的執行方法。

創建視圖

讓我們創建以下JSP檔helloWorld.jsp,在eclipse專案在WebContent檔夾。

<%@ page contentType="text/html; charset=UTF-8" %>
<%@ taglib prefix="s" uri="/struts-tags" %>
<html>
<head>
<title>Hello World</title>
</head>
<body>
   Hello World, <s:property value="name"/>
</body>
</html>

創建頁面:

我們還需要在WebContent檔夾中創建 index.jsp。該檔將作為初始動作URL,用戶可以在其中點擊告訴Struts 2框架調用 HelloWorldAction類定義的方法呈現 helloWorld.jsp視圖。

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
   pageEncoding="ISO-8859-1"%>
<%@ taglib prefix="s" uri="/struts-tags"%>
   <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Hello World</title>
</head>
<body>
   <h1>Hello World From Struts2</h1>
   <form action="hello">
      <label for="name">Please enter your name</label><br/>
      <input type="text" name="name"/>
      <input type="submit" value="Say Hello"/>
   </form>
</body>
</html>

Hello 動作定義在上面的視圖檔將被映射到HelloWorldAction類和其執行方法使用struts.xml檔。

配置檔

現在,我們需要註冊我們的攔截器,然後調用它默認的攔截器在前面的例子中調用。要註冊一個新定義的攔截,直接放在的<interceptors>...</interceptors>標籤下<package>的標籤插件struts.xml檔。您可以跳過這一步為默認的攔截器,就像我們在我們前面的例子。但在這裏,讓我們註冊和使用它,如下所示:


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
    "http://struts.apache.org/dtds/struts-2.0.dtd">

<struts>
   <constant name="struts.devMode" value="true" />
   <package name="helloworld" extends="struts-default">

      <interceptors>
         <interceptor name="myinterceptor"
            class="com.zaixian.struts2.MyInterceptor" />
      </interceptors>

      <action name="hello"
         class="com.zaixian.struts2.HelloWorldAction"
         method="execute">
         <interceptor-ref name="params"/>
         <interceptor-ref name="myinterceptor" />
         <result name="success">/HelloWorld.jsp</result>
      </action>

   </package>
</struts>

應該指出的是,可以註冊多個攔截器<package>標籤內,同一時間,可以調用多個攔截裏面的<action>標籤。可以調用相同的攔截器與不同的動作。 

web.xml檔需要在 WEB-INF檔夾下創建 WebContent 如下:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns="http://java.sun.com/xml/ns/javaee"
   xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
   xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
   http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
   id="WebApp_ID" version="3.0">

   <display-name>Struts 2</display-name>
   <welcome-file-list>
      <welcome-file>index.jsp</welcome-file>
   </welcome-file-list>
   <filter>
      <filter-name>struts2</filter-name>
      <filter-class>
         org.apache.struts2.dispatcher.FilterDispatcher
      </filter-class>
   </filter>

   <filter-mapping>
      <filter-name>struts2</filter-name>
      <url-pattern>/*</url-pattern>
   </filter-mapping>
</web-app>

右鍵點擊專案名稱,並單擊  Export > WAR File 檔創建一個WAR檔。然後部署在Tomcat 的webapps目錄下這個WAR。最後,啟動Tomcat 伺服器和嘗試訪問URL http://localhost:8080/HelloWorldStruts2/index.jsp。這會給你以下畫面:

Hello World Input

現在,在給定的文本框中輸入任何單詞,並單擊“Say Hello“ 按鈕執行已定義的動作。現在,如果檢查生成的日誌,會發現下麵的文本下方:


Pre-Processing
Inside action....
Post-Processing

堆疊多個攔截器:

可以想像,配置多個攔截器每個動作很快就會變得非常難以控制。出於這個原因,攔截器與攔截器棧管理。下麵是一個例子,直接從在struts-default.xml檔:


<interceptor-stack name="basicStack">
   <interceptor-ref name="exception"/>
   <interceptor-ref name="servlet-config"/>
   <interceptor-ref name="prepare"/>
   <interceptor-ref name="checkbox"/>
   <interceptor-ref name="params"/>
   <interceptor-ref name="conversionError"/>
</interceptor-stack>

上面的棧被調用basicStack,可用於在配置中,如下所示。此配置節點放置在<package.../>節點下。每個<interceptor-ref.../>標記引用一個攔截器或攔截器棧已配置在當前的攔截器棧。因此,這是非常重要的,以確保該名稱是唯一的所有攔截器和攔截器棧配置配置初始的攔截器和攔截器棧時。 

我們已經看到了如何應用攔截的動作,將攔截器棧是沒有什麼不同。事實上,我們完全使用相同的標籤:


<action name="hello" class="com.zaixian.struts2.MyAction">
   <interceptor-ref name="basicStack"/>
   <result>view.jsp</result>
</action

上述註冊的“basicStack”所有6個攔截器完成註冊的棧 Hello 動作。應該指出的是,攔截器執行的順序在配置中。例如,在上述情況下,異常將被執行,servlet 配置等。


上一篇: Struts2 Action/動作 下一篇: Struts2快速入門