美文网首页
拦截器的原理及配置方式

拦截器的原理及配置方式

作者: 小尾巴1024 | 来源:发表于2018-11-27 14:51 被阅读0次

    序言:

    先説一下拦截器的作用吧!拦截器可以动态拦截请求路径,然后可以在拦截前后进行某些操作,比如权限验证、入参检测、阻止action执行等。
    在AOP编程中拦截器被用在某个方法或字段被访问之前被拦截,然后在执行前后进行某些操作。
    

    原理:

    拦截器Interceptor 的拦截功能是基于Java的反射机制(动态代理)实现的。
    

    实现方法:

    在使用Spring框架时,实现拦截器的功能比较简单,有两种方式:一种是实现HandlerInterceptor接口;另一种是实现WebRequestInterceptor接口。
    

    一、实现HandlerInterceptor接口:该接口定义了 3 个方法,分别为preHandle()、postHandle()和afterCompletion(),咱们就是通过复写这 3 个方法来对用户的请求进行拦截处理的。

    1.1、preHandle(HttpServletRequest request, HttpServletResponse response, Object handle)方法,该方法在请求处理之前进行调用。SpringMVC 中的 Interceptor 是链式调用的,在一个应用中或者说是在一个请求中可以同时存在多个 Interceptor 。每个 Interceptor 的调用会依据它的声明顺序依次执行。该方法的返回值是布尔值 Boolean 类型的,当它返回为 false 时,表示请求结束,后续的 Interceptor 和 Controller 都不会再执行。
    1.2、postHandle(HttpServletRequest request, HttpServletResponse response, Object handle, ModelAndView modelAndView)方法,postHandle 方法在当前请求进行处理之后,也就是在 Controller 中的方法调用之后执行。
    1.3、afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handle, Exception ex)方法,该方法将在整个请求结束之后,也就是在 DispatcherServlet 渲染了对应的视图之后执行,这个方法的主要作用是用于进行资源清理的工作。
    

    二、实现WebRequestInterceptor接口:也定义了 3 个方法,同HandlerInterceptor接口完全相同,咱们也是通过复写这 3 个方法来用户的请求进行拦截处理的。而且这 3 个方法都传递了同一个参数 WebRequest。

    2.1、preHandle(WebRequest request)方法,该方法在请求处理之前进行调用,也就是说,其会在 Controller 中的方法调用之前被调用。
    2.2、postHandle(WebRequest request, ModelMap model)方法,该方法在请求处理之后,也就是在 Controller 中的方法调用之后被调用,但是会在视图返回被渲染之前被调用,所以可以在这个方法里面通过改变数据模型 ModelMap 来改变数据的展示。
    2.3、afterCompletion(WebRequest request, Exception ex)方法,该方法会在整个请求处理完成,也就是在视图返回并被渲染之后执行。因此可以在该方法中进行资源的释放操作。
    

    具体的配置实现:

    1、springboot方式配置拦截器:

    1. 创建一个类继承自HandlerInterceptorAdapter
    public class CommonInterceptor extends HandlerInterceptorAdapter {
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            System.out.println("----preHandle begin---");
            return true;
        }
    }
    
    1. 配置拦截器,需要拦截的路径
    @Configuration
    public class InterceptorConfig  extends WebMvcConfigurerAdapter {
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            registry.addInterceptor(getCommonInterceptor()).addPathPatterns("/user/**");
        }
    
        @Bean
        public CommonInterceptor getCommonInterceptor(){
            return new CommonInterceptor();
        }
    }
    

    2、xml方式配置拦截器

    1. 在SpringMVC的配置文件中加入以下标签
    <mvc:interceptors>
      <!-- 使用 bean 定义一个 Interceptor,直接定义在 mvc:interceptors 下面的 Interceptor 将拦截所有的请求 -->
      <!--<bean class="com.test.interceptor.TimeBasedAccessInterceptor"/>-->
      <mvc:interceptor>
          <mvc:mapping path="/test"/>
          <!-- 定义在 mvc:interceptor 下面的 Interceptor,表示对特定的请求进行拦截 -->
          <bean class="com.test.interceptor.TimeBasedAccessInterceptor"/>
      </mvc:interceptor>
      <mvc:interceptor>
          <mvc:mapping path="/person"/>
          <bean class="com.test.interceptor.PersonInterceptor"/>
      </mvc:interceptor>
    </mvc:interceptors>
    

    //这个拦截器拦截 /person路径

    public class PersonInterceptor extends HandlerInterceptorAdapter {
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            Enumeration parameterNames = request.getParameterNames();
            while (parameterNames.hasMoreElements()){
                Object o = parameterNames.nextElement();
                System.out.println(o.toString());
            }
            return true;
        }
    }
    

    //这个拦截器拦截 /test路径

    public class TimeBasedAccessInterceptor extends HandlerInterceptorAdapter {
        @Override
        public boolean preHandle(HttpServletRequest request,
                                HttpServletResponse response, Object handler) throws Exception {
            String url = request.getRequestURL().toString();
            Enumeration<String> parameterNames = request.getParameterNames();
            while (parameterNames.hasMoreElements()) {
                String name = parameterNames.nextElement();
                System.out.println(name + " : " + request.getParameter(name));
            }
            return true;
        }
    }
    

    相关文章

      网友评论

          本文标题:拦截器的原理及配置方式

          本文链接:https://www.haomeiwen.com/subject/aaugqqtx.html