拦截器介绍

拦截器的作用

对访问目标程序前,后进行功能的扩展,类似于Filter作用

拦截器的开发过程

自定义拦截器,需要实现org.springframework.web.servlet.HandlerInterceptor接口

//自定义拦截器

public class LogInterceptor implements HandlerInterceptor {

//在执行jsp之后执行
@Override
public void afterCompletion(HttpServletRequest arg0,
HttpServletResponse arg1, Object arg2, Exception arg3)
throws Exception {
    System.out.println("LogInterceptor - afterCompletion...");
}

//在执行目标方法后,jsp执行前执行
@Override
public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1,
Object arg2, ModelAndView arg3) throws Exception {
    System.out.println("LogInterceptor - postHandle...");

}
//在执行目标方法前执行
@Override
public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1,
Object arg2) throws Exception {
     System.out.println("LogInterceptor - preHandle...");
    //返回true 相当于放行请求,执行后面的拦截器或目标方法。
    //返回false 后面的目标方法,拦截器,jsp等都不执行了,主要用于权限控制
    return true;      
}
 
}

声明拦截器配置

<!-- 声明拦截器 -->
<mvc:interceptors>
    <bean id="logInterceptor"  class="com.xiao.zhen.springmvc.interceptor.LogInterceptor"></bean>
</mvc:interceptors>

多个拦截器执行过程

1、当俩个拦截器都实现放行操作时,顺序为preHandle 1,preHandle 2,postHandle 2,postHandle 1,afterCompletion 2,afterCompletion 1

2、当第一个拦截器preHandle返回false,也就是对其进行拦截时,第二个拦截器是完全不执行的,第一个拦截器只执行preHandle部分。

3、当第一个拦截器preHandle返回true,第二个拦截器preHandle返回false,顺序为preHandle 1,preHandle 2 ,afterCompletion 1

拦截器对象是在服务器启动时创建的,单例的

拦截器声明路径的拦截配置

  • 拦截器是基于java的反射机制的,而过滤器是基于函数回调。
  • 拦截器不依赖与servlet容器,过滤器依赖与servlet容器。
  • 拦截器只能对action请求起作用,而过滤器则可以对几乎所有的请求起作用。
  • 拦截器可以访问action上下文、值栈里的对象,而过滤器不能访问。
  • 在action的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次。
  • 拦截器可以获取IOC容器中的各个bean,而过滤器就不行,这点很重要,在拦截器里注入一个service,可以调用业务逻辑

三个方法的作用

<!-- 声明拦截器 -->

<mvc:interceptors>
          //对所有都拦截
     <bean id="logInterceptor"  class="com.xiao.zhen.springmvc.interceptor.LogInterceptor"></bean>                

     <mvc:interceptor>   //进一步细化

     <mvc:mapping path="/springmvc/*"/>   //对谁进行拦截

     <mvc:exclude-mapping path="/springmvc/abc"/>  //不对谁进行拦截
     <bean id="log2Interceptor"  class="com.xiao.zhen.springmvc.interceptor.Log2Interceptor">   </bean>
     </mvc:interceptor>
 
</mvc:interceptors>

开发拦截器除了可以实现HandlerIntercptor接口,还可以继承HandlerInterceptorAdapter适配器类.

多个拦截器执行,体现了责任链设计模式.

  • 责任链设计模式:

    将复杂的业务逻辑拆分成若干个元素,将这些元素纳入到一个链式的结构中,每一个元素的执行有必要调用下一个元素的执行,好处是局部高度的扩展性.可以任意增加,减少元素个数,也可以调整元素的执行顺序.
  • preHandle
预处理回调方法, 实现处理器的预处理(如登录检查),包括目标方法上一些共同的代码也可以放到拦截器中 ,第三个参数为响应的处理器(如具体的Controller实现); 
返回值:true表示继续流程(如调用下一个拦截器或处理器);false表示流程中断(如登录检查失败),不会继续调用其他的拦截器或处理器,此时我们需要通过response来产生响应;
  • postHandle

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

  • afterCompletion

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

过滤器和拦截器的区别

1.过滤器是servlet中的对象,拦截器是框架中的对象

2.过滤器实现Filter接口对象,拦截器是实现HandleInterceptor

3.过滤器是用来设置request,response参数、属性,侧重对数据的过滤;拦截器是用来验证请求的,能截断请求。

4.过滤器是在拦截器之前执行的

5.过滤器是tomcat服务器创建的对象,拦截器是springmvc容器创建的对象

6.过滤器是一个执行时间点;拦截器是三个执行时间点

7.过滤器可以处理jsp、js、html等;拦截器是侧重拦截Controller的对象,如果你的请求不能被DispatcherServlet接收,这个请求不会执行拦截器的内容

8.拦截器拦截普通类方法执行,过滤器过滤servlet请求响应
 

过滤器:

public class AuthFilter implements Filter {

  private final static Logger LOGGER = LoggerFactory.getLogger(AuthFilter.class);

  @Override
  public void init(FilterConfig filterConfig) throws ServletException {

  }

  @Override
  public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
    throws IOException, ServletException {
    HttpServletRequest req = (HttpServletRequest) request;
    try {
      if (req.getMethod().equalsIgnoreCase("OPTIONS")) {
        chain.doFilter(request, response);
      } else {

        String accessToken = req.getHeader(HeaderEnum.ACCESS_TOKEN.getKey());
        String uidStr = req.getHeader(HeaderEnum.UID.getKey());
        String url = req.getRequestURI();

        // 业务处理,例如业务校验

        chain.doFilter(request, response);

      }
    } catch (Exception e) {
      LOGGER.error("user verify api/token/locked error:{}", e);
    }

  }

  @Override
  public void destroy() {
  }

  private Boolean isExclude(String url) {
    List<String> excludeList = new ArrayList<>();
    
    excludeList.add("api/url1");

    excludeList.add("/api/url2");

    return excludeList.contains(url);
  }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值