Spring Boot 的拦截器概念上和 Servlet Filter 很像,拦截发送到 Controller 的请求和给出的响应。
你可以通过拦截器实现写日志,增加或更新配置等功能。Spring Boot 中,拦截器的实现有 2 个步骤。
第一步,实现拦截器接口 HandlerInterceptor,或者继承 HandlerInterceptorAdapter 类。
其中 HandlerInterceptor 是一个接口,提供了 3 个方法。
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 {
}
}
注意,该接口有 default 方法,意味着不是所有的方法都需要被实现,按需实现即可。
HandlerInterceptorAdapter 是一个抽象类,它的方法多了一个 afterConcurrentHandlingStarted() 方法,该方法用于处理异步请求,当请求的是异步方法的时候会触发该方法时,异步请求先运行 preHandle,接着运行 afterConcurrentHandlingStarted。
public abstract class HandlerInterceptorAdapter implements AsyncHandlerInterceptor {
/**
* This implementation always returns {@code true}.
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
return true;
}
/**
* This implementation is empty.
*/
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
@Nullable ModelAndView modelAndView) throws Exception {
}
/**
* This implementation is empty.
*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,
@Nullable Exception ex) throws Exception {
}
/**
* This implementation is empty.
*/
@Override
public void afterConcurrentHandlingStarted(HttpServletRequest request, HttpServletResponse response,
Object handler) throws Exception {
}
}
第二步,注册拦截器
注册拦截器很简单,只需要配置一个类,使其实现 WebMvcConfigurer 接口即可(继承 WebMvcConfigurerAdapter 这种方法已经被废弃了)。
其中还可以设定多个不同的拦截器,并且映射到不同的 url 地址上。
配置注册拦截器
@Configuration
public class WebMvcConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new TestInterceptor());
registry.addInterceptor(new TestInterceptor2()).addPathPatterns("/intercept");
}
}
通过上面的 2 个步骤,SpringBoot 中的拦截器就实现好了,非常简单。