過濾器、監聽器、攔截器作用及配置

過濾器

Servlet中的過濾器Filter是實現了javax.servlet.Filter接口的服務器端程序,主要的用途是過濾字符編碼、做一些業務邏輯判斷等。其工作原理是,只要你在web.xml文件配置好要攔截的客戶端請求,它都會幫你攔截到請求,此時你就可以對請求或響應(Request、Response)統一設置編碼,簡化操作;同時還可以進行邏輯判斷,如用戶是否已經登錄、有沒有權限訪問該頁面等等工作,它是隨你的web應用啓動而啓動的,只初始化一次,以後就可以攔截相關的請求,只有當你的web應用停止或重新部署的時候才能銷燬。

在javax.servlet.Filter接口中定義了3個方法:

 void init(FilterConfig filterConfig) 用於完成過濾器的初始化

 void destroy() 用於過濾器銷燬前,完成某些資源的回收

 void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) 實現過濾功能,該方法對每個請求增加額外的處理

package com.cn.util;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class FilterUtil implements Filter{

	@SuppressWarnings("unused")
	private FilterConfig filterConfig;
	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
		this.filterConfig = filterConfig;
		System.out.println("過濾器Filter初始化");
	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws IOException, ServletException {
		if (!(request instanceof HttpServletRequest) || !(response instanceof HttpServletResponse)) {
			throw new ServletException("FilterUtil just supports HTTP requests");
		}
		HttpServletRequest httpRequest = (HttpServletRequest) request;
		HttpServletResponse httpResponse = (HttpServletResponse) response;
		httpRequest.setCharacterEncoding(this.filterConfig.getInitParameter("encoding"));
		httpResponse.setCharacterEncoding(this.filterConfig.getInitParameter("encoding"));
		chain.doFilter(httpRequest, httpResponse);
	}

	@Override
	public void destroy() {
		System.out.println("過濾器Filter銷燬");
	}

}
web.xml配置:

<filter>
    <filter-name>encodingFilter</filter-name>
    <!-- <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> -->
    <filter-class>com.cn.util.FilterUtil</filter-class>
    <async-supported>true</async-supported>
    <init-param>
      <param-name>encoding</param-name>
      <param-value>UTF-8</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>encodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

監聽器

Servlet的監聽器Listener,它是實現了javax.servlet.ServletContextListener接口的服務器端程序,它也是隨web應用的啓動而啓動,只初始化一次,隨web應用的停止而銷燬。主要作用是:做一些初始化的內容添加工作、設置一些基本的內容、比如一些參數或者是一些固定的對象等等。

在javax.servlet.ServletContextListener接口中定義了2種方法:

  void contextInitialized(ServletContextEvent sce) 監聽器的初始化

  void contextDestroyed(ServletContextEvent sce) 監聽器銷燬

package com.cn.util;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;

public class ServletContextListenerUtil implements ServletContextListener{

	//監聽器的初始化
	@Override
	public void contextInitialized(ServletContextEvent sce) {
		System.out.println("監聽器ServletContextListenerUtil初始化");
	}

	//監聽器銷燬
	@Override
	public void contextDestroyed(ServletContextEvent sce) {
		System.out.println("監聽器ServletContextListenerUtil銷燬");
	}
}
項目啓動時,先啓動監聽器,再啓動過濾器。

攔截器

攔截器是在面向切面編程中應用的,就是在你的service或者一個方法前調用一個方法,或者在方法後調用一個方法比如動態代理就是攔截器的簡單實現,在你調用方法前打印出字符串(或者做其它業務邏輯的操作),也可以在你調用方法後打印出字符串,甚至在你拋出異常的時候做業務邏輯的操作。攔截器不是在web.xml配置的,比如struts在struts.xml配置,在springMVC在spring與springMVC整合的配置文件中配置。

在springmvc中,定義攔截器要實現HandlerInterceptor接口,並實現該接口中提供的三個方法

package com.cn.util;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

public class InterceptorUtil implements HandlerInterceptor{

	//進入Handler方法之前執行
    //可以用於身份認證、身份授權。如果認證沒有通過表示用戶沒有登陸,需要此方法攔截不再往下執行,否則就放行
	@Override
	public boolean preHandle(HttpServletRequest request,
			HttpServletResponse response, Object handler) throws Exception {
		// TODO Auto-generated method stub
		System.out.println("InterceptorUtil...........preHandle");
		String user= (String) request.getSession().getAttribute("user");
		if(user != null){
			return true;
		}
		request.getRequestDispatcher("/WEB-INF/jsp/index.jsp").forward(request, response);
		//true表示放行,false表示不放行
		return false;
	}

	@Override
	public void postHandle(HttpServletRequest request,
			HttpServletResponse response, Object handler,
			ModelAndView modelAndView) throws Exception {
		// TODO Auto-generated method stub
		System.out.println("InterceptorUtil...........postHandle");
	}

	@Override
	public void afterCompletion(HttpServletRequest request,
			HttpServletResponse response, Object handler, Exception ex)
			throws Exception {
		// TODO Auto-generated method stub
		System.out.println("InterceptorUtil...........afterCompletion");
	}

}
  preHandle方法:進入Handler方法之前執行。可以用於身份認證、身份授權。比如如果認證沒有通過表示用戶沒有登陸,需要此方法攔截不再往下執行(return false),否則就放行(return true)。
  postHandle方法:進入Handler方法之後,返回ModelAndView之前執行。可以看到該方法中有個modelAndView的形參。應用場景:從modelAndView出發:將公用的模型數據(比如菜單導航之類的)在這裏傳到視圖,也可以在這裏同一指定視圖。
  afterCompletion方法:執行Handler完成之後執行。應用場景:統一異常處理,統一日誌處理等。
在springmvc中,攔截器是針對具體的HandlerMapping進行配置的,也就是說如果在某個HandlerMapping中配置攔截,經過該 HandlerMapping映射成功的handler最終使用該攔截器。

spring-mvc.xml配置文件中:

<!-- 攔截器配置 -->
    <mvc:interceptors>
        <!--多個攔截器,順序執行 -->
	    <!-- 登陸認證攔截器 -->
	    <mvc:interceptor>
	        <!-- /** 表示攔截所有url包括子url路徑,/*只攔截根下的url -->
	        <mvc:mapping path="/**"/>
	        <bean class="com.cn.util.InterceptorUtil"></bean>
	    </mvc:interceptor>
	    <!-- 其他攔截器 -->
    </mvc:interceptors>

在網上查詢的過濾器和攔截器的區別,基本都是以下一模一樣的5行話。
1、攔截器是基於java的反射機制的,而過濾器是基於函數回調
2、過濾器依賴與servlet容器,而攔截器不依賴與servlet容器
3、攔截器只能對action請求起作用,而過濾器則可以對幾乎所有的請求起作用
4、攔截器可以訪問action上下文、值棧裏的對象,而過濾器不能
5、在action的生命週期中,攔截器可以多次被調用,而過濾器只能在容器初始化時被調用一次

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

過濾器(Filter):當你有一堆東西的時候,你只希望選擇符合你要求的某一些東西。定義這些要求的工具,就是過濾器。
攔截器(Interceptor):在一個流程正在進行的時候,你希望干預它的進展,甚至終止它進行,這是攔截器做的事情。
監聽器(Listener):當一個事件發生的時候,你希望獲得這個事件發生的詳細信息,而並不想幹預這個事件本身的進程,這就要用到監聽器。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章