侧边栏

拦截器

拦截器

拦截器概述

SpringMVC的处理器拦截器,类似于Servlet开发中的过滤器Filter,用于对处理器进行预处理和后处理。

过滤器和拦截器区别

  1. 过滤器

    依赖于servlet容器。在实现上基于函数回调,可以对几乎所有请求进行过滤,但是缺点是一个过滤器实例只能在容器初始化时调用一次。使用过滤器的目的是用来做一些过滤操作,比如:在过滤器中修改字符编码;在过滤器中修改HttpServletRequest的一些参数,包括:过滤低俗文字、危险字符等

  2. 拦截器

    依赖于web框架,在实现上基于Java的反射机制,属于面向切面编程(AOP)的一种运用。由于拦截器是基于web框架的调用,因此可以使用Spring的依赖注入(DI)进行一些业务操作,同时一个拦截器实例在一个controller生命周期之内可以多次调用。

创建拦截器

  1. 添加SpringMVC提供的拦截器接口:HandlerInterceptor

    public class MyHandlerInterceptor implements HandlerInterceptor {
    
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
                throws Exception {
            System.out.println("MyHandlerInterceptor->preHandle");
            return true;
        }
    
        @Override
        public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
                               ModelAndView modelAndView) throws Exception {
            System.out.println("MyHandlerInterceptor->postHandle");
        }
    
        @Override
        public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
                throws Exception {
            System.out.println("MyHandlerInterceptor->afterCompletion");
        }
    
    }
    
    
  2. 拦截器一个有3个回调方法

    1. preHandle​:

      预处理回调方法,实现处理器的预处理(如登录检查),第三个参数为响应的处理器返回值:true表示继续流程(如调用下一个拦截器或处理器);false表示流程中断(如登录检查失败),不会继续调用其他的拦截器或处理器,此时我们需要通过response来产生响应;

    2. postHandle​:

      后处理回调方法,实现处理器的后处理(但在渲染视图之前),此时我们可以通过modelAndView(模型和视图对象)对模型数据进行处理或对视图进行处理,modelAndView也可能为null。

    3. afterCompletion​:

      整个请求处理完毕回调方法,即在视图渲染完毕时回调,如性能监控中我们可以在此记录结束时间并输出消耗时间,还可以进行一些资源清理,类似于try-catch-finally中的finally,但仅调用处理器执行链中preHandle返回true的拦截器才会执行afterCompletion。

  3. 添加Controller

    @Controller
    @RequestMapping("/index")
    public class LoginControl {
        @RequestMapping(value = "/login")
        public String login(){
            System.out.println("LoginControl->login");
            return  "login";
        }
        @RequestMapping(value = "/test")
        @ResponseBody
        public String test(){
            System.out.println("LoginControl->test");
            return "test";
        }
    }
    
    
  4. 配置拦截器

    1. 拦截所有Controller类里的所有处理方法

      1. 在Spring的配置文件中添加如下配置

            <!-- 配置拦截器:-->
            <mvc:interceptors>
                <!-- 会拦截所有Controller类里的所有处理方法 -->
                <bean class="com.lucas.controller.MyHandlerInterceptor"></bean>
            </mvc:interceptors>
        
        
    2. 只拦截某个请求路径的处理方法

      在Spring的配置文件中添加如下配置

       <!-- 配置拦截器:-->
          <mvc:interceptors>
              <!-- 可以配置多个拦截器  也可以配置bean 拦截器 拦截所有请求 -->
              <mvc:interceptor>
                  <!-- 只拦截该路径 -->
                  <mvc:mapping path="/**/login"/>
                  <!-- 会拦截所有Controller类里的所有处理方法 -->
                  <bean class="com.lucas.controller.MyHandlerInterceptor"></bean>
              </mvc:interceptor>
          </mvc:interceptors>
      
      

SpringBoot拦截器(HandlerInterceptor)

在我们的SpringBoot中要实现拦截请求,可以实现我们的 HandlerInterceptor​ 接口来配置我们的拦截器。接着实现我们的 WebMvcConfigurer​ 实现拦截功能

HandlerInterceptor的三个方法(preHandle,postHandle、afterCompletion)

  1. 目标方法执行之前(preHandle):
  2. 目标方法执行完成之后(postHandle):
  3. 页面渲染后(afterCompletion):

WebMvcConfigurer

其实以前都是继承WebMvcConfigurerAdapter类 不过springBoot2.0以上WebMvcConfigurerAdapter 方法过时,有两种替代方案:

  1. 继承WebMvcConfigurationSupport
  2. 实现WebMvcConfigurer
    但是继承WebMvcConfigurationSupport会让Spring-boot对mvc的自动配置失效。根据项目情况选择。现在大多数项目是前后端分离,并没有对静态资源有自动配置的需求所以继承WebMvcConfigurationSupport也未尝不可。
@Configuration
public class WebAppConfigurer implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        // 可添加多个
        registry.addInterceptor(new TestFilter()).addPathPatterns("/**");
    }

    ....
}

其实下面还有很多方法我这里就省略了,过滤器可以添加多个,可以指定Path,这里的/**是对所有的请求都做拦截。

posted @ 2023-09-19 11:58  lkjlwq  阅读(86)  评论(0)    收藏  举报
// 侧边栏目录 // https://blog-static.cnblogs.com/files/douzujun/marvin.nav.my1502.css