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/");
}
}
请求日志的记录。
重复提交校验。
@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("/**");
}
}