1. 程式人生 > 實用技巧 >Spring Boot 攔截器的使用

Spring Boot 攔截器的使用

一、使用場景

比如對特定的URL檢查使用者是否登入,列印處理使用者請求耗時的時間等,可以用攔截器來實現。


二、攔截器使用

定義攔截器,需要實現HandlerInterceptor 介面,介面中有3個方法

  • preHandle:在DispatcherServlet處理請求執行之前被呼叫
  • postHandle:在DispatcherServlet處理請求執行完成後,生成檢視之前被呼叫(還未渲染頁面)
  • afterCompletion:在DispatcherServlet處理請求執行完成後,且已生成檢視被呼叫,可以用於清除資源(已渲染了頁面)

)2.1 建立自定義攔截器MyInterceptor類

@Slf4j
public class MyInterceptor implements HandlerInterceptor {

    /**
     * 定義攔截器:需要實現 HandlerInterceptor 介面
     *
     * HandlerInterceptor介面中有3個方法
     * 1.preHandle:在業務處理器處理請求之前被呼叫
     * 2.postHandle:在業務處理器處理請求執行完成後,生成檢視之前執行(還未渲染頁面))
     * 3.afterCompletion:在DispatcherServlet完全處理完請求後被呼叫,可用於清理資源等。返回處理(已經渲染了頁面)
     
*/ @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { HandlerMethod handlerMethod = (HandlerMethod) handler; Method method = handlerMethod.getMethod(); String methodName = method.getName(); log.info(
"===攔截到了方法:{},在該方法執行之前執行===", methodName); // 判斷使用者有沒有登陸,一般登陸後的使用者都有一個對應的token String token = request.getParameter("token"); if (StringUtils.isEmpty(token)) { log.info("使用者沒有登陸,沒有執行許可權......請登陸"); return false; } // 通過方法,可以獲取該方法上的自定義註解,然後通過註解來判斷該方法是否要被攔截 // @UnInterceptor 自定義註解,不被攔截 UnInterceptor unInterceptor = method.getAnnotation(UnInterceptor.class); if (null == unInterceptor) { return false; } return true; } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { log.info("執行完方法之後進行(Controller方法呼叫之後),但是此時還沒有進行檢視渲染"); } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { log.info("整個請求都處理完畢,DispatcherServlet也渲染了對應的檢視,此時可以做一些清理的工作等等"); } }

)2.2 建立攔截器配置類,實現WebMvcConfigurer 介面,對所有請求由MyInterceptor 類進行攔截

@Configuration
public class MyInterceptorConfig implements WebMvcConfigurer {

    /**
     * 解決靜態資源被攔截問題
     *
     * @param registry
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 實現WebMvcConfigurer不會導致靜態資源被攔截
        registry.addInterceptor(new MyInterceptor()).addPathPatterns("/**");
    }
}

)2.3 建立controller類,接收請求

@Controller
@RequestMapping("/interceptor")
public class InterceptorController {

    @GetMapping("/test")
    public String test() {
        return "hello";
    }

    @UnInterceptor
    @GetMapping("/test1")
    @ResponseBody
    public String test1() {
        return "不被攔截";
    }
}

)2.4 建立 hello.html 頁面,用於頁面返回渲染


三、測試

)3.1 對於 token 校驗測試。在MyInterceptor 類中的preHandle 方法中註釋@UnInterceptor 校驗的程式碼,

訪問 localhost:8080/interceptor/test 時,會被攔截,由於沒有帶token值,執行preHandle 方法時返回false,不會繼續往下執行

通過 postman 表單請求設定 token 值,再次請求

測試結果如下,可以看到MyInterceptor 類中,三個方法都已執行,且返回了 hello.html 中的頁面

)3.2 對於自定義註解校驗測試。在MyInterceptor 類中的preHandle 方法中註釋token校驗的程式碼,放開@UnInterceptor 的校驗程式碼,

訪問 localhost:8080/interceptor/test1可以看到MyInterceptor 類中,三個方法都已執行