1.拦截器配置
拦截器是一种动态拦截方法调用的机制,在SpringMVC中动态拦截控制器方法的执行
1.WebMvcConfigurationSupport是Spring MVC的主要配置类之一,它用于自定义和配置Spring MVC的行为和特性,我们可以通过继承WebMvcConfigurationSupport类来扩展和定制Spring MVC的配置。
2.通过重写WebMvcConfigurationSupport类中的方法,可以对请求处理、视图解析、格式转换、拦截器、资源处理等进行定制和扩展
//控制器
@Controller
public class UserController
{
@RequestMapping("/gouser")
@ResponseBody
public User go(User user)
{
System.out.println(user);
return user;
}
}
//拦截器类
@Component
public class MyInterceptor implements HandlerInterceptor
{
@Override
//执行前
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("执行前拦截器处理");
//handler:被拦截的处理器对象,本质上是一个方法对象,对反射技术中的method对象进行了再封装
HandlerMethod handlerMethod = (HandlerMethod) handler;
System.out.println(handlerMethod.getMethod().getName());
//return true则被拦截的处理器允许往下执行,return false则被拦截的处理器不往下执行
return true;
}
@Override
//执行后
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
//modelAndView如果处理器执行完成具有返回结果,可以读取到对应数据和页面信息,并进行调整
System.out.println("执行后拦截器处理");
}
@Override
//完成后
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
//ex如果处理器执行过程中出现异常,可以针对异常进行单独处理
System.out.println("完成后的最后处理");
}
}
//配置WebMvcConfigurationSupport
@Component
public class SpringMVCSupport extends WebMvcConfigurationSupport
{
@Autowired
private MyInterceptor myInterceptor;
@Override
//指定拦截器指定拦截路径
protected void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(myInterceptor).addPathPatterns("/gouser");
}
@Override
//过滤静态资源
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/webapp/**").addResourceLocations("/webapp");
}
}
启动服务器发起请求:http://localhost/gouser?id=1&name=milo&hobby.food=apple&hobby.sport=ball
控制台输出:
执行前拦截器处理
go
User{id=1, name='ssc', hobby=Hobby{food='apple', sport='ball'}}
执行后拦截器处理
完成后的最后处理
2.拦截器链的配置与执行顺序
//01拦截器
@Component
public class MyInterceptor01 implements HandlerInterceptor
{
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("执行前拦截器处理01");
HandlerMethod handlerMethod = (HandlerMethod) handler;
System.out.println(handlerMethod.getMethod().getName());
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("执行后拦截器处理01");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("完成后的最后处理01");
}
}
//02拦截器
@Component
public class MyInterceptor02 implements HandlerInterceptor
{
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("执行前拦截器处理02");
HandlerMethod handlerMethod = (HandlerMethod) handler;
System.out.println(handlerMethod.getMethod().getName());
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("执行后拦截器处理02");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("完成后的最后处理02");
}
}
//组成拦截器链
@Component
public class SpringMVCSupport extends WebMvcConfigurationSupport
{
@Autowired
private MyInterceptor myInterceptor;
@Autowired
private MyInterceptor02 myInterceptor02;
@Override
protected void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(myInterceptor).addPathPatterns("/gouser");
registry.addInterceptor(myInterceptor02).addPathPatterns("/gouser");
}
@Override
protected void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/webapp/**").addResourceLocations("/webapp");
}
}
启动服务器发起请求:http://localhost/gouser?id=1&name=milo&hobby.food=apple&hobby.sport=ball
控制台输出:
执行前拦截器处理01
go
执行前拦截器处理02
go
User{id=1, name='ssc', hobby=Hobby{food='apple', sport='ball'}}
执行后拦截器处理02
执行后拦截器处理01
完成后的最后处理02
完成后的最后处理01
我们可以理解拦截器链执行顺序为先进后出
//此时修改下拦截器02的前置处理
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("执行前拦截器处理02");
HandlerMethod handlerMethod = (HandlerMethod) handler;
System.out.println(handlerMethod.getMethod().getName());
return false;
}
启动服务器发起请求:http://localhost/gouser?id=1&name=milo&hobby.food=apple&hobby.sport=ball
控制台输出:
执行前拦截器处理01
go
执行前拦截器处理02
go
完成后的最后处理01
结论:
1.当前面的拦截器前置处理返回false的时候,后面所有的后置处理都不会再执行了
2.当拦截器运行中断时,仅运行配置在前面的拦截器的afterCompletion操作