Servlet过滤器是服务器与客户端请求与响应的中间层组件,主要用于对浏览器的请求进行过滤处理,用于拦截客户端对服务端的请求,并对这些请求进行过滤,或者重定向的不同目标资源。
过滤器以一种组件的方式绑定到WEB应用程序,它采用了“链”的方式进行处理的,可以进行多级过滤。

若在服务端部署了多个过滤器,请求会依次按照过滤器的顺序进行处理,在第一个过滤器处理请求后,会传递给第二个过滤器进行处理,以此类推,一直传递到最后一个过滤器。
过滤器的对象主要是Filter,它不是一个标准的Servlet,它不能处理用户请求,也不能对客户端生成响应。主要用于对HttpServletRequest 进行预处理,也可以对HttpServletResponse 进行后处理。
Filter是一个接口,编写过滤器对象需要实现Filter接口,在Filter接口定义了三个方法,分别是init()、destory() 和doFilter()。
init()方法
该方法在 Filter 生命周期中仅执行一次,在过滤器被初始化时调用。
destory()方法
该方法在Web容器卸载 Filter 对象之前被调用,在这个方法中,可以释放过滤器使用的资源。
doFilter()方法
对请求进行过滤处理。
例1:创建一个过滤器对象,实现Filter接口的三个方法。
在项目的com.example包下新建filter包,在filter包下建立MyFilter类。
程序清单 MyFilter.java
public class MyFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
Filter.super.init(filterConfig);
//过滤器初始化代码
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
// 过滤器处理代码
}
@Override
public void destroy() {
Filter.super.destroy();
// 过滤器释放资源
}
}MyFilter类实现了Filter接口的三个方法。
init()方法主要是初始化过滤器,过滤器的初始化处理代码可以放置到该方法内。参数filterConfig是FilterConfig接口,该接口封装了 Filter 程序在 web.xml 中的所有注册信息,并且提供了一系列获取这些配置信息的方法。
FilterConfig接口的主要方法说明如下:
(1)String getFilterName()
返回在 web.xml 文件中为 Filter 所设置的名称,也就是返回 <filter-name> 元素的设置值。
(1)String getInitParameter(String name)
返回在 web.xml 文件中为 Filter 所设置的某个名称的初始化参数值,如果指定名称的初始化参数不存在,则返回 null。
(3)ServletContext getServletContext()
返回 FilterConfig 对象中所包装的 ServletContext 对象的引用。
doFilter()方法是过滤器处理代码,对请求进行过滤处理的代码可以放置到该方法内;过滤器生命周期结束后,会调用destroy()方法,在方法内可以放置释放过滤器资源的代码。
参数chain是FilterChain接口,该接口的doFilter 方法将激活下一个 Filter的doFilter 方法,能够让过滤器链顺序执行。
要让过滤器生效,需要在web.xml文件内配置过滤器,主要是声明过滤器和配置过滤器映射。
web.xml是tomcat非常重要的配置文件,tomcat启动过程中会读取该配置文件,并加载配置文件内配置的过滤器、监听器、Servlet等Java对象。web.xml在项目webapp目录下的WEB-INF目录。
MyFilter过滤器在web.xml文件内的配置代码如下:
<filter> <filter-name>myfilter</filter-name> <filter-class>com.example.filter.MyFilter</filter-class> </filter> <filter-mapping> <filter-name>myfilter</filter-name> <url-pattern>/myfilter</url-pattern> </filter-mapping>
在web-app标签内添加上面的代码。filter标签用于声明过滤器对象,在这个标签中,必须配置<filter-name>和<filter-class>两个子元素,<filter-name>配置过滤器对象名称,<filter-class>配置过滤器完整类路径。
filter-mapping标签用于配置过滤器的映射路径,<filter-name>是在filter标签内配置的过滤器名称,<url-pattern>配置过滤器应用的URL。
例2:配置一个过滤器,实现网站计数器的功能。
网站计数器的初始化值配置在filter标签内,打开web.xml配置文件,修改filter标签的内容:
<filter> <filter-name>myfilter</filter-name> <filter-class>com.example.filter.MyFilter</filter-class> <init-param> <param-name>count</param-name> <param-value>1000</param-value> </init-param> </filter>
在filter标签内添加<init-param>子元素,该元素主要用于配置过滤器的初始化参数,参数可以使用FilterConfig接口提供的方法读取。
程序清单 MyFilter.java
public class MyFilter implements Filter {
// 计数变量
private int count;
@Override
public void init(FilterConfig filterConfig) throws ServletException {
Filter.super.init(filterConfig);
// 获取在web.xml配置的初始值
String param = filterConfig.getInitParameter("count");
count = Integer.valueOf(param);
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
// 过滤器处理代码
// 过滤器每执行1次,count自增
count++;
HttpServletRequest req = (HttpServletRequest) request;
ServletContext context = req.getSession().getServletContext();
context.setAttribute("count", count);
chain.doFilter(request, response);
}
@Override
public void destroy() {
Filter.super.destroy();
// 过滤器释放资源
}
}MyFilter对象在Tomcat启动后被加载,其init方法被调用,在init方法内初始化计数变量count,当客户端请求与MyFilter过滤器配置的映射URL匹配后,doFilter方法被调用,在doFilter方法内让计数变量count自增,并将计数变量count设置到ServletContext应用环境对象,JSP页面就可以通过application对象的getAttribute方法获取计数变量的值。
在webapp目录下创建filetesample.jsp文件,代码如下:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
访客:<%=application.getAttribute("count")%>
</body>
</html>在浏览器输入filetesample.jsp网页的链接地址,运行结果如下图所示:
