1. 程式人生 > >spring boot攔截器HandlerInterceptor詳解

spring boot攔截器HandlerInterceptor詳解

作用之一就是 自定義註解的時候,在攔截器中處理這部分的註解的 ,定義這部分的註解有什麼作用?

上一篇對過濾器的定義做了說明,也比較簡單。過濾器屬於Servlet範疇的API,與Spring 沒什麼關係。 

       Web開發中,我們除了使用 Filter 來過濾請web求外,還可以使用Spring提供的HandlerInterceptor(攔截器)。

HandlerInterceptor 的功能跟過濾器類似,但是提供更精細的的控制能力:在request被響應之前、request被響應之後、檢視渲染之前以及request全部結束之後。我們不能通過攔截器修改request內容,但是可以通過丟擲異常(或者返回false)來暫停request的執行。   

配置攔截器也很簡單,Spring 為什麼提供了基礎類WebMvcConfigurerAdapter ,我們只需要重寫 addInterceptors 方法添加註冊攔截器。

實現自定義攔截器只需要3步: 

1、建立我們自己的攔截器類並實現 HandlerInterceptor 介面。 

2、建立一個Java類繼承WebMvcConfigurerAdapter,並重寫 addInterceptors 方法。 

2、例項化我們自定義的攔截器,然後將對像手動新增到攔截器鏈中(在addInterceptors方法中新增)。 

PS:本文重點在如何在Spring-Boot中使用攔截器,關於攔截器的原理請大家查閱資料瞭解。

程式碼示例:

com.kfit.interceptor.MyInterceptor1.java

package com.kfit.interceptor;
  
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
  
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
  
/**
 * 自定義攔截器1
 *
 * @author   Angel
 */
publicclass MyInterceptor1 implements HandlerInterceptor {
  
    @Override
    publicboolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        System.out.println(">>>MyInterceptor1>>>>>>>在請求處理之前進行呼叫(Controller方法呼叫之前)");
  
        returntrue;// 只有返回true才會繼續向下執行,返回false取消當前請求
    }
  
    @Override
    publicvoid postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
            ModelAndView modelAndView) throws Exception {
        System.out.println(">>>MyInterceptor1>>>>>>>請求處理之後進行呼叫,但是在檢視被渲染之前(Controller方法呼叫之後)");
    }
  
    @Override
    publicvoid afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
            throws Exception {
        System.out.println(">>>MyInterceptor1>>>>>>>在整個請求結束之後被呼叫,也就是在DispatcherServlet 渲染了對應的檢視之後執行(主要是用於進行資源清理工作)");
    }
  
}

com.kfit.interceptor.MyInterceptor2.java

package com.kfit.interceptor;
  
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
  
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
  
/**
 * 自定義攔截器2
 *
 * 
 */
public class MyInterceptor2 implements HandlerInterceptor {
  
    @Override
    publicboolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
            throws Exception {
        System.out.println(">>>MyInterceptor2>>>>>>>在請求處理之前進行呼叫(Controller方法呼叫之前)");
  
        returntrue;// 只有返回true才會繼續向下執行,返回false取消當前請求
    }
  
    @Override
    publicvoid postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
            ModelAndView modelAndView) throws Exception {
        System.out.println(">>>MyInterceptor2>>>>>>>請求處理之後進行呼叫,但是在檢視被渲染之前(Controller方法呼叫之後)");
    }
  
    @Override
    publicvoid afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
            throws Exception {
        System.out.println(">>>MyInterceptor2>>>>>>>在整個請求結束之後被呼叫,也就是在DispatcherServlet 渲染了對應的檢視之後執行(主要是用於進行資源清理工作)");
    }
  
}

Com.kfit.config.MyWebAppConfigurer.java

package com.kfit.config;
  
import com.kfit.interceptor.MyInterceptor1;
import com.kfit.interceptor.MyInterceptor2;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
  
@Configuration
public class MyWebAppConfigurer
        extends WebMvcConfigurerAdapter {
  
    @Override
    publicvoid addInterceptors(InterceptorRegistry registry) {
        // 多個攔截器組成一個攔截器鏈
        // addPathPatterns 用於新增攔截規則
        // excludePathPatterns 使用者排除攔截
        registry.addInterceptor(new MyInterceptor1()).addPathPatterns("/**");
        registry.addInterceptor(new MyInterceptor2()).addPathPatterns("/**");
        super.addInterceptors(registry);
    }
  
}

然後在瀏覽器輸入地址: http://localhost:8080/index 後,控制檯的輸出為:

>>>MyInterceptor1>>>>>>>在請求處理之前進行呼叫(Controller方法呼叫之前)
>>>MyInterceptor2>>>>>>>在請求處理之前進行呼叫(Controller方法呼叫之前)
>>>MyInterceptor2>>>>>>>請求處理之後進行呼叫,但是在檢視被渲染之前(Controller方法呼叫之後)
>>>MyInterceptor1>>>>>>>請求處理之後進行呼叫,但是在檢視被渲染之前(Controller方法呼叫之後)
>>>MyInterceptor2>>>>>>>在整個請求結束之後被呼叫,也就是在DispatcherServlet 渲染了對應的檢視之後執行(主要是用於進行資源清理工作)
>>>MyInterceptor1>>>>>>>在整個請求結束之後被呼叫,也就是在DispatcherServlet 渲染了對應的檢視之後執行(主要是用於進行資源清理工作)

根據輸出可以瞭解攔截器鏈的執行順序(具體原理介紹,大家找度娘一問便知)

最後強調一點:只有經過DispatcherServlet 的請求,才會走攔截器鏈,我們自定義的Servlet 請求是不會被攔截的,比如我們自定義的Servlet地址http://localhost:8080/myServlet1 是不會被攔截器攔截的。並且不管是屬於哪個Servlet 只要複合過濾器的過濾規則,過濾器都會攔截。

最後說明下,我們上面用到的 WebMvcConfigurerAdapter 並非只是註冊新增攔截器使用,其顧名思義是做Web配置用的,它還可以有很多其他作用,通過下面截圖便可以大概瞭解,具體每個方法都是幹什麼用的,留給大家自己研究(其實都大同小異也很簡單)。
---------------------  
轉載於:https://blog.csdn.net/u012100371/article/details/77082956