目錄
1. 攔截器介紹
攔截器是在servlet執行之前執行的程序(這里就是controller代碼執行之前),它主要是用於攔截用戶請求並作相應的處理,比如說可以判斷用戶是否登錄,做相關的日志記錄,也可以做權限管理。
SpringBoot中的攔截器實現和spring mvc 中是一樣的,它的大致流程是,先自己定義一個攔截器類,並將這個類實現一個HandlerInterceptor類,或者是繼承HandlerInterceptorAdapter,都可以實現攔截器的定義。然后將自己定義的攔截器注入到適配器中,也有兩種方式,一種是實現WebMvcConfigurer接口,一種是繼承WebMvcConfigurerAdapter。下面我們來看看如何完成。
2.自定義攔截器
直接上代碼,再進行一些代碼講解。
public class MyInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { System.out.println("進入攔截器了"); //中間寫邏輯代碼,比如判斷是否登錄成功,失敗則返回false return true; } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) { // System.out.println("controller 執行完了"); } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) { System.out.println("我獲取到了一個返回的結果:"+response); System.out.println("請求結束了"); } }
代碼說明:
- 自定義的攔截器可以實現HandlerInterceptor接口,也可以繼承HandlerInterceptorAdapter類。
- 重寫三個方法,當然也可以只實現一個最重要的preHandle方法。
- preHandle方法:此方法會在進入controller之前執行,返回Boolean值決定是否執行后續操作。
- postHandle方法:此方法將在controller執行之后執行,但是視圖還沒有解析,可向ModelAndView中添加數據(前后端不分離的)。
- afterCompletion方法:該方法會在整個請求結束(請求結束,但是並未返回結果給客戶端)之后執行, 可獲取響應數據及異常信息。
3.攔截器注入適配器
@Configuration public class InterceptorConfig implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new MyInterceptor()) .addPathPatterns("/**")//攔截所有的路徑 .excludePathPatterns("/LoginController/login"); } }
代碼說明:
- 通過實現WebMvcConfigurer接口可以自定義一個適配器,也可以通過繼承WebMvcConfigurerAdapter來定義適配器,建議使用第一種,第二種已經是過時的方法了。
- 重寫addInterceptors方法,addInterceptor方法是將攔截器注入到適配器中。
- addPathPatterns方法是設置一個需要攔截的路徑,可以是多個字符串或者是直接傳入一個數組。
- excludePathPatterns是配置不需要攔截的路徑。
- 需要加上configuration注解說明這是一個配置類,在項目啟動的時候自動執行。
4.controller測試
先創建一個登陸的測試,這個接口是不會攔截的。
@RestController @RequestMapping("LoginController") public class Login { @RequestMapping("/login") public String login(){ System.out.println("controller開始執行"); return "login success"; } }
創建一個攔截的controller
@RestController @RequestMapping("/hello") public class HelloController { @RequestMapping("/hello") public String hello(){ System.out.println("經過攔截的controller代碼執行完畢"); return "hello"; } }
5. 測試
-
測試未攔截的接口,瀏覽器輸入:localhost:8097/LoginController/login,查看控制台輸出情況。
控制台只輸出了未攔截接口內的代碼,說明這個接口是未攔截的。瀏覽器的顯示就不管了。其實一般是攔截登錄接口,這里就將它放開了,以供測試。
-
測試攔截的接口,瀏覽器輸入:localhost:8097/hello/hello,查看控制台輸出情況。
可以看到,首先是進入了攔截器,通過攔截器之后,進入了controller中的方法,執行完controller的代碼之后就進入了自定義攔截器中的postHandle方法,最后進入afterCompletion方法,並獲取到了一個response對象。
6. 擴展內容:攔截器鏈
我們可以定義多個攔截器組成一個攔截器鏈。我們可以在適配器中注入多個攔截器。多加一行代碼就行了。
按照攔截器注入的順序,攔截器的執行順序應該是一下順序:攔截器1,攔截器2,攔截器2處理,攔截器1處理,攔截器2結束,攔截器1結束。對應三個過程的方法就是preHandle,postHandle,afterCompletion。
7. 總結
本文從攔截器的自定義到自定義適配器,然后將攔截器注入適配器,再到編寫測試代碼。准備工作完成之后就進行一個測試攔截器是否成功,最后擴展出攔截器鏈的一些內容。如果你覺得本文對你有用,三連走起!