Filter是在web.xml中另外一个常用的配置项,可以通过<filter>和<filter-mapping>组合起来使用Filter。实际上Filter可以完成与Servlet同样的工作,甚至比Servlet使用起来更加灵活,因为它除了提供了request和response对象外,还提供了一个FilterChain对象,可以让我们更加灵活地控制请求的流转。
过滤器能够对Servlet容器传给Web组件的ServletRequest对象和ServletResponse对象进行检查和修改。过滤器本身并不生成ServletRequest对象和ServletResponse对象,它只为Web组件提供如下过滤功能:
所有自定义的过滤器都必须实现:
javax.servlet.Filter
这个接口。
这个接口包含3个过滤器必须实现的方法:
doFilter(ServletRequest req, ServletResponse res, FilterChain chain){ Code1; chain.doFilter(req, res); // 如果希望执行后续的filter或者servlet必须执行这个方法; Code2; }
过滤器由Servlet容器创建。
发布过滤器时,必须在web.xml文件中加入<filter>元素和<filter-mapping>元素。
<filter> <filter-name>过滤器名</filter-name> <filter-class>过滤器类名</filter-class> <init-param> <param-name>参数名1</param-name> <param-value>参数值1</param-value> </init-param> <init-param> <param-name>参数名2</param-name> <param-value>参数值2</param-value> </init-param> </filter> <filter-mapping> <filter-name>过滤器名</filter-name> <url-pattern>URL</url-pattern> </filter-mapping>
当客户请求的URL和<url-pattern>指定的URL匹配时,Servlet容器就会先调用过滤器的doFilter方法。
如果希望过滤器能为所有的URL过滤,那么可以把<url-pattern>的值设为“/*”,这样,当客户请求访问Web应用中的任何一个Web组件时,Servlet容器都会先把请求转发给过滤器。
在web.xml文件中,必须先配置所有过滤器,再配置Servlet。
多个过滤器可以串联起来协同工作,Servlet容器将根据它们在web.xml中定义的先后顺序,依次调用它们的doFilter方法。
例如,有两个过滤器串联起来,它们的doFilter()方法均采用如下结构:
如果要在过滤器中改写请求/响应信息,可以创建一个HttpServletRequest/HttpServletResponse的包装类,可以直接继承自HttpServletRequestWrapper/HttpServletResponseWrapper类,并覆盖其中的部分方法,再由过滤器把这个包装类的对象传给后续的Web组件。
public class MyResponseWrapper extends HttpServletResponseWrapper{ ... ... public MyResponseWrapper(ServletResponse res){ super((HttpServletResponse)res); ... ... } } public class MyFilter implements Filter{ public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { ... ... MyResponseWrapper myResWrapper = new MyResponseWrapper(response); ... ... chain.doFilter(request, myResWrapper); ... ... } }