java 攔截器、過濾器、監聽器

轉自:http://www.cnblogs.com/wangyuyu/archive/2013/07/02/3167354.html
 

1、理解Struts2攔截器html

1. Struts2攔截器是在訪問某個Action或Action的某個方法,字段以前或以後實施攔截,而且Struts2攔截器是可插拔的,攔截器是AOP的一種實現.java

2. 攔截器棧(Interceptor Stack)。Struts2攔截器棧就是將攔截器按必定的順序聯結成一條鏈。在訪問被攔截的方法或字段時,Struts2攔截器鏈中的攔截器就會按其以前定義的順序被調用。web

2、實現Struts2攔截器原理spring

Struts2攔截器的實現原理相對簡單,當請求struts2的action時,Struts 2會查找配置文件,並根據其配置實例化相對的 攔截器對象,而後串成一個列表,最後一個一個地調用列表中的攔截器apache

3、定義Struts2攔截器。編程

Struts2規定用戶自定義攔截器必須實現com.opensymphony.xwork2.interceptor.Interceptor接口。該接口聲明瞭3個方法,cookie

void init(); void destroy(); String intercept(ActionInvocation invocation) throws Exception;session

其中,init和destroy方法會在程序開始和結束時各執行一遍,無論使用了該攔截器與否,只要在struts.xml中聲明瞭該Struts2攔截器就會被執行。
intercept方法就是攔截的主體了,每次攔截器生效時都會執行其中的邏輯。app

 

不過,struts中又提供了幾個抽象類來簡化這一步驟。jsp

 

public abstract class AbstractInterceptor implements Interceptor;
public abstract class MethodFilterInterceptor extends AbstractInterceptor;

 

都是模板方法實現的。

其中AbstractInterceptor提供了init()和destroy()的空實現,使用時只須要覆蓋intercept()方法;

而MethodFilterInterceptor則提供了includeMethods和excludeMethods兩個屬性,用來過濾執行該過濾器的action的方法。能夠經過param來加入或者排除須要過濾的方法。

通常來講,攔截器的寫法都差很少。看下面的示例:

 

package interceptor;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.Interceptor;
public class MyInterceptor implements Interceptor {
public void destroy() {
// TODO Auto-generated method stub
}
public void init() {
// TODO Auto-generated method stub
}
public String intercept(ActionInvocation invocation) throws Exception {
System.out.println("Action執行前插入 代碼");      
//執行目標方法 (調用下一個攔截器, 或執行Action)    
final String res = invocation.invoke();    
System.out.println("Action執行後插入 代碼");    
return res;    
}
}

 

4、配置Struts2攔截器

Struts2攔截器須要在struts.xml中聲明,以下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.objectFactory" value="spring" />

 

<package name="default" extends="struts-default"> <interceptors> <interceptor name="MyInterceptor" class="interceptor.MyInterceptor"></interceptor> <interceptor-stack name="myInterceptorStack"> <interceptor-ref name="MyInterceptor"/> <interceptor-ref name="defaultStack"/> </interceptor-stack> </interceptors> <action name="loginAction" class="loginAction"> <result name="fail">/index.jsp </result> <result name="success">/success.jsp</result> <interceptor-ref name="myInterceptorStack"></interceptor-ref> </action> </package> </struts>

 

 

 

攔截器

名字

說明

Alias Interceptor

alias

在不一樣請求之間將請求參數在不一樣名字件轉換,請求內容不變

Chaining Interceptor

chain

讓前一個Action的屬性能夠被後一個Action訪問,如今和chain類型的result()結合使用。

Checkbox Interceptor

checkbox

添加了checkbox自動處理代碼,將沒有選中的checkbox的內容設定爲false,而html默認狀況下不提交沒有選中的checkbox。

Cookies Interceptor

cookies

使用配置的name,value來是指cookies

Conversion Error Interceptor

conversionError

將錯誤從ActionContext中添加到Action的屬性字段中。

Create Session Interceptor

createSession

自動的建立HttpSession,用來爲須要使用到HttpSession的攔截器服務。

Debugging Interceptor

debugging

提供不一樣的調試用的頁面來展示內部的數據情況。

Execute and Wait Interceptor

execAndWait

在後臺執行Action,同時將用戶帶到一箇中間的等待頁面。

Exception Interceptor

exception

將異常定位到一個畫面

File Upload Interceptor

fileUpload

提供文件上傳功能

I18n Interceptor

i18n

記錄用戶選擇的locale

Logger Interceptor

logger

輸出Action的名字

Message Store Interceptor

store

存儲或者訪問實現ValidationAware接口的Action類出現的消息,錯誤,字段錯誤等。

Model Driven Interceptor

model-driven

若是一個類實現了ModelDriven,將getModel獲得的結果放在Value Stack中。

Scoped Model Driven

scoped-model-driven

若是一個Action實現了ScopedModelDriven,則這個攔截器會從相應的Scope中取出model調用Action的setModel方法將其放入Action內部。

Parameters Interceptor

params

將請求中的參數設置到Action中去。

Prepare Interceptor

prepare

若是Acton實現了Preparable,則該攔截器調用Action類的prepare方法。

Scope Interceptor

scope

Action狀態存入session和application的簡單方法。

Servlet Config Interceptor

servletConfig

提供訪問HttpServletRequest和HttpServletResponse的方法,以Map的方式訪問。

Static Parameters Interceptor

staticParams

struts.xml文件中將中的中的內容設置到對應的Action中。

Roles Interceptor

roles

肯定用戶是否具備JAAS指定的Role,不然不予執行。

Timer Interceptor

timer

輸出Action執行的時間

Token Interceptor

token

經過Token來避免雙擊

Token Session Interceptor

tokenSession

Token Interceptor同樣,不過雙擊的時候把請求的數據存儲在Session中

Validation Interceptor

validation

使用action-validation.xml文件中定義的內容校驗提交的數據。

Workflow Interceptor

workflow

調用Action的validate方法,一旦有錯誤返回,從新定位到INPUT畫面

Parameter Filter Interceptor

N/A

從參數列表中刪除沒必要要的參數

Profiling Interceptor

profiling

經過參數激活profile

 

 

 

===============================過濾器===========================================================

 

過濾器,是在java web中,你傳入的request,response提早過濾掉一些信息,或者提早設置一些參數,而後再傳入servlet或者struts的 action進行業務邏輯,好比過濾掉非法url(不是login.do的地址請求,若是用戶沒有登錄都過濾掉),或者在傳入servlet或者 struts的action前統一設置字符集,或者去除掉一些非法字符

攔截器,是在面向切面編程的就是在你的service或者一個方法,前調用一個方法,或者在方法後調用一個方法好比動態代理就是攔截器的簡單實現,在你調用方法前打印出字符串(或者作其它業務邏輯的操做),也能夠在你調用方法後打印出字符串,甚至在你拋出異常的時候作業務邏輯的操做。

 

攔截器與過濾器的區別 :

  1. 攔截器是基於java的反射機制的,而過濾器是基於函數回調。
  2. 攔截器不依賴與servlet容器,過濾器依賴與servlet容器。
  3. 攔截器只能對action請求起做用,而過濾器則能夠對幾乎全部的請求起做用。
  4. 攔截器能夠訪問action上下文、值棧裏的對象,而過濾器不能訪問。
  5. 在action的生命週期中,攔截器能夠屢次被調用,而過濾器只能在容器初始化時被調用一次

執行順序 :過濾前 - 攔截前 - Action處理 - 攔截後 - 過濾後。我的認爲過濾是一個橫向的過程,首先把客戶端提交的內容進行過濾(例如未登陸用戶不能訪問內部頁面的處理);過濾經過後,攔截器將檢查用戶提交數據的驗證,作一些前期的數據處理,接着把處理後的數據發給對應的Action;Action處理完成返回後,攔截器還能夠作其餘過程(還沒想到要作啥),再向上返回到過濾器的後續操做。

 

一個Filter 可負責攔截多個請求或響應:一個請求或響應也可被多個請求攔截。

建立一個Filter 只需兩個步驟: 
(1)建立Filter 處理類:

(2)在web.xml 文件中配置Filter 。 
建立Filter 必須實現javax.servlet.Filter 接口,在該接口中定義了三個方法。 
• void init(FilterConfig config): 用於完成Filter 的初始化。 
• void destroy(): 用於Filter 銷燬前,完成某些資源的回收。 
• void doFilter(ServletRequest request, ServletResponse response,FilterChain chain): 實現過濾功能,該方法就是對每一個請求及響應增長的額外處理。

過濾器Filter也具備生命週期:init()->doFilter()->destroy(),由部署文件中的filter元素驅動。在servlet2.4中,過濾器一樣能夠用於請求分派器,但須在web.xml中聲明,<dispatcher>INCLUDE或FORWARD或REQUEST或ERROR</dispatcher>該元素位於filter-mapping中。

Filter經常使用的場景:

例1、 日誌的記錄,當有請求到達時,在該過濾器中進行日誌的記錄。處理完成後,進入後續的Filter或者處理。

步驟1:編寫Filter類

package test.filter;

 

import javax.servlet.Filter;

import javax.servlet.FilterChain;

import javax.servlet.FilterConfig;

import javax.servlet.ServletContext;

import javax.servlet.ServletRequest;

import javax.servlet.ServletResponse;

import javax.servlet.http.HttpServletRequest;

 

public class LogFilter implements Filter {

private FilterConfig config;

// 實現初始化方法

public void init(FilterConfig config) {

this.config = config;

}

// 實現銷燬方法

public void destroy() {

this.config = null;

}

public void doFilter(ServletRequest request, ServletResponse response,

FilterChain chain) {

// 獲取ServletContext 對象,用於記錄日誌

ServletContext context = this.config.getServletContext();

long before = System.currentTimeMillis();

System.out.println("開始過濾... ");

// 將請求轉換成HttpServletRequest 請求

HttpServletRequest hrequest = (HttpServletRequest) request;

// 記錄日誌

context.log("Filter已經截獲到用戶的請求的地址: " + hrequest.getServletPath());

try {

// Filter 只是鏈式處理,請求依然轉發到目的地址。

chain.doFilter(request, response);

catch (Exception e) {

e.printStackTrace();

}

long after = System.currentTimeMillis();

// 記錄日誌

context.log("過濾結束");

// 再次記錄日誌

context.log(" 請求被定位到" + ((HttpServletRequest) request).getRequestURI()

+ "所花的時間爲: " + (after - before));

}

}

在上面的請求Filter中,僅在日誌中記錄請求的URL,對全部的請求都執行chain.doFilter(request,reponse)方法,當Filter 對請求過濾後,依然將請求發送到目的地址。

步驟2:在web.xml中配置Filter

<!-- 定義Filter -->

<filter>

<!-- Filter 的名字 -->

<filter-name>log</filter-name>

<!-- Filter 的實現類 -->

<filter-class> test.filter.LogFilter</filter-class>

</filter>

<!-- 定義Filter 攔截地址 -->

<filter-mapping>

<!-- Filter 的名字 -->

<filter-name>log</filter-name>

<!-- Filter 負責攔截的URL -->

<url-pattern>/filter/*</url-pattern>

</filter-mapping>

相關文章
相關標籤/搜索