SpringMVC拦截器详解

文章介绍了SpringMVC中的拦截器配置,如何通过继承WebMvcConfigurationSupport定制拦截器行为,以及拦截器链的执行顺序。展示了前置处理、后置处理和完成后的处理逻辑,并指出拦截器链的执行遵循先进后出原则。
摘要由CSDN通过智能技术生成

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操作

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值