java攔截器(Interceptor)學習筆記

1,攔截器的概念
    java裏的攔截器是動態攔截Action調用的對象,它提供了一種機制可使開發者在一個Action執行的先後執行一段代碼,也能夠在一個Action
執行前阻止其執行,同時也提供了一種能夠提取Action中可重用部分代碼的方式。在AOP中,攔截器用於在某個方法或者字段被訪問以前,進行攔截
而後再以前或者以後加入某些操做。目前,咱們須要掌握的主要是Spring的攔截器,Struts2的攔截器不用深究,知道便可。java

過濾器、監聽器、攔截器差別圖

2,攔截器的原理
    大部分時候,攔截器方法都是經過代理的方式來調用的。Struts2的攔截器實現相對簡單。當請求到達Struts2的ServletDispatcher時,Struts2
會查找配置文件,並根據配置實例化相對的攔截器對象,而後串成一個列表(List),最後一個一個的調用列表中的攔截器。Struts2的攔截器是可
插拔的,攔截器是AOP的一個實現。Struts2攔截器棧就是將攔截器按必定的順序鏈接成一條鏈。在訪問被攔截的方法或者字段時,Struts2攔截器鏈
中的攔截器就會按照以前定義的順序進行調用。

3,自定義攔截器的步驟
    第一步:自定義一個實現了Interceptor接口的類,或者繼承抽象類AbstractInterceptor。
    第二步:在配置文件中註冊定義的攔截器。
    第三步:在須要使用Action中引用上述定義的攔截器,爲了方便也能夠將攔截器定義爲默認的攔截器,這樣在不加特殊說明的狀況下,全部的
Action都被這個攔截器攔截。

4,過濾器與攔截器的區別
    過濾器能夠簡單的理解爲「取你所想取」,過濾器關注的是web請求;攔截器能夠簡單的理解爲「拒你所想拒」,攔截器關注的是方法調用,好比攔截
敏感詞彙。
4.1,攔截器是基於java反射機制來實現的,而過濾器是基於函數回調來實現的。(有人說,攔截器是基於動態代理來實現的)
4.2,攔截器不依賴servlet容器,過濾器依賴於servlet容器。
4.3,攔截器只對Action起做用,過濾器能夠對全部請求起做用。
4.4,攔截器能夠訪問Action上下文和值棧中的對象,過濾器不能。
4.5,在Action的生命週期中,攔截器能夠屢次調用,而過濾器只能在容器初始化時調用一次。

5,Spring攔截器
5.1,抽象類HandlerInterceptorAdapter
    咱們若是在項目中使用了Spring框架,那麼,咱們能夠直接繼承HandlerInterceptorAdapter.java這個抽象類,來實現咱們本身的攔截器。web

Spring框架,對java的攔截器概念進行了包裝,這一點和Struts2很相似。HandlerInterceptorAdapter繼承了抽象接口HandlerInterceptor。spring

看看源碼:api

package org.springframework.web.servlet.handler;  
import javax.servlet.http.HttpServletRequest;  
import javax.servlet.http.HttpServletResponse;  
import org.springframework.web.servlet.HandlerInterceptor;  
import org.springframework.web.servlet.ModelAndView;  
public abstract class HandlerInterceptorAdapter implements HandlerInterceptor{  
    // 在業務處理器處理請求以前被調用  
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception{  
        return true;  
    }  
    // 在業務處理器處理請求完成以後,生成視圖以前執行  
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)  
      throws Exception{  
    }  
    // 在DispatcherServlet徹底處理完請求以後被調用,可用於清理資源  
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)  
      throws Exception{  
    }  
} 

下面,咱們利用Spring框架提供的HandlerInterceptorAdapter抽過類,來實現一個自定義的攔截器。咱們這個攔截器叫作
UserLoginInterceptor,進行登陸攔截控制。工做流程是這樣的:若是當前用戶沒有登陸,則跳轉到登陸頁面;登陸成功後,繼續訪問。session

package com.singlee.capital.approve.service;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

public class UserloginInterceptor extends HandlerInterceptorAdapter {

    // 在業務處理器處理請求以前被調用  
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception{ 
        String requestUri = request.getRequestURI();  
        String contextPath = request.getContextPath();  
        String url = requestUri.substring(contextPath.length());  
        System.out.println("requestUri" + requestUri);  
        System.out.println("contextPath" + contextPath);  
        System.out.println("url" + url);  
        String username = (String) request.getSession().getAttribute("username");
        //判斷session中是否有登陸用戶信息
        if(null == username){  
            // 跳轉到登陸頁面  
            request.getRequestDispatcher("/WEB-INF/login.jsp").forward(request, response); 
            return false;  
        }  
        else{  
            return true;  
        }
    }  
    // 在業務處理器處理請求完成以後,生成視圖以前執行  
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)  
      throws Exception{  
    }  
    // 在DispatcherServlet徹底處理完請求以後被調用,可用於清理資源  
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)  
      throws Exception{  
    } 
    
}

總結:
    1.過濾器(Filter):所謂過濾器顧名思義是用來過濾的,Java的過濾器可以爲咱們提供系統級別的過濾,也就是說,能過濾全部的web請求,
這一點,是攔截器沒法作到的。在Java Web中,你傳入的request,response提早過濾掉一些信息,或者提早設置一些參數,而後再傳入servlet或
者struts的action進行業務邏輯,好比過濾掉非法url(不是login.do的地址請求,若是用戶沒有登錄都過濾掉),或者在傳入servlet或者struts
的action前統一設置字符集,或者去除掉一些非法字符(聊天室常常用到的,一些罵人的話)。filter 流程是線性的,url傳來以後,檢查以後,
可保持原來的流程繼續向下執行,被下一個filter, servlet接收。
    2.監聽器(Listener):Java的監聽器,也是系統級別的監聽。監聽器隨web應用的啓動而啓動。Java的監聽器在c/s模式裏面常常用到,它
會對特定的事件產生產生一個處理。監聽在不少模式下用到,好比說觀察者模式,就是一個使用監聽器來實現的,在好比統計網站的在線人數。
又好比struts2能夠用監聽來啓動。Servlet監聽器用於監聽一些重要事件的發生,監聽器對象能夠在事情發生前、發生後能夠作一些必要的處理。
    3.攔截器(Interceptor):java裏的攔截器提供的是非系統級別的攔截,也就是說,就覆蓋面來講,攔截器不如過濾器強大,可是更有針對性。
Java中的攔截器是基於Java反射機制實現的,更準確的劃分,應該是基於JDK實現的動態代理。它依賴於具體的接口,在運行期間動態生成字節碼。
攔截器是動態攔截Action調用的對象,它提供了一種機制可使開發者在一個Action執行的先後執行一段代碼,也能夠在一個Action執行前阻止其
執行,同時也提供了一種能夠提取Action中可重用部分代碼的方式。在AOP中,攔截器用於在某個方法或者字段被訪問以前,進行攔截而後再以前或
者以後加入某些操做。app

下一節筆記是攔截器與過濾器的詳細差別框架

相關文章
相關標籤/搜索