HandlerInterceptor
Allows customization of the handler
workflow interface of the processor execution chain. We can customize the interceptor to intercept the handlers processor (you can understand it as the interface of the controller layer), so that we can add some common repetitive processing behaviors (such as interface authentication, interface logging, performance monitoring, etc.) without Modify the implementation of each handler.
Note, this explanation is based on SpringBoot 2.3.12.RELEASE
version.
The HandlerInterceptor interface has only three default empty implementation methods. In lower versions, these three methods are not default methods, but abstract methods.
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 { } }
The execution sequence diagram of these three methods is as follows:
preHandle
Pre-processing, To intercept the execution of a handler, the preHandle method will be called after HandlerMapping
determines an appropriate handler object, but before HandlerAdapter
calls the processor. It can be simply understood that the controller interface is executed before it is called.
Intercepter is chained, that is, executed one after another. If this method returns true, the next interceptor or handler is executed directly. If this method returns false or throws an exception, the execution chain is terminated and the handler is no longer called.
Note that if this method does not return true, postHandle
and afterCompletion
will not be executed.
Then what is the use of this method? In fact, you can do some preprocessing before the interface is called, such as user permission verification.
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
Post-processing will be done after HandlerAdapter
calls the processor, but after DispatcherServlet
renders the view was called before. You can do some additional processing on ModelAndView
here. It can be simply understood that it is executed after the controller interface is called.
Note that the execution order of this method in the execution chain is reversed, that is, the interceptor declared first is executed later.
afterCompletion is executed after the request is processed, that is, after the view is rendered. It is generally used to clean up some resources and cooperate with preHandle to calculate the interface execution time, etc.
Note that, like postHandle, the execution order of this method in the execution chain is also reversed, that is, the interceptor declared first is executed later.
@Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) { // 请求完后,清除当前线程的用户信息 UserContextHolder.removeUserContext(); }
Note that our custom interceptor must be registered through the implementation class of WebMvcConfigurer
to take effect.
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"); } }
The above is the detailed content of How to use SpringBoot interceptor. For more information, please follow other related articles on the PHP Chinese website!