Spring Boot 攔截器的使用
阿新 • • 發佈:2020-08-07
一、使用場景
比如對特定的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 類中,三個方法都已執行