/**
* 过滤器
* @author yule
* @date 2018/7/2 21:52
*/
public class DemoFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("demo过滤器init。。。");
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("demo过滤器doFilter。。。此处省略业务处理逻辑");
//通过判断是否继续往下走
filterChain.doFilter(servletRequest, servletResponse);
}
@Override
public void destroy() {
System.out.println("demo过滤器destroy。。。");
}
}
springmvc 拦截器
定义
springMVC 拦截器源码解析 https://www.linuxidc.com/Linux/2019-03/157747.htm
Spring Web MVC的处理器拦截器。类似于Servlet开发中的过滤器Filter,用于对处理器进行预处理和后处理。拦截器是面向切面编程的,依赖的技术就是Java的动态代理。
应用场景
1.日志记录:记录请求日志等。
2.权限检查:白名单等;
3.性能监控:可以通过拦截器在进入处理器之前记录开始时间,在处理完后记录结束时间,从而得到该请求的处理时间;
4.通用行为:读取cookie得到用户信息并将用户对象放入请求,从而方便后续流程使用,还有如提取Locale、Theme信息等,只要是多个处理器都需要的即可使用拦截器实现。
5.OpenSessionInView:如Hibernate,在进入处理器打开Session,在完成后关闭Session。
本质是AOP(面向切面编程),符合 AOP 的所有功能都可以使用拦截器实现。
配置
在 spring-mvc.xml 中
<mvc:interceptors>
<!-- 使用bean定义一个Interceptor,直接定义在mvc:interceptors根下面的Interceptor将拦截所有的请求 -->
<!-- <bean/> -->
<mvc:interceptor>
<!--进行拦截的地址-->
<mvc:mapping path="/**"/>
<bean/>
</mvc:interceptor>
</mvc:interceptors>
执行顺序
根据 xml 中的配置顺序来执行。拦截器的执行顺序在过滤器之间。
方法说明
•preHandle(HttpServletRequest request, HttpServletResponse response, Object handle)方法,该法在请求处理之前进行调用。SpringMVC 中的 Interceptor 是链式调用的,在一个应用中或者说是在一个请求中可以同时存在多个 Interceptor 。每个 Interceptor 的调用会依据它的声明顺序依次执行,而且最先执行的都是 Interceptor 中的 preHandle 方法,所以可以在这个方法中进行一些前置初始化操作或者是对当前请求做一个预处理,也可以在这个方法中进行一些判断来决定请求是否要继续进行下去。该方法的返回值是布尔值 Boolean 类型的,当它返回为 false 时,表示请求结束,后续的 Interceptor 和 Controller 都不会再执行;当返回值为 true 时,就会继续调用下一个 Interceptor 的 preHandle 方法,如果已经是最后一个 Interceptor 的时候,就会是调用当前请求的 Controller 中的方法。
•postHandle(HttpServletRequest request, HttpServletResponse response, Object handle, ModelAndView modelAndView)方法,通过 preHandle 方法的解释咱们知道这个方法包括后面要说到的 afterCompletion 方法都只能在当前所属的 Interceptor 的 preHandle 方法的返回值为 true 的时候,才能被调用。postHandle 方法在当前请求进行处理之后,也就是在 Controller 中的方法调用之后执行,但是它会在 DispatcherServlet 进行视图返回渲染之前被调用,所以咱们可以在这个方法中对 Controller 处理之后的 ModelAndView 对象进行操作。postHandle 方法被调用的方向跟 preHandle 是相反的,也就是说,先声明的 Interceptor 的 postHandle 方法反而会后执行。
•afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handle, Exception ex)方法,也是需要当前对应的 Interceptor 的 preHandle 方法的返回值为 true 时才会执行。因此,该方法将在整个请求结束之后,也就是在 DispatcherServlet 渲染了对应的视图之后执行,这个方法的主要作用是用于进行资源清理的工作。afterCompletion 方法被调用的方向也跟 preHandle 是相反的,也就是说,先声明的 Interceptor 的 afterCompletion 方法反而会后执行
举个栗子
spring-mvc 中