SpringBoot中使用攔截器的配置詳解
1. 應用場景
攔截器是 AOP 的一種實現(xiàn),專門攔截對動態(tài)資源的后臺請求,即攔截對控制層的請 求。使用場景比較多的是判斷用戶是否有權限請求后臺,更拔高一層的使用場景也有,比如攔截器可以 結合 websocket 一起使用,用來攔截 websocket 請求,然后做相應的處理等等。攔截器不會攔截靜態(tài) 資源,Spring Boot 的默認靜態(tài)目錄為 resources/static,該目錄下的靜態(tài)頁面、js、css、圖片等等, 不會被攔截.
2. 定義攔截器
定義攔截器,只需要實現(xiàn) HandlerInterceptor 接口, 該接口中有三個方法:
preHandle(……) 、 postHandle(……) 和 afterCompletion(……) 。
- preHandle(……) 方法:該方法的執(zhí)行時機是,當某個 url 已經(jīng)匹配到對應的 Controller 中的某個方法,且在這個方法執(zhí)行之前。所以 preHandle(……) 方法可以決定是否將請求放行,這是通過返回值來決定的,返回 true 則放行,返回 false 則不會向后執(zhí)行。
- postHandle(……) 方法:該方法的執(zhí)行時機是,當某個 url 已經(jīng)匹配到對應的 Controller 中的某個方法,且在執(zhí)行完了該方法,但是在 DispatcherServlet 視圖渲染之前。所以在這個方法中有個ModelAndView 參數(shù),可以在此做一些修改動作。
- afterCompletion(……) 方法:顧名思義,該方法是在整個請求處理完成后(包括視圖渲染)執(zhí)行,這時做一些資源的清理工作,這個方法只有在 preHandle(……) 被成功執(zhí)行后并且返回 true才會被執(zhí)行。
2.1 自定義攔截類實現(xiàn)HandlerInterceptor接口
public class MyInterceptor implements HandlerInterceptor { private Logger logger = LoggerFactory.getLogger(MyInterceptor.class); @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { HandlerMethod handlerMethod = (HandlerMethod) handler; Method method = handlerMethod.getMethod(); String methodName = method.getName(); logger.info("方法{}被攔截", methodName); return true; } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { logger.info("方法被執(zhí)行,但是視圖還未渲染"); } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { logger.info("方法執(zhí)行完畢,進行資源清理"); } }
2.2 實現(xiàn)WebMvcConfigurer接口進行攔截配置
實現(xiàn)WebMvcConfigurer的這種配置會自動過濾靜態(tài)資源;
@Configuration public class MyInterceptorConfig implements WebMvcConfigurer { @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new MyInterceptor()).addPathPatterns("/**"); } }
省略controller類
測試結果
10:52:16.316 [http-nio-8080-exec-1] INFO c.e.h.interceptors.MyInterceptor - 方法test被攔截
10:52:16.344 [http-nio-8080-exec-1] INFO c.e.h.interceptors.MyInterceptor - 方法被執(zhí)行,但是視圖還未渲染
10:52:16.344 [http-nio-8080-exec-1] INFO c.e.h.interceptors.MyInterceptor - 方法執(zhí)行完畢,進行資源清理
定義哪些不用攔截
取消攔截操作
如果我要攔截所有 /admin 開頭的 url 請求的話,需要在攔截器配置中添加這個前綴,但是 在實際項目中,可能會有這種場景出現(xiàn):某個請求也是 /admin 開頭的,但是不能攔截,比如 /admin/login 等等
解決方案:
1.使用excludePathPatterns("/adminUser/login")
@Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new MyInterceptor()).addPathPatterns("/**").excludePathPatterns("/adminUser/login"); }
2.可以定義一個注解
該注解專門用來取消攔截操作,如果某個 Controller 中的方法我們 不需要攔截掉,即可在該方法上加上我們自定義的注解即可,下面先定義一個注解:
@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface UnInterception { }
測試
controller類
@RestController @RequestMapping("/intercept") public class IntercepController { @UnInterception @RequestMapping("/hello") public String test() { return "success"; }
interceptor攔截類
@Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { HandlerMethod handlerMethod = (HandlerMethod) handler; Method method = handlerMethod.getMethod(); String methodName = method.getName(); if (method.getAnnotation(UnInterception.class)!=null) { logger.info("方法{}不被攔截", methodName); return true; } logger.info("方法{}被攔截", methodName); return false; }
訪問 localhost:8080/intercept/hello
結果
11:34:24.648 [http-nio-8080-exec-1] INFO c.e.h.interceptors.MyInterceptor - 方法test不被攔截
11:34:24.676 [http-nio-8080-exec-1] INFO c.e.h.interceptors.MyInterceptor - 方法被執(zhí)行,但是視圖還未渲染
11:34:24.679 [http-nio-8080-exec-1] INFO c.e.h.interceptors.MyInterceptor - 方法執(zhí)行完畢,進行資源清理
到此這篇關于SpringBoot中使用攔截器的配置詳解的文章就介紹到這了,更多相關SpringBoot攔截器內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!