【springboot中使用拦截器】
- 1.攔截器原理
- 1.定義攔截器:
- 2.配置攔截器
- 3.解決靜態資源被攔截
- 2.攔截器使用實例
- 2.1判斷用戶有沒有登錄
- 2.2取消攔截操作
1.攔截器原理
攔截器的原理很簡單,是AOP 的一種實現,專門攔截對動態資源的后臺請求,即攔截對控制層的請求。使用場景比較多的是判斷用戶是否有權限請求后臺,更拔高一層的使
用場景也有,比如攔截器可以結合websocket 一起使用,用來攔截websocket 請求,然后做相應的處理等等。攔截器不會攔截靜態資源,Spring Boot 的默認靜態目錄為resources/static,該目錄下的靜態頁面、js、css、圖片等等,不會被攔截(也要看如何實現,有些情況也會攔截,我在下文會指出)。
1.定義攔截器:
//定義攔截器 public class MyInterceptor implements HandlerInterceptor {private Logger logger = LoggerFactory.getLogger(MyInterceptor.class);@Overridepublic 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;//返回true才會繼續執行,返回false則取消當前請求}@Overridepublic void postHandle(HttpServletRequest request,HttpServletResponse response, Object handler, ModelAndViewmodelAndView) throws Exception {logger.info("執行完方法之后進執行(Controller 方法調用之后),但是此 時還沒進行視圖渲染");}@Overridepublic void afterCompletion(HttpServletRequest request,HttpServletResponse response, Object handler, Exception ex) throwsException {logger.info("整個請求都處理完咯,DispatcherServlet 也渲染了對應的 視圖咯,此時我可以做一些清理的工作了");}}2.配置攔截器
@Configuration //定義完攔截器之后配置攔截器 //在Spring Boot 2.0 之前,我們都是直接繼承WebMvcConfigurerAdapter 類,然后重寫 //addInterceptors 方法來實現攔截器的配置。但是在Spring Boot 2.0 之后,該方法已 //經被廢棄了(當然,也可以繼續用),取而代之的是WebMvcConfigurationSupport 方法,如下: public class MyInterceptorConfig extends WebMvcConfigurationSupport {@Overrideprotected void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new MyInterceptor()).addPathPatterns("/**"); //addPathPatterns 方法是添加要攔截的請求,這里我們攔截所有的請求。這 super.addInterceptors(registry);} }啟動:
訪問controller層下的任意路徑,查看控制臺輸出:
3.解決靜態資源被攔截
雖然Spring Boot 2.0 廢棄了WebMvcConfigurerAdapter,但是
WebMvcConfigurationSupport 又會導致默認的靜態資源被攔截,這就需要我們手動將靜態資源放開。
如何放開呢?除了在MyInterceptorConfig 配置類中重寫addInterceptors 方法外,還需要再重寫一個方法:addResourceHandlers,將靜態資源放開:
這樣配置好之后,重啟項目,靜態資源也可以正常訪問了。
另外一種更方便的方式來配置:
不繼承WebMvcConfigurationSupport 類,直接實現WebMvcConfigurer 接口,然后重寫addInterceptors 方法,將自定義的攔截器添加進去即可,如下:
由于這兩種方式的不同,繼承WebMvcConfigurationSupport 類的方式可以用在前后端分離的項目中,后臺不需要訪問靜態資源(就不需要放開靜態資源了);實現WebMvcConfigure 接口的方式可以用在非前后端分離的項目中,因為需要讀取一些圖片、css、js 文件等等。
2.攔截器使用實例
2.1判斷用戶有沒有登錄
一般用戶登錄功能我們可以這么做,要么往session 中寫一個user,要么針對每個user 生成一個token,第二種要更好一點,那么針對第二種方式,如果用戶登錄成功了,每次請求的時候都會帶上該用戶的token,如果未登錄,則沒有該token,服務端可以檢測這個token 參數的有無來判斷用戶有沒有登錄,從而實現攔截功能。我們改造一下preHandle 方法,如下:
public class MyInterceptor implements HandlerInterceptor {private static final Logger logger = LoggerFactory.getLogger(MyInterceptor.class);@Overridepublic 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);// 通過方法,可以獲取該方法上的自定義注解,然后通過注解來判斷該方法是否要被攔截// @UnInterception 是我們自定義的注解UnInterception unInterception = method.getAnnotation(UnInterception.class);if (null != unInterception) {return true;}// 判斷用戶有沒有登陸,一般登陸之后的用戶都有一個對應的tokenString token = request.getParameter("token");if (null == token || "".equals(token)) {logger.info("用戶未登錄,沒有權限執行……請登錄");return false;}// 返回true才會繼續執行,返回false則取消當前請求return true;}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {logger.info("執行完方法之后進執行(Controller方法調用之后),但是此時還沒進行視圖渲染");}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {logger.info("整個請求都處理完咯,DispatcherServlet也渲染了對應的視圖咯,此時我可以做一些清理的工作了");} }2.2取消攔截操作
我們可以定義一個注解,該注解專門用來取消攔截操作,如果某個Controller 中的方法我們不需要攔截掉,即可在該方法上加上我們自定義的注解即可,
下面先定義一個注解:
然后在Controller 中的某個方法上添加該注解,在攔截器處理方法中添加該注解取消攔截的邏輯
@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); // 通過方法,可以獲取該方法上的自定義注解,然后通過注解來判斷該方法是否要被攔截 // @UnInterception 是我們自定義的注解 UnInterception unInterception = method.getAnnotation(UnInterception.class); if (null != unInterception) { return true; } // 返回true 才會繼續執行,返回false 則取消當前請求 return true; } 與50位技術專家面對面20年技術見證,附贈技術全景圖總結
以上是生活随笔為你收集整理的【springboot中使用拦截器】的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【springboot中使用aop的具体
- 下一篇: springboot使用HttpSess