> 文章列表 > SpringBoot拦截器的使用

SpringBoot拦截器的使用

SpringBoot拦截器的使用

Hi I’m Shendi


SpringBoot拦截器的使用

简介

最近要实现一个全局对象的传递,在接口中直接通过增加函数参数来直接使用的这种方式

之前一直使用的是过滤器,但这种需求过滤器是没有办法实现的,过滤器可以给请求注入字符串,但不能注入对象

例如 User 类,想要的效果如下

public String test(User user) {return user.toString();
}

经过使用,拦截器也不能实现这样的效果…

可以使用addArgumentResolvers来实现,参考 https://sdpro.top/blog/html/article/1047.html

SpringBoot拦截器和Servlet的过滤器类似,相当于基于AOP的函数拦截,拦截器可以用来进行身份验证、日志记录、请求参数处理等。

创建拦截器

有两种方法

  • 实现 org.springframework.web.servlet.HandlerInterceptor
  • 继承 org.springframework.web.servlet.handler.HandlerInterceptorAdapter
    • 这个我用的时候已经被标记弃用了,并且我看实现的AsyncHandlerInterceptor接口,而AsyncHandlerInterceptor实现HandlerInterceptor,所以建议使用第一种

接口代码如下

SpringBoot拦截器的使用

可以看到接口定义了三个默认行为,分别为如下

名称 描述
preHandle 在请求处理前执行,可以理解为过滤器的 chain.doFilter 上面部分代码,有一个boolean返回值,返回true则会继续执行,否则不继续执行
postHandle 在请求处理完执行,可以理解为过滤器的 chain.doFilter 后面部分代码
afterCompletion 处理完执行,在postHandle之后。可以理解为finally

代码如下

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;public class DefaultIntercept implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {System.out.println("pre");return true;}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {System.out.println("post");}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {System.out.println("after");}}

配置拦截器

要使拦截器生效,还需要进行以下操作

  • 创建类,实现WebMvcConfigurer接口
  • 实现addInterceptors函数
  • 在函数内使用 registry.addInterceptor 来使拦截器生效

例如

@Configuration
public class WebConfig implements WebMvcConfigurer {@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(defaultIntercept()).addPathPatterns("/**");}@Beanpublic DefaultIntercept defaultIntercept() {return new DefaultIntercept();}}

后面的 addPathPatterns 为匹配的规则,具体可以参考文档,/** 就代表全部

运行测试

随便建个接口,试试拦截器效果

@GetMapping("/")
public String get() {System.out.println("接口执行");return "test";
}

请求后控制台输出如下

SpringBoot拦截器的使用

在pre的时候 return false 看一下结果

SpringBoot拦截器的使用

可以看到执行了pre后就没有继续执行了

调整优先级

在配置类,添加拦截器的时候可以使用 order 函数指定

registry.addInterceptor(defaultIntercept()).addPathPatterns("/**").order(1);

值越小,优先级越高,不配置默认是0,如果没有指定,那么将按照加入的先后顺序进行拦截

END