Loading

Java之SpringMVC拦截器

SpringMVC拦截器

SpirngMVC的拦截器类似于Servlet中的Filter,是AOP思想的具体应用

SpirngMVC拦截器是SpringMVC自己的,只有使用了SpringMVC才可以用

拦截器只会拦截访问控制器的方法,并不会拦截jsp/html/css/js

Spring的Interceptor(拦截器)与Servlet的Filter有相似之处,都能实现权限检查、日志记录等。不同的是:

Filter Interceptor Summary
Filter 接口定义在 javax.servlet 包中 接口 HandlerInterceptor 定义在org.springframework.web.servlet 包中
Filter 定义在 web.xml 中
Filter在只在 Servlet 前后起作用。Filters 通常将 请求和响应(request/response) 当做黑盒子,Filter 通常不考虑servlet 的实现。 拦截器能够深入到方法前后、异常抛出前后等,因此拦截器的使用具有更大的弹性。允许用户介入(hook into)请求的生命周期,在请求过程中获取信息,Interceptor 通常和请求更加耦合。 在Spring构架的程序中,要优先使用拦截器。几乎所有 Filter 能够做的事情, interceptor 都能够轻松的实现1
Filter 是 Servlet 规范规定的。 而拦截器既可以用于Web程序,也可以用于Application、Swing程序中。 使用范围不同
Filter 是在 Servlet 规范中定义的,是 Servlet 容器支持的。 而拦截器是在 Spring容器内的,是Spring框架支持的。 规范不同
Filter 不能够使用 Spring 容器资源 拦截器是一个Spring的组件,归Spring管理,配置在Spring文件中,因此能使用Spring里的任何资源、对象,例如 Service对象、数据源、事务管理等,通过IoC注入到拦截器即可 Spring 中使用 interceptor 更容易
Filter 是被 Server(like Tomcat) 调用 Interceptor 是被 Spring 调用 因此 Filter 总是优先于 Interceptor 执行

interceptor 的执行顺序大致为:

  1. 请求到达 DispatcherServlet
  2. DispatcherServlet 发送至 Interceptor ,执行 preHandle
  3. 请求达到 Controller
  4. 请求结束后,postHandle 执行

Spring 中主要通过 HandlerInterceptor 接口来实现请求的拦截,实现 HandlerInterceptor 接口需要实现下面三个方法:

  • preHandle() – 在handler执行之前,返回 boolean 值,true 表示继续执行,false 为停止执行并返回。
  • postHandle() – 在handler执行之后, 可以在返回之前对返回的结果进行修改
  • afterCompletion() – 在请求完全结束后调用,可以用来统计请求耗时等等

而preHandle方法大致会在DispatchServlet#doDispatch方法中进行调用。在DispatchServlet#doDispatch中调用applyPreHandler()方法对所有的拦截器进行遍历,如果发现拦截器的preHandle()方法返回false的话,则直接执行triggerAfterCompletion()方法,并返回false,运行停止,如果获取的布尔类型为true,则将对interceptorIndex进行赋值为1。所以拦截器中preHandle的返回值为false,是会在doDispatch方法中抛出异常的。

拦截器配置

springmvc-servlet.xml

<!--    拦截器配置-->
<mvc:interceptors>
    <mvc:interceptor>
<!--            一个/代表当前路径下的这一个请求,/**代表当前路径及子路径下的所有请求-->
        <mvc:mapping path="/**"/>
        <bean class="com.zh1z3ven.controller.MyInterceptor"/>
    </mvc:interceptor>
</mvc:interceptors>

要实现拦截器需要继HandlerInterceptor接口

public class MyInterceptor implements HandlerInterceptor {
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        return false;
    }

    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

    }

    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

    }
}

这里实现了HandlerInterceptor接口的3个方法

1、preHandle方法,处理请求前执行

return true,在这里放行,执行下一个拦截器

return false,不执行下一个拦截器

public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        return false;
    }

2、postHandle方法,处理请求后执行

public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

    }

3、afterCompletion方法,请求过后进行的操作

public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

    }

2\3主要用来写拦截日志

小结:
其实拦截器没多少东西,后续会在审计中的权限绕过深入分析一下

posted @ 2021-08-29 23:35  Zh1z3ven  阅读(206)  评论(0编辑  收藏  举报