SpringBoot项目实战经验之HandlerInterceptorAdapter实现自定义拦截器

此文章已同步更新至我的个人博客https://simonting.gitee.io


SpringBoot中提供了HandlerInterceptorAdapter适配器供我们自定义拦截器,可以拦截自定义或所有的请求做相应的处理。

HandlerInterceptorAdapter中共有四个方法:

  • preHandle :在Controller方法被调用前执行
  • postHandle :在Controller方法调用后执行
  • afterCompletion :在整个请求处理完成之后执行
  • afterConcurrentHandlingStarted :用来处理异步请求,当Controller中有异步请求方法的时候会触发该方法。

实现步骤

自定义拦截器

继承HandlerInterceptorAdapter,重写方法(在实际项目中,可以按照实际的业务重写方法,不需要重写全部四个方法)

/**
 * @Author zhangting
 * @Desc 自定义拦截器
 * @Date 2020/08/04
 **/
@Component
@Slf4j
public class MyInterceptor1 extends HandlerInterceptorAdapter {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        log.info("----- preHandle(1) -----");
        return super.preHandle(request, response, handler);
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        log.info("----- postHandle(1) -----");
        super.postHandle(request, response, handler, modelAndView);
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        log.info("----- afterCompletion(1) -----");
        super.afterCompletion(request, response, handler, ex);
    }

    @Override
    public void afterConcurrentHandlingStarted(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        log.info("----- afterConcurrentHandlingStarted(1) -----");
        super.afterConcurrentHandlingStarted(request, response, handler);
    }
}

注册拦截器

实现WebMvcConfigurer,注册拦截器

/**
 * @Author zhangting
 * @Desc 注册拦截器
 * @Date 2020/08/04
 **/
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {

    @Autowired
    private MyInterceptor1 myInterceptor1;


    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(myInterceptor1);
    }
}

上面实现的是自定义一个拦截器的情景,但是一般在实际项目中会需要自定义多个拦截器,那么这些拦截器的执行顺序又是如何确定的呢?拦截器内部的方法的执行顺序又是怎样的呢?

自定义多个拦截器

定义MyInterceptor2拦截器

/**
 * @Author zhangting
 * @Desc 自定义拦截器
 * @Date 2020/08/04
 **/
@Component
@Slf4j
public class MyInterceptor2 extends HandlerInterceptorAdapter {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        log.info("----- preHandle(2) -----");
        return super.preHandle(request, response, handler);
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        log.info("----- postHandle(2) -----");
        super.postHandle(request, response, handler, modelAndView);
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        log.info("----- afterCompletion(2) -----");
        super.afterCompletion(request, response, handler, ex);
    }

    @Override
    public void afterConcurrentHandlingStarted(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        log.info("----- afterConcurrentHandlingStarted(2) -----");
        super.afterConcurrentHandlingStarted(request, response, handler);
    }
}

将自定义的MyInterceptor2拦截器注册到容器中

/**
 * @Author zhangting
 * @Desc 注册拦截器
 * @Date 2020/08/04
 **/
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {

    @Autowired
    private MyInterceptor1 myInterceptor1;

    @Autowired
    private MyInterceptor2 myInterceptor2;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(myInterceptor1);
        registry.addInterceptor(myInterceptor2);
    }
}

此时我们定义了两个拦截器,且注册的时候,先注册MyInterceptor1拦截器,再注册MyInterceptor2拦截器,接下来测试一下他们的执行顺序。

使用postman模拟请求,打印日志


结论

由测试结果可以得出:

  • 拦截器的执行顺序_按照注册顺序_。
  • 方法的执行顺序按照:preHandle()方法按照正序执行,postHandle()、afterCompletion()方法按照倒序执行。

自定义拦截URL

在注册拦截器如果不指定拦截的URL则默认所有的URL都会被拦截。我们也可以在注册拦截器时自定义该拦截器需要拦截的URL。

使用postman模拟请求,查看日志:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值