1. 程式人生 > >Struts2攔截器

Struts2攔截器

apach style tro cells 引入 span type can getc

一、內容提要

1.攔截器的概念及應用

2.STRUTS2自帶的攔截器

3.自定義攔截器

4.自定義攔截器的應用

二、攔截器的概念及應用

攔截器(Interceptor)是Struts2的一個重要特性。Struts2框架的大多數核心功能都是通過攔截器來實現的,像避免表單重復提交、類型轉換、對象組裝、驗證、文件上傳等,都是在攔截器的幫助下實現的。攔截器之所以稱為“攔截器”,是因為它可以在Action執行之前或執行之後攔截調用。

Struts2將它的核心功能放到攔截器中實現而不是分散到Action中實現,有利於系統的解耦,使得功能的實現類類似於個人電腦的組裝,變成了可插拔的。需要某個功能就“插入”一個攔截器,不需要某個功能就“拔出”。

攔截器應用:

  • 為action動態添加輸入驗證
  • 對象組裝(也就是進行數據類型轉換)
  • 權限控制
  • 日誌記錄等

三、STRUTS2自帶的攔截器

Struts2本身提供了很多的攔截器,這些攔截器已經在struts-default.xml文件中定義,在Web應用程序中可以直接引用這些攔截器。這也是為什麽struts配置文件裏經常有這樣一個屬性extends="struts-default"加載Struts2本身提供的攔截器。

具體情況如下:

序號

攔截器名稱

作用

1

alias

在請求之間轉換名字不同的相似參數

2

chain

將所有的屬性從前一個Aciotn復到當前Action中

3

params

最基本的一個攔截器,負責解析HTTP請求中的參數,並將參數值設置成Action對應的屬性值

4

cookie

基於cookie的名/值設置Action的屬性

5

conversionError

將類型轉換錯誤從ActionContext中取出,添加到Action字段錯誤中

6

createSession

自動創建一個HttpSession對象

7

debugging

當struts.devMode屬性設置為true,才有,用於調試

8

execAndWait

可以用於防止後臺Action Http請求超時

9

exception

提供了異常處理的核心功能

10

fileUpload

用於對文件上傳提供支持

11

i18n

用於支持國際化

12

timer

負責輸出action的執行時間,用於分析action

13

token

檢查傳到Action的token值的有效性,防表單重復提交

四、自定義攔截器

作為“框架(framework)”,可擴展性是不可或缺的,因為世上沒有放之四海而皆準的東西。雖然,Struts 2為我們提供如此豐富的攔截器實現,但是這並不意味我們失去創建自定義攔截器的能力,恰恰相反,在Struts 2自定義攔截器是相當容易的一件事。

在Struts2中編寫攔截類,有如下二種方式:

實現Interceptor此接口

繼承AbstractInterceptor類(一般會選擇此種方式)

案例:

編寫攔截器類:

註意:在編寫攔截器時要註意,攔截器必順是無狀態的,換句話 說,在攔截器類中不應該有實例變量。這是因為struts2對每一個Action的請求使用的是同一個攔截器實例來處理,如果攔截器有狀態,在多線程並發情況下,攔截器的狀態將不可預測。

package com.silvan.interceptor;

import com.opensymphony.xwork2.ActionInvocation;

import com.opensymphony.xwork2.interceptor.AbstractInterceptor;

public class AroundInterceptor extends AbstractInterceptor {

public void init() {

System.out.println("這是一個初始化方法");

}

public String intercept(ActionInvocation invocation) throws Exception {

String result = "";

System.out.println("我是在action的execute方法執行之前動作");

result = invocation.invoke();

System.out.println("我是在action的execute方法執行之後動作");

return result;

}

public void destroy() {

System.out.println("這是一個清理方法");

}

}

Struts.xml配置攔截器

<?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="InterceptorDemo" extends="struts-default">

<!--在這裏定義攔截器 -->

<interceptors>

<interceptor name="around" class="com.silvan.interceptor.AroundInterceptor" />

</interceptors>

<action name="interceptor" class="com.silvan.action.InterceptorAction">

<result>/index.jsp </result>

<!--在這裏使用攔截器,當使用自定義的攔截器後,默認的攔截器將失效,這樣原本struts提供的攔截器功能就會失效,比如用於類型轉換的params攔截器 -->

<interceptor-ref name="around"/>

</action>

</package>

</struts>

Action類

public class InterceptorAction extends ActionSupport {

private int id;

private String userName;

@Override

public String execute() throws Exception {

System.out.println("執行interceptor Action……");

return SUCCESS;

}

Get/set……

}

頁面顯示Login

<form action="interceptor">

<table>

<tr><td>編號:<input type="text" name="id" value="1"></td></tr>

<tr><td>姓名:<input type="text" name="userName" value="ross"></td></tr>

<tr><td><input type="submit" value="submit"></td></tr>

</table>

</form>

返回顯示index

<body>

編號:<s:property value="id"/><br/>

用戶名:<s:property value="userName"/>

</body>

當自定義了攔截器後,默認的攔截器將失效, index頁面取不到登錄的值,所以需要引入默認的攔截器。配置如下:

Struts.xml配置攔截器

<?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="InterceptorDemo" extends="struts-default">

<!--在這裏定義攔截器 -->

<interceptors>

<interceptor name="around" class="com.silvan.interceptor.AroundInterceptor" />

<!-- 定義攔截器棧 -->

<interceptor-stack name="myStack">

<!--引用攔截器 -->

<interceptor-ref name="around"></interceptor-ref>

<!-- 引入默認的攔截器 -->

<interceptor-ref name="defaultStack"></interceptor-ref>

</interceptor-stack>

</interceptors>

<!—針對包引用攔截器,這樣就不僅僅對某個action起作用 -->

<!-- <default-interceptor-ref name="mystack"/> -->

<action name="interceptor" class="com.silvan.action.InterceptorAction">

<result>/index.jsp </result>

<!—引用攔截器棧 -->

<interceptor-ref name="myStack"/>

</action>

</package>

</struts>

Struts.xml配置多個攔截器方式:

<?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="InterceptorDemo" extends="struts-default">

<!--在這裏定義攔截器 -->

<interceptors>

<interceptor name="around" class="com.silvan.interceptor.AroundInterceptor" />

<interceptor name="around1" class="com.silvan.interceptor.AroundInterceptor1" />

<!-- 定義攔截器棧 -->

<interceptor-stack name="myStack">

<!--引用攔截器 -->

<interceptor-ref name="around"></interceptor-ref>

<interceptor-ref name="around1"></interceptor-ref>

<!-- 引入默認的攔截器 -->

<interceptor-ref name="defaultStack"></interceptor-ref>

</interceptor-stack>

</interceptors>

<!-- <default-interceptor-ref name="mystack"/> -->

<action name="interceptor" class="com.silvan.action.InterceptorAction">

<result>/index.jsp </result>

<interceptor-ref name="myStack"/>

</action>

</package>

</struts>

五、練習

需求分析

在一個系統中,如果用戶沒有選擇登錄系統就直接使用相應的資源,從常理上來講這是不允許的。也就是說在當用戶訪問受保護資源時,攔截器截獲用戶請求,判斷用戶是否已經登錄,如果沒有登錄,則向用戶顯示登錄頁面,請求用戶登錄如果用戶已經登錄,則向用戶顯示資源。

Action

public String execute() throws Exception {

System.out.println("執行interceptor Action……");

if(userName!=null){

ActionContext context = ActionContext.getContext();

Map<String,Object> session = context.getSession();

session.put("userName", userName);

}

return SUCCESS;

}

Interceptor

public String intercept(ActionInvocation invocation) throws Exception {

String result = "";

System.out.println("我是在action的execute方法執行之前動作");

String user =(String) ActionContext.getContext().getSession().get("userName");

if(user!=null && "".equals(user)){

System.out.println("非法訪問……");

return "error_login";

}

result = invocation.invoke();

System.out.println("我是在action的execute方法執行之後動作");

return result;

}

配置

<!-- <global-results name="error_login">/login.jsp</global-results> -->

<!-- <default-interceptor-ref name="mystack"/> -->

<action name="interceptor" class="com.silvan.action.InterceptorAction">

<result>/index.jsp </result>

<result name="error_login">/login.jsp</result>

<interceptor-ref name="myStack"/>

</action>

Struts2攔截器