过滤器(Filter)
Filter 的基本功能是对 Servlet 容器调用 Servlet 的过程进行拦截,从而在 Servlet 进行响应处理的前后实现一些特殊的功能。
在 Servlet API 中定义了三个接口供开发人员编写 Filter 程序:Filter, FilterChain, FilterConfig。
Filter 程序是一个实现了 Filter 接口的 Java 类,与 Servlet 程序相似,它由 Servlet 容器进行调用和执行。
Filter 程序需要在 web.xml 文件中进行注册和设置它所能拦截的资源:Filter 程序可以拦截 Jsp, Servlet, 静态图片文件和静态 html 文件
过滤过程:
基本工作原理:
Filter可以对Servlet容器发送给Servlet程序的请求和Servlet程序发送给Servlet容器的响应进行拦截,从而对请求和响应的信息进行过滤。
一个web.xml中可以注册多个Filter,当有多个Filter对某个Servlet程序的访问过程进行拦截时,针对该Servlet的访问到达后,web容器就会把这些Filter组合成一个Filter链。链中各个Filter的拦截顺序与它们在web.xml映射的先后顺序一致。
Filter接口:
与开发Servlet不同,Filter接口并没有相应的实现类可以继承。因此,要开发过滤器,只能实现Filter接口。实现Filter接口需要重写下列几个方法:
- init(FilterConfig filterConfig)throws ServletException;
web应用启动时,web服务器会根据web.xml中的配置信息来创建每个注册的Filter实
例,并将其保存在服务器内存中。
web容器创建Filter实例后,立即调用init()方法,该方法在该Filter生命周期中只调用一次。
web容器在调用init方法时,会传递一个包含Filter配置和运行环境的FilterConfig对象。类似于ServletConfig,都由容器实现。利用该对象可以得到ServletContext对象,也可得到Filter配置的初始化参数。该对象的常用方法如下:
- String getFilterName():得到描述符中指定的过滤器的名字。
- String getInitParameter(String name): 返回在部署描述中指定的名字为name的初始化参数的值。如果不存在返回null.
- Enumeration getInitParameterNames():返回过滤器的所有初始化参数的名字的枚举集合。
- public ServletContext getServletContext():返回Servlet上下文对象的引用。
- doFilter(ServletRequest request,ServletResponse response,FilterChain chain) throws IOException,ServletException;
doFilter()类似于Servlet中的service()方法。当客户端请求目标资源时,容器就会调用与
之相关联的Filter的doFilter()方法。
其中request,response参数为web容器或Filter链上一个Filter传来的请求和响应参数。参数chain为代表当前Filter链的对象,只有调用该对象的doFilter(request,response)方法之后,才能把请求交付给下一个Filter或目标Servlet去处理。
即通过chain. doFilter(request, response)放行,让请求和响应向下执行。
该方法的请求和响应参数类型是ServletRequest和ServletResponse,Filter不依赖于具体的协议。
- destroy()
web容器卸载Filter对象前调用,该方法在Filter生命周期中只调用一次,释放Filter占
用的资源。
过滤器的部署:
实现Filter之后,需要在web.xml中注册和设置Filter拦截的资源。通过<filter></filter>和< filter-mapping></ filter-mapping>元素来完成。
Filter注册方式与Servlet基本一致,只是部分名称不同而已。
<filter>
<filter-name>testFitler</filter-name>
<filter-class>org.test.TestFiter</filter-class>
<!-- 配置Filter初始化的参数 -->
<init-param>
<param-name>name</param-name>
<param-value>TestFilter</param-value>
</init-param>
</filter>
<filter-mapping>元素用于设置一个 Filter 所负责拦截的资源。一个Filter拦截的资源可通过两种方式来指定:Servlet 名称和资源访问的请求路径( url样式)
- <filter-name>子元素用于设置filter的注册名称。该值必须是在<filter>元素中声明过的过滤器的名字。
- <url-pattern>设置 filter 所拦截的请求路径。
- <servlet-name>指定过滤器所拦截的Servlet名称。
- <dispatcher>指定过滤器所拦截的资源被 Servlet 容器调用的方式,可以是REQUEST, INCLUDE,FORWARD和ERROR之一,默认REQUEST. 可以设置多个<dispatcher> 子元素用来指定 Filter 对资源的多种调用方式进行拦截。
<dispatcher>子元素设置的值及其意义:
REQUEST |
当用户直接访问页面时,Web容器将会调用过滤器。 |
INCLUDE |
如果目标资源是通过RequestDispatcher的include()方法访问时,那么该过滤器将被调用。 |
FORWARD |
如果目标资源是通过RequestDispatcher的forward()方法访问时,那么该过滤器将被调用。 |
ERROR |
如果目标资源是通过声明式异常处理机制调用时,那么该过滤器将被调用。 |