天天看點

過濾器和攔截器以及在springboot中的使用一攔截器二 攔截器三 過濾器和攔截器的比較

一攔截器

一、攔截器(Interceptor)

定義:在面向切面程式設計中應用的,在方法執行之前或者之後,進行攔截,添加某些操作;基于java的反射機制實作的。攔截是aop的一種實作政策。
        在webWork中,攔截器是動态攔截Action調用的對象,提供了一種機制使開發者可以定義在一個Action執行的前後執行的代碼,也可以在一個Action執行前阻止其
  執行。同時,也提供了一種可以提取Action中可重用的部分的方式。
        攔截器從Action中抽出了很多功能,大量減少了Actin中的代碼,抽取出的公共方法可以更好的重用。
        當我們送出對Action的請求時,ServletDispatcher會根據請求,排程并執行相應的Action;在此Action執行之前,調用被Interceptor截取,Interceptor
     在Action執行前後執行。           

二、在ssm中的實作

SpringMVC 中的Interceptor 攔截請求是通過HandlerInterceptor 來實作的。主要有兩種方式:
 第一種: 定義的Interceptor類  實作Spring 的HandlerInterceptor 接口,或者是這個類繼承實作了HandlerInterceptor 接口的類,比如Spring 已經提供的實作了
          HandlerInterceptor 接口的抽象類HandlerInterceptorAdapter ;
 第二種: 定義的Interceptor類, 實作Spring的WebRequestInterceptor接口,或者是繼承實作了WebRequestInterceptor的類。           

三、在springboot中的實作

第一種: 建立類 LogCostInterceptor  實作  HandlerInterceptor 接口;
          建立配置類WebConfiguration 繼承 WebMvcConfigurationSupport (或者 WebMvcConfigurerAdapter);添加 @Configuration注解;           

@Configuration

public class WebConfiguration extends WebMvcConfigurationSupport {

private Logger logger = LoggerFactory.getLogger(WebConfiguration.class);
    
    @Override
    public void addInterceptors(InterceptorRegistry registry){
            // 多個攔截器組成一個攔截器鍊
            // addPathPatterns 用于添加攔截規則
            // excludePathPatterns 使用者排除攔截
            registry.addInterceptor(new LogCostInterceptor()).addPathPatterns().excludePathPatterns("/swagger-ui.html");
    }           

}

四、 攔截器中三個方法的詳細解釋

SpringMvc的過濾器是鍊式的,在一個應用中或者一個請求中可以有多個Interceptor,執行順序按照聲明中的順序執行,先執行每個過濾器中的preHandle方法。
 1) preHandle  在請求controller之前執行,可以在方法中進行一些初始化操作或者是對目前請求的一個預處理,也可以設定一些判斷決定請求是否要繼續下去。
                傳回結果如果是true,則執行後續的Interceptor中的preHandle和controller,
                如果是false,表示請求結束。
 2) postHandle  在preHandle執行為true後,執行該方法。在controller執行之後,在DispatcherServlet進行視圖傳回渲染之前被調用;在這個方法中可以對
                  ModelAndView對象進行處理。postHandle的執行順序在鍊式中和preHandle的執行順序是相反的,先執行preHandle的過濾器的postHandle後執行。
 3) afterCompletion  preHandle執行為true後執行。 該方法在整個請求結束之後,在DispatcherServlet渲染了對應的視圖之後執行。
                      作用: 進行資源清理工作。           

二 攔截器

一 、定義:

filter 實作了 javax.servlet.filter接口的伺服器端程式;           

二、 用途:

設定字元集、控制權限、控制轉向、業務邏輯判斷等           

三、 工作原理:

在web.xml檔案配置需要攔截的用戶端請求,它會幫你攔截到請求,此時你可以對請求或相應統一設定編碼、簡化操作;同時可以進行邏輯判斷,如使用者是否已經登入、有沒有權限通路該頁面等等。
   随着web應用啟動而啟動,隻需要初始化一次,以後就可以攔截相關請求,隻有當web應用停止或重新部署的時候才銷毀。
   Filter 主要使用者對使用者請求進行預處理,也可以對HttpServletResponse進行後處理,是個典型的處理鍊。           

四、 流程:

filter對使用者請求進行預處理,将請求交給Servlet進行處理并生成響應,最後Filter再對伺服器響應進行後處理。           

五、 用處:

在HttpServletRequest到達Servlet之前,攔截客戶的HttpServletRequest。
    根據需要檢查HttpServletRequest,也可以修改HttpServletRequest頭和資料。
    在HttpServletResponse到達用戶端之前,攔截HttpServletResponse。
    根據需要檢查HttpServletResponse,也可以修改HttpServletResponse頭和資料。           

六、 種類:

使用者授權的Filter:Filter負責檢查使用者請求,根據請求過濾使用者非法請求。
    日志Filter:詳細記錄某些特殊的使用者請求。
    負責解碼的Filter:包括對非标準編碼的請求解碼。
    能改變XML内容的XSLT Filter等。
    Filter可以負責攔截多個請求或響應;一個請求或響應也可以被多個Filter攔截。           

七、 使用:

1 建立Myfilter類繼承Filter
          重寫 init 和 doFilter
        ② 在init方法中初始化自定義參數,參數名稱可以設定為此時的 url,對其執行過濾,也就是放過; 
        ③ 在doFilter中可以進行認證鑒權處理,之後執行相應的邏輯;
                       也可以進行跨域的設定;
           在doFilter中 chain.doFilter(req, res)是對請求和響應處理的分界線,執行該方法之前,即對使用者請求進行預處理;執行該方法之後,即對伺服器響應進行後處理
         1)第一種方案
           a: 在Myfilter類 添加注解  @WebFilter ,可以添加 @Order(1)多個Myfilter的時候 按照順序執行
              @WebFilter的一些參數值
                  (    filterName = "Myfilter", urlPatterns = "/snow/api/*",
                        initParams = {  @WebInitParam(name = "url", value = "/snow/api/login")}
                    )
              filterName 攔截的位址   initParams 放過的位址,不需要檢測
           b: 在springboot的啟動類上添加 @ServletComponentScan
          2)第二種方案
            a:  在Myfilter類 添加注解  @Component,交給spring容器處理
            b:  建立一個config類,添加注解 
                            

public class config {

@Bean
public FilterRegistrationBean webAuthFilterRegistration() {
    FilterRegistrationBean registration = new FilterRegistrationBean();
    registration.setFilter(myfilte());
    registration.setName("Myfilter");
    registration.addUrlPatterns("/snow/api/*");
    registration.addInitParameter("url", "/snow/api/login");
    registration.setOrder(0); //設定順序
    return registration;
}

@Bean
public Filter myfilter() {
    return new Myfilter();
}           

三 過濾器和攔截器的比較

一、差別和不同
         相同:都是AOP程式設計思想的實作。
         不同點: 
        使用範圍不同              過濾器隻能使用再web應用程式,也就是在servlet容器中; 攔截器即可以使用在web應用中,也可以使用在 
                                         javaSE的各種環境。
        使用的資源不同           攔截器是spring的元件,被spring管理,可以使用spring的任何資源包括:Servive對象、事務管理、資料源等, 
                                         通過IOC注入到容器即可。過濾器不可以。
        使用的深度(範圍)不同     過濾器隻在Servlet前後起作用;攔截器可以深入到方法前後、異常抛出前後等,具有更大的彈性。 
        執行順序不同             Filter是被Server(比如tomcat、netty)調用; Interceptor被spring調用; 是以Filter在Interceptor前面執行。
         使用選擇                   在spring架構的實作中,優先選擇使用攔截器。
   二、 過濾器和攔截器的執行流程圖