(一)拦截器概述
1.1拦截器介绍
拦截器的作用类似于Servlet 中的Filter,都可以用于对处理器进行预处理和后处理。在Spring MVC 与Spring Boot 中使用拦截器一般是实现HandlerInterceptor
接口。
下面是去掉注释后的源码。HandlerInterceptor
接口提供了三个方法。下面分别对这三个方法作具体介绍。
public interface HandlerInterceptor {
boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception;
void postHandle(
HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)
throws Exception;
void afterCompletion(
HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception;
}
1.2拦截器中的三个方法
preHandle()
:这个方法可以实现处理器的预处理,也就是它会在handler 方法执行之前就开始执行。当返回值是true 时表示继续执行,返回false 时则不会执行后续的拦截器或处理器。
作用:身份验证,身份授权等。
postHandle()
:这个方法是后处理回调方法,也就是在控制器完成后(试图渲染之前)执行。
作用:将公用的模型数据传到视图,也可以在这里统一指定视图(菜单导航等)。
afterCompletion()
:这个方法是请求处理完毕后的回调方法,即在视图渲染完毕时调用。
作用:进行统一的异常处理,日志处理等。
(二)在Spring Boot 中使用拦截器
2.1使用步骤
- 写一个拦截器实现
HandlerInterceptor
接口。 - 再写一个类继承
WebMvcConfigurerAdapter
接口,重写其中的addInterceptors()
方法。调用registry.addInterceptor()
方法注册该拦截器。
2.2简单实现
拦截器MyHandlerInterceptor
类
public class MyHandlerInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o)
throws Exception {
System.out.println("== preHandle ==");
return true;
}
@Override
public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse,
Object o, ModelAndView modelAndView) throws Exception {
System.out.println("== postHandle ==");
}
@Override
public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse,
Object o, Exception e) throws Exception {
System.out.println("== afterCompletion ==");
}
}
注册拦截器WebConfiguration
类
@SpringBootConfiguration
public class WebConfiguration extends WebMvcConfigurerAdapter {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new MyHandlerInterceptor()).addPathPatterns("/**");
}
}
控制器TestController
类
@RestController
public class TestController {
@GetMapping("/helllo")
@ResponseBody
public String test(){
System.out.println("== Controller ==");
return "Hello World!";
}
}
PS:在使用拦截器的时候,要注意让入口类扫描到该拦截器,入口类默认扫描的包是与入口类同级的包与其子包。
在访问”hello” 时,控制台的输出如下: