• SpringMVC基础:拦截器


    Interceptor拦截器

    拦截器是整个SpringMVC的一个重要内容,拦截器与过滤器类似,都是用于拦截一些非法请求,但是我们之前讲解的过滤器是作用于Servlet之前,只有经过层层的拦截器才可以成功到达Servlet,而拦截器并不是在Servlet之前,它在Servlet与RequestMapping之间,相当于DispatcherServlet在将请求交给对应Controller中的方法之前进行拦截处理,它只会拦截所有Controller中定义的请求映射对应的请求(不会拦截静态资源),这里一定要区分两者的不同。

    创建拦截器

    创建一个拦截器我们需要实现一个HandlerInterceptor接口:

    1. public class MainInterceptor implements HandlerInterceptor {
    2. @Override
    3. public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    4. System.out.println("我是处理之前!");
    5. return true; //只有返回true才会继续,否则直接结束
    6. }
    7. @Override
    8. public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
    9. System.out.println("我是处理之后!");
    10. }
    11. @Override
    12. public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
    13. System.out.println("我是完成之后!");
    14. }
    15. }

    接着我们需要在配置类中进行注册:

    1. @Override
    2. public void addInterceptors(InterceptorRegistry registry) {
    3. registry.addInterceptor(new MainInterceptor())
    4. .addPathPatterns("/**") //添加拦截器的匹配路径,只要匹配一律拦截
    5. .excludePathPatterns("/home"); //拦截器不进行拦截的路径
    6. }

    现在我们在浏览器中访问index页面,拦截器已经生效。

    得到整理拦截器的执行顺序:

    我是处理之前!

    我是处理!

    我是处理之后!

    我是完成之后!

    也就是说,处理前和处理后,包含了真正的请求映射的处理,在整个流程结束后还执行了一次afterCompletion方法,其实整个过程与我们之前所认识的Filter类似,不过在处理前,我们只需要返回true或是false表示是否被拦截即可,而不是再去使用FilterChain进行向下传递。

    那么我们就来看看,如果处理前返回false,会怎么样:

    我是处理之前!

    通过结果发现一旦返回false,之后的所有流程全部取消,那么如果是在处理中发生异常了呢?

    1. @RequestMapping("/index")
    2. public String index(){
    3. System.out.println("我是处理!");
    4. if(true) throw new RuntimeException("");
    5. return "index";
    6. }

    结果为:

    我是处理之前! 我是处理! 我是完成之后!

    我们发现如果处理过程中抛出异常,那么久不会执行处理后postHandle方法,但是会执行afterCompletion方法,我们可以在此方法中获取到抛出的异常。

    多级拦截器

    前面介绍了仅仅只有一个拦截器的情况,我们接着来看如果存在多个拦截器会如何执行,我们以同样的方式创建二号拦截器:

     

    1. public class SubInterceptor implements HandlerInterceptor {
    2. @Override
    3. public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    4. System.out.println("二号拦截器:我是处理之前!");
    5. return true;
    6. }
    7. @Override
    8. public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
    9. System.out.println("二号拦截器:我是处理之后!");
    10. }
    11. @Override
    12. public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
    13. System.out.println("二号拦截器:我是完成之后!");
    14. }
    15. }

    注册二号拦截器:

    1. @Override
    2. public void addInterceptors(InterceptorRegistry registry) {
    3. //一号拦截器
    4. registry.addInterceptor(new MainInterceptor()).addPathPatterns("/**").excludePathPatterns("/home");
    5. //二号拦截器
    6. registry.addInterceptor(new SubInterceptor()).addPathPatterns("/**");
    7. }

    注意拦截顺序就是注册的顺序,因此拦截器会根据注册顺序依次执行,我们可以打开浏览器运行一次:

    一号拦截器:我是处理之前! 二号拦截器:我是处理之前! 我是处理! 二号拦截器:我是处理之后! 一号拦截器:我是处理之后! 二号拦截器:我是完成之后! 一号拦截器:我是完成之后!

    和多级Filter相同,在处理之前,是按照顺序从前向后进行拦截的,但是处理完成之后,就按照倒序执行处理后方法,而完成后是在所有的postHandle执行之后再同样的以倒序方式执行。

    那么如果这时一号拦截器在处理前就返回了false呢?

     

    1. @Override
    2. public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    3. System.out.println("一号拦截器:我是处理之前!");
    4. return false;
    5. }

    得到结果如下:

    一号拦截器:我是处理之前!

    我们发现,与单个拦截器的情况一样,一旦拦截器返回false,那么之后无论有无拦截器,都不再继续。

  • 相关阅读:
    7月20日第壹简报,星期三,农历六月廿二
    消息转化器(解决由于后端给前端响应的格式中不能处理Long类型,因为js只会处理前16位,这样会导致后面的精度丢失)
    条件欧几里得聚类
    npm:发布/迭代个人开发包到世界仓库
    如何实现ElementUI动态表头?
    <wx-open-launch-weapp>微信公众号H5激活微信小程序躺坑日记
    DIRECT_IO 配置参数(UNIX)
    PyTorch与torchvision、torchaudio、python版本对应关系
    MQTT协议入门介绍
    Hadoop大数据开发__HBase分布式集群安装部署
  • 原文地址:https://blog.csdn.net/Leon_Jinhai_Sun/article/details/126573615