一、过滤器(Filter)
1、概述:
过滤器是以配置的形式存在,实现接口或基于注解对特定URL进行拦截。工作原理是基于函数回调机制。
Filter可以认为是Servlet的一种“加强版”,它主要用于对用户请求进行预处理,也可以对HttpServletResponse进行后处理,是一个典型的处理链。
Filter也可以对用户请求生成响应,这一点与Servlet相同,但实际上很少会使用Filter向用户生成响应。
2、工作模式:
使用Filter的一般流程是:
1)用户发起请求;
2)Filter先对用户请求进行预处理;
3)处理后请求交给Servlet进行再次预处理,而后生成响应;
4)最后filter再对服务器响应进行后处理。
3、作用:
1)HttpServletRequest到达Servlet之前,拦截客户的HttpServletRequest;
2)根据需要检查HttpServletRequest,也可以修改HttpServletRequest头和数据;
3)在HttpServletResponse到达客户端之前,拦截HttpServletResponse;
4)根据需要检查HttpServletResponse,也可以修改HttpServletResponse头和数据。
4、分类:
Filter有如下几个种类:
1)用户授权的Filter:Filter负责检查用户请求,根据请求过滤用户非法请求;
2)日志Filter:详细记录某些特殊的用户请求;
3)负责解码的Filter:包括对非标准编码的请求解码;
4)能改变XML内容的XSLT Filter等;
Filter可以负责拦截多个请求或响应,一个请求或响应也可以被多个Filter拦截。
5、创建Filter:
1)创建Filter处理类;
2)web.xml文件中配置Filter。
·创建Filter必须实现javax.servlet.Filter接口,在该接口中定义了如下三个方法:
- void init(FilterConfig config):用于完成Filter的初始化;
- void destory():用于Filter销毁前,完成某些资源的回收;
- void doFilter(ServletRequest request, ServletResponse response, FilterChain chain):
该方法实现过滤功能,该方法就是对每个请求及响应增加的额外处理。
该方法可以实现对用户请求进行预处理(ServletRequest request),也可以实现对服务器响应进行后处理(ServletResponse response),而它们的分界线为 - 是否调用了chain.doFilter(),执行该方法之前,即对用户请求进行预处理,执行该方法后,即对服务器响应进行后处理。
二、拦截器(Interceptor) 与AOP
1、概述:
拦截器,是java技术中,spring框架的一个组件,其工作原理依赖于java的反射机制。在AOP(Aspect-Oriented Programming)中,用于在某个方法或字段被访问之前,进行拦截,然后基于AOP的设置,在访问的过程前、中、后自定义的加入操作。
拦截器本身是属于AOP的一种实现策略。
在WebWork的中文文档中解释为 - 拦截器是动态拦截Action调用的对象。它提供了一种机制,可以使开发者可以定义在一个Action执行的前后执行的代码,也可以在一个Action执行前阻止执行。同时也提供了一种可以提取Action中可重用的部分的方式。
2、工作模式
1)用户的请求被提交至控制器处理器后,基于注解对请求进行判断;
2)根据拦截器的设置类型,区分前后置(即controller流程执行前、后),对应执行所需要做的动作行为。
拦截器的实现是继承HandlerInterceptor接口,并实现接口的preHandle、postHandle和afterCompletion方法。
boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception;
preHandler()是前置处理:该方法会在请求处理前执行调用(即预处理)。可以进行编码、安全控制、权限校验等行为;注意,如果返回值为true,将视为当前请求结束,不仅自身的拦截器失效,其他的拦截器也不会再执行。
void postHandle(
HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)
throws Exception;
postHandle()后置处理:这个方法只有prehandle()方法返回值为true时才执行。在业务处理器处理请求执行完成后,生成视图之前执行。后处理(调用了Service并返回ModelAndView,但未进行页面渲染),有机会修改ModelAndView。
void afterCompletion(
HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception;
afterCompletion()后处理:这个方法只有prehandle()方法返回值为true时才执行。在整个请求结束之后,DispatcherServlet渲染了对应的视图后执行。可以用于清理资源等。
3、实现方式:
拦截器的使用基本是基于SpringAOP,由于随着jdk以及springboot的一些技术发展延申,可能实现与用法会有一定不同,近期的用法可以先参考这篇文章:
SpringBoot之HandlerInterceptor拦截器的使用 ——(一)_spring 多个handlerinterceptor-CSDN博客
因为文章主要想记录过滤器(Filter)与拦截器(Interceptor)的区别,所以详细内容,这里暂时不描述。
三、过滤器与拦截器的区别
相同点:
1、过滤器(Filter)与拦截器(Interceptor)均体现AOP的编程思想(切面编程),都可以实现如日志记录、登录鉴权等功能;
2、过滤器(Filter)和拦截器(Interceptor)都可以通过Order注解设定执行顺序。
不同点:
1、过滤器属于Servlet级别,Filter是在javax.servlet包中定义的,需要依赖于网络容器,所以filter只能在web项目中使用;
2、拦截器属于Spring级别,Interceptor是SpringMVC中实现的,它算是spring的一个组件,所以由spring容器进行管理;
3、底层上,过滤器是基于函数回调方式,拦截器是基于java反射机制(动态代理);
4、执行顺序,或称为使用范围不同。过滤器在一个请求首次进入Servlet(web项目)时,doFilter方法即对其产生作用,而拦截器则是在请求进入Servlet之后,在进入Controller之前作用。后处理也是一次类推。