SpringBoot 攔截器妙用你真的瞭解嗎
HandlerInterceptor 詳解
HandlerInterceptor
允許定制 handler
處理器執行鏈的工作流接口。我們可以自定義攔截器用於攔截 handlers 處理器(你可以理解為 controller 層的接口),從而可以添加一些共同的重復性的處理行為(例如接口鑒權,接口日志記錄,性能監控等),而不用修改每一個 handler 的實現。
註意,此基於 SpringBoot 2.3.12.RELEASE
版本講解。
HandlerInterceptor 接口隻有三個默認空實現方法,在低版本中這三個方法不是默認方法,而是抽象方法。
public interface HandlerInterceptor { default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { return true; } default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception { } default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception { } }
這三個方法的執行順序圖如下:
preHandle
preHandle
前置處理,攔截一個處理器(handler)的執行,preHandle 方法會在 HandlerMapping
確定一個適當的處理器對象之後,但在 HandlerAdapter
調用處理器之前被調用。可以簡單理解為 controller 接口被調用之前執行。
Intercepter 是鏈式的,就是一個接著一個執行。如果此方法返回 true,則會執行下一個攔截器或者直接執行處理器。如果此方法返回 false 或者拋出異常則終止執行鏈,也不再調用處理器。
註意,此方法如果不返回 true,那麼 postHandle
和 afterCompletion
不會被執行。
那這個方法有什麼用呢?其實可以做一些接口被調用前的預處理,例如用戶權限校驗。
package com.chenpi; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.lang.Nullable; import org.springframework.stereotype.Component; import org.springframework.web.method.HandlerMethod; import org.springframework.web.servlet.HandlerInterceptor; /** * @Description 用戶權限驗證攔截 * @Author 陳皮 * @Date 2021/6/27 * @Version 1.0 */ @Component public class UserPermissionInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { if (handler instanceof HandlerMethod) { HandlerMethod handlerMethod = (HandlerMethod) handler; // 獲取用戶權限校驗註解 UserAuthenticate userAuthenticate = handlerMethod.getMethod().getAnnotation(UserAuthenticate.class); if (null == userAuthenticate) { userAuthenticate = handlerMethod.getMethod().getDeclaringClass() .getAnnotation(UserAuthenticate.class); } if (userAuthenticate != null && userAuthenticate.permission()) { // 驗證用戶信息 UserContext userContext = userContextManager.getUserContext(request); if (null == userContext) { return false; } } } return true; } }
postHandle
postHandle
後置處理,會在 HandlerAdapter
調用處理器之後,但在 DispatcherServlet
渲染視圖之前被調用。可以在此對 ModelAndView
做一些額外的處理。可以簡單理解為 controller 接口被調用之後執行。
註意,此方法在執行鏈中的執行順序是倒著執行的,即先聲明的攔截器後執行。
afterCompletion
afterCompletion 完成之後,在請求處理完之後被執行,也就是渲染完視圖之後。一般用於做一些資源的清理工作,配合 preHandle 計算接口執行時間等。
註意,和 postHandle 一樣,此方法在執行鏈中的執行順序也是倒著執行的,即先聲明的攔截器後執行。
@Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) { // 請求完後,清除當前線程的用戶信息 UserContextHolder.removeUserContext(); }
註冊攔截器
註意,我們自定義的攔截器要通過 WebMvcConfigurer
的實現類進行註冊,才能生效。
package com.yzj.ehr.common.config; import com.yzj.ehr.common.context.UserContextResolver; import org.springframework.stereotype.Component; import org.springframework.web.method.support.HandlerMethodArgumentResolver; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; import com.yzj.ehr.common.interceptor.UserPermissionInterceptor; /** * @Description 註冊攔截器 * @Author 陳皮 * @Date 2021/6/27 * @Version 1.0 */ @Component public class WebAppConfigurer implements WebMvcConfigurer { private UserPermissionInterceptor userPermissionInterceptor; public WebAppConfigurer(final UserPermissionInterceptor userPermissionInterceptor) { this.userPermissionInterceptor = userPermissionInterceptor; } @Override public void addInterceptors(InterceptorRegistry registry) { // 匹配所有接口,排除/base/test接口 registry.addInterceptor(userPermissionInterceptor).addPathPatterns("/**") .excludePathPatterns("/base/test"); } }
到此這篇關於SpringBoot 攔截器妙用你真的瞭解嗎的文章就介紹到這瞭,更多相關SpringBoot 攔截器內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- 詳解SpringMVC的攔截器鏈實現及攔截器鏈配置
- springboot過濾器和攔截器的實例代碼
- SpringBoot使用Interceptor攔截器的實例
- SpringBoot攔截器的使用介紹
- SpringMVC攔截器超詳細解讀