一、Interceptor 实现方式
- 实现HandlerInterceptor
- 继承WebRequestInterceptor
两者的区别不大,针对于 preHandle 这个方法的时候,继承WebRequestInterceptor类的不需要返回值,但是实现HandlerInterceptor接口的,需要一个Boolean类型的返回值,true 的才会往下走,false的话就会中断请求,常用的是第一种。
@Override
public void preHandle(WebRequest request) throws Exception {
}
@Override
public void postHandle(WebRequest request, ModelMap model) throws Exception {
}
@Override
public void afterCompletion(WebRequest request, Exception ex) throws Exception {
}
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
Object handler) {
}
@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 {
}
二、针对于springboot 需要的一些配置参数
- 需要一个配置类实现 WebMvcConfigurer来加载拦截器
@Configuration
public class Config implements WebMvcConfigurer {
@Autowired
private ApiSignInterceptor apiSignInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(apiSignInterceptor)
.addPathPatterns("/**")
;
}
}
这里有一个很重要的点,就是拦截器引入,主要是针对 addInterceptors方法。一些人可能会这么去写:
通过new 的方式直接去加载拦截器
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new ApiSignInterceptor())
}
实际上,这两种都是可以实现的,通过@Autowired 的方式去引入你的拦截器,你可以直接在拦截器里面引入其他service来写你的一些业务代码,比如存表之类的,不然的话,你通过new 的方式引入拦截器,你在拦截器里面引入其他的service,会是null,无法使用。
三、异常处理
拦截器里的异常是可以被全局异常捕获的,所以写个全局异常类就可以了,不需要额外在跳到controller里面或者通过response来传递。
@RestControllerAdvice
public class GlobalExceptionAdvice {
@ExceptionHandler({ BizException.class })
public ResponseBean<T> handleBizException(BizException e) {
LogUtil.warn(e, "业务异常");
return new ResponseBean<>(e.getErrorCode(), e.getErrorMsg());
}
}
四、拦截器失效的几种情况
- 如果有其他config 继承了 WebMvcConfigurationSupport 类的,会导致拦截器失效。
- 拦截器没有加到配置里的。
- springboot 的Application 包位置未扫描到,需要加Scan的范围。
|