一、过滤器(Filter)
1.含义
它依赖于servlet容器,配置于web.xml。
Servlet中的过滤器Filter是实现了javax.servlet.Filter接口的服务器端程序,主要的用途是设置字符集、控制权限、控制转向、做一些业务逻辑判断等。在实现上,基于函数回调,它可以对几乎所有请求进行过滤。其工作原理是,只要你在web.xml文件配置好要拦截的客户端请求,它都会帮你拦截到请求,此时你就可以对请求或响应(Request、Response)统一设置编码,简化操作;同时还可进行逻辑判断,如用户是否已经登陆、有没有权限访问该页面等等工作。还可以用来做一些过滤操作,获取我们想要获取的数据,比如:在Javaweb中,对传入的request、response提前过滤掉一些信息,或者提前设置一些参数,然后再传入servlet或者Controller进行业务逻辑操作。它是随你的web应用启动而启动的,只初始化一次,以后就可以拦截相关请求,只有当你的web应用停止或重新部署的时候才销毁。
Filter可以认为是Servlet的一种“加强版”,它主要用于对用户请求进行预处理,也可以对HttpServletResponse进行后处理,是个典型的处理链。Filter也可以对用户请求生成响应,这一点与Servlet相同,但实际上很少会使用Filter向用户请求生成响应。使用Filter完整的流程是:Filter对用户请求进行预处理,接着将请求交给Servlet进行处理并生成响应,最后Filter再对服务器响应进行后处理。
2.用处
(1)在HttpServletRequest到达Servlet之前,拦截客户的HttpServletRequest
(2)根据需要检查HttpServletRequest,也可以修改HttpServletRequest头和数据
(3)在HttpServletResponse到达客户端之前,拦截HttpServletResponse
(4)根据需要检查HttpServletResponse,也可以修改HttpServletResponse头和数据
3.种类
(1)用户授权的Filter:Filter负责检查用户请求,根据请求过滤用户非法请求
(2)日志Filter:详细记录某些特殊的用户请求
(3)负责解码的Filter:包括对非标准编码的请求解码
(4)能改变XML内容的XSLT Filter等
(5)Filter可以负责拦截多个请求或响应;一个请求或响应也可以被多个Filter拦截
4.创建
创建一个Filter只需两个步骤
(1)创建Filter处理类
(2)web.xml文件中配置Filter
创建Filter必须实现javax.servlet.Filter接口,在该接口中定义了如下三个方法
(1)void init(FilterConfig config):用于完成Filter的初始化
(2)void destory():用于Filter销毁前,完成某些资源的回收
(3)void doFilter(ServletRequest request,ServletResponse response,FilterChain chain):实现过滤功能,该方法就是对每个请求及响应增加的额外处理。该方法可以实现对用户请求进行预处理(ServletRequest request),也可实现对服务器响应进行后处理(ServletResponse response)—它们的分界线为是否调用了chain.doFilter(),执行该方法之前,即对用户请求进行预处理;执行该方法之后,即对服务器响应进行后处理
二、拦截器(Interceptor)
1.含义
它依赖于web框架,配置于SpringMVC的配置文件或者struts的配置文件中。在SpringMVC中就是依赖于SpringMVC框架。在实现上,基于Java的反射机制,属于面向切面编程(AOP)的一种运用,就是在service或者一个方法前,调用一个方法,或者在方法后,调用一个方法,比如动态代理就是拦截器的简单实现,在调用方法前打印出字符串(或者做其它业务逻辑的操作),也可以在调用方法后打印出字符串,甚至在抛出异常的时候做业务逻辑的操作。由于拦截器是基于web框架的调用,因此可以使用Spring的依赖注入(DI)进行一些业务操作,同时一个拦截器实例在一个controller生命周期之内可以多次调用。但是缺点是只能对controller请求进行拦截,对其他的一些比如直接访问静态资源的请求则没办法进行拦截处理。
2.使用
Interceptor 的执行顺序大致为:
(1)请求到达 DispatcherServlet
(2)DispatcherServlet 发送至 Interceptor ,执行 preHandle
(3)请求达到 Controller
(4)请求结束后,postHandle 执行
Spring 中主要通过 HandlerInterceptor 接口来实现请求的拦截,实现 HandlerInterceptor 接口需要实现下面三个方法:
(1)preHandle() – 在handler执行之前,返回 boolean 值,true 表示继续执行,false 为停止执行并返回。
(2)postHandle() – 在handler执行之后, 可以在返回之前对返回的结果进行修改
(3)afterCompletion() – 在请求完全结束后调用,可以用来统计请求耗时等等
三、过滤器和的拦截器执行顺序
过滤前(Filter)-拦截前(Interceptor)-Action处理-拦截后-过滤后