过滤器(Filter)与拦截器(Interceptor)区别
过滤器(Filter)
Servlet中的过滤器Filter是实现了javax.servlet.Filter接口的服务器端程序,主要的用途是设置字符集、控制权限、控制转向、做一些业务逻辑判断等。其工作原理是,只要你在web.xml文件配置好要拦截的客户端请求,它都会帮你拦截到请求,此时你就可以对请求或响应(Request、Response)统一设置编码,简化操作;同时还可进行逻辑判断,如用户是否已经登陆、有没有权限访问该页面等等工作。它是随你的web应用启动而启动的,只初始化一次,以后就可以拦截相关请求,只有当你的web应用停止或重新部署的时候才销毁。
Filter可以认为是Servlet的一种“加强版”,它主要用于对用户请求进行预处理,也可以对HttpServletResponse进行后处理,是个典型的处理链。Filter也可以对用户请求生成响应,这一点与Servlet相同,但实际上很少会使用Filter向用户请求生成响应。使用Filter完整的流程是:Filter对用户请求进行预处理,接着将请求交给Servlet进行处理并生成响应,最后Filter再对服务器响应进行后处理。
Filter有如下几个用处。
在HttpServletRequest到达Servlet之前,拦截客户的HttpServletRequest。
根据需要检查HttpServletRequest,也可以修改HttpServletRequest头和数据。
在HttpServletResponse到达客户端之前,拦截HttpServletResponse。
根据需要检查HttpServletResponse,也可以修改HttpServletResponse头和数据。
Filter有如下几个种类。
用户授权的Filter:Filter负责检查用户请求,根据请求过滤用户非法请求。
日志Filter:详细记录某些特殊的用户请求。
负责解码的Filter:包括对非标准编码的请求解码。
能改变XML内容的XSLT Filter等。
Filter可以负责拦截多个请求或响应;一个请求或响应也可以被多个Filter拦截。
创建一个Filter只需两个步骤
- 创建Filter处理类
- 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(),执行该方法之前,即对用户请求进行预处理;执行该方法之后,即对服务器响应进行后处理。
- 拦截器是在面向切面编程中应用的,就是在你的service或者一个方法前调用一个方法,或者在方法后调用一个方法。是基于JAVA的反射机制。拦截器不是在web.xml,比如struts在struts.xml中配置。
-
拦截器(Interceptor)使用
interceptor 的执行顺序大致为:
- 请求到达 DispatcherServlet
- DispatcherServlet 发送至 Interceptor ,执行 preHandle
- 请求达到 Controller
- 请求结束后,postHandle 执行
Spring 中主要通过 HandlerInterceptor 接口来实现请求的拦截,实现 HandlerInterceptor 接口需要实现下面三个方法:
- preHandle() – 在handler执行之前,返回 boolean 值,true 表示继续执行,false 为停止执行并返回。
- postHandle() – 在handler执行之后, 可以在返回之前对返回的结果进行修改
- afterCompletion() – 在请求完全结束后调用,可以用来统计请求耗时等等