spring MVC 拦截器

深坑

在 spring 中 拦截器intercprot 和 过滤器 Filter 其实作用类似,最重要的是要记住它们的执行顺序: 先 filter 后 interceptor,过滤前 -> 拦截前 -> action 执行 -> 拦截后 -> 过滤后。

拦截器类型:

关于 WebMvcConfigurer 配置接口

spring boot 2.0 以前
WebMvcConfigurer只是个接口, 通过 WebMvcConfigurerAdapter 空实现该接口,配置拦截都继承于 WebMvcConfigurerAdapter 抽象类。

spring boot 2.0 以后
WebMvcConfigurer 接口的方法成员采用了 default 关键字,因此 WebMvcConfigurerAdapter 被废弃。可以直接通过 implements 实现 WebMvcConfigurer 需要重写的方法。

WebMvcConfigurationSupport
当没有定义 WebMvcConfigurationSupport 配置类时,默认会启用 WebMvcAutoConfiguration 类来加载 DelegatingWebMvcConfiguration 委托类。参考文章1参考文章2

HandlerInterceptor 接口

1)、创建一个拦截器实现 HandlerInterceptor 接口

public class LoginHandlerInterceptor implements HandlerInterceptor { @Resource private ValueOperations<String, Object> valueOperations; /** * 该方法在处理请求之前进行调用,就是在执行 Controller 的任务之前,如果返回 true 就继续往下执行,返回 false 就放弃执行 */ @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { Cookie[] cookies = request.getCookies(); String _token=null; if (cookies != null) { for (Cookie cookie : cookies) { if (cookie.getName().equals("_TOKEN_")) { _token = cookie.getValue(); } } } /** * 判断是否登录,没登录直接返回 */ if (StringUtils.isBlank(_token) || valueOperations.get(_token) == null) { Result result = Result.failure(1990, "Go log in, access"); response.setContentType("application/json"); response.setStatus(HttpServletResponse.SC_OK); response.setCharacterEncoding("UTF-8"); response.getOutputStream().println(JSON.toJSONString(result)); return false; } return true; } }

2)、新建配置类来管理拦截器,并将之前的拦截器注入其中
在 spring Boot 1.5版本都是靠重写 WebMvcConfigurerAdapter 的方法来添加自定义拦截器,在 springBoot 2.0 后,该类被标记为 @Deprecated(弃用),官方推荐直接实现WebMvcConfigurer或者直接继承WebMvcConfigurationSupport,方式一实现WebMvcConfigurer接口(推荐)方式二继承WebMvcConfigurationSupport类

@Configuration public class WebAppConfig implements WebMvcConfigurer { /** * 由于在拦截器中注解无效,需要提交注入 bean */ @Bean public HandlerInterceptor getLoginInterceptor() { return new LoginHandlerInterceptor(); } @Override public void addInterceptors(InterceptorRegistry registry) { /** * 所有以 api 开头的请求都需要经过 LoginHandler 校验 * excludePathPatterns("", "", ...): 用于排查部分需要校验的氢气地址, 需要指定请求全路径 */ registry.addInterceptor(getLoginInterceptor()) .addPathPatterns("/api/**") .excludePathPatterns("/api/user/login"); } }

参考文章

SpringBoot 拦截器(Interceptor)的使用
过滤器 和 拦截器 6个区别,别再傻傻分不清了