学习了解HandlerInterceptor

684 阅读2分钟

1、前言

  • 在SpringBoot中我们可以使用HandlerInterceptor这个适配器来实现自己的拦截器。这样就可以拦截所有的请求并做相应的处理。

2、应用场景

  • 日志记录、请求前、请求后日志记录
  • 登录校验,在任何请求前校验登录接口
  • 性能监控。检查慢sql
  • 防重复提交

3、主要包括

- 在HandlerInterceptor中主要提供了以下的方法:

    • preHandle:在方法被调用前执行。在该方法中可以做类似校验的功能。如果返回true,则继续调用下一个拦截器。如果返回false,则中断执行,也就是说我们想调用的方法 不会被执行,但是你可以修改response为你想要的响应。
    • postHandle:在方法执行后调用。
    • afterCompletion:在整个请求处理完毕后进行回调,也就是说视图渲染完毕或者调用方已经拿到响应。

4、handlerInceptor和handlerInterceptorAdaptor的区别

  • handlerInterceptorAdaptor需要继承,handlerInceptor需要实现
  • 建议使用HandlerInterceptorAdapter,因为可以按需进行方法的覆盖。

5、HandlerInterceptor需要结合webMvcConfigurer 来使用,

6、代码

一个登录验证的逻辑。


@Configuration
public class InterceptorConfig implements WebMvcConfigurer {

    @Autowired
    private IBizLoginService loginService;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {

        InterceptorRegistration registration = registry.addInterceptor(new HandlerInterceptor() {
            @Override
            public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
                return loginService.isLogin(request, response);
//                return true;
            }

            @Override
            public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

            }

            @Override
            public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

            }
        });
        registration.addPathPatterns("/**");                    //所有路径都被拦截
        registration.excludePathPatterns("/", "/login", "/error", "/static/**", "/common/cutword");       //添加不拦截路径
        registration.excludePathPatterns("/swagger-resources/**", "/webjars/**", "/v2/**", "/swagger-ui.html/**");
    }

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("doc.html").addResourceLocations("classpath:/META-INF/resources/");
        registry.addResourceHandler("swagger-ui.html").addResourceLocations("classpath:/META-INF/resources/");
        registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");
    }
}

请求日志的记录。

image.png

image.png

重复提交校验。

@Component
public abstract class RepeatSubmitInterceptor extends HandlerInterceptorAdapter
{
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception
    {
        if (handler instanceof HandlerMethod)
        {
            HandlerMethod handlerMethod = (HandlerMethod) handler;
            Method method = handlerMethod.getMethod();
            RepeatSubmit annotation = method.getAnnotation(RepeatSubmit.class);
            if (annotation != null)
            {
                if (this.isRepeatSubmit(request))
                {
                    AjaxResult ajaxResult = new AjaxResult();
                    ajaxResult.put("code", Constants.CODE.REPEAT_SUBMIT_ERROR.getValue());
                    ajaxResult.put("msg", Constants.CODE.REPEAT_SUBMIT_ERROR.getDescription());
                    ajaxResult.put("obj", "");
                    ServletUtils.renderString(response, Json.marshal(ajaxResult));
                    return false;
                }
            }
            return true;
        }
        else
        {
            return super.preHandle(request, response, handler);
        }
    }

    /**
     * 验证是否重复提交由子类实现具体的防重复提交的规则
     * 
     * @param request
     * @return
     * @throws Exception
     */
    public abstract boolean isRepeatSubmit(HttpServletRequest request) throws Exception;
}




@Configuration
public class RepeatSubmitConfig implements WebMvcConfigurer  {
    @Autowired
    private RepeatSubmitInterceptor repeatSubmitInterceptor;

    /**
     * 自定义拦截规则
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry)
    {
        registry.addInterceptor(repeatSubmitInterceptor).addPathPatterns("/**");
    }
}