一个 Filter 程序就是一个 Java 类,这个类必须实现 Filter 接口。javax.servlet.Filter 接口中定义了三个方法:init、doFilter、destory。
1、init 方法
public voic init(FilterConfig filterConfig) throws ServletException
当一个 Filter 对象能够拦截访问请求时,Servlet 容器将调用 Filter 对象的 doFilter 方法。
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws java.io.IOException.ServletException
其中,参数 request 和 response 为 Web 容器或 Filter 链中上一个 Filter 传递过来的请求和响应对象;参数 chain 为代表当前 Filter 链的对象。
该方法在 Web 容器卸载 Filter 对象之前被调用,也仅执行一次。可以完成与 init 方法相反的功能,释放被该 Filter 对象打开的资源,例如:关闭数据库连接和 IO 流。
该接口用于定义一个 Filter 链的对象应该对外提供的方法,这个接口只定义了一个 doFilter 方法。
public void doFilter(ServletRequest request, ServletResponse response) throws java.io.IOException.ServletException
FilterChain 接口的 doFilter 方法用于通知 Web 容器把请求交给 Filter 链中的下一个 Filter 去处理,如果当前调用此方法的 Filter 对象是Filter 链中的最后一个 Filter,那么将把请求交给目标 Servlet 程序去处理。
一个 <filter> 元素用于注册一个 Filter。其中,<filter-name> 元素是必需的,<filter-class> 元素也是必需的,<init-param> 元素是可选的,可以有多个 < init-param> 元素。
<filter>
<filter-name>FirstFilter</filter-name>
<filter-class>FirstFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>GB2312</param-value>
</init-param>
</filter>
<filter-mapping> 元素用于设置一个 Filter 所负责拦截的资源。一个 Filter 拦截的资源可以通过两种方式来指定:资源的访问请求路径和 Servlet 名称。
第一种:指定资源的访问路径
<filter-mapping>
<filter-name>FirstFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<url-pattern> 元素中的访问路径的设置方式遵循 Servlet 的 URL 映射规范。
第二种:指定 Servlet 的名称
<filter-mapping>
<filter-name>FirstFilter</filter-name>
<servlet-name>default></servlet-name>
<dispatcher>INCLUDE</dispatcher>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
(1)、<servlet-name> 元素与 <url-pattern> 元素是二选一的关系,其值是某个 Servlet 在 web.xml 文件中的注册名称。
(2)、<dispatcher> 元素的设置值有 4 种:REQUEST、INCLUDE、FORWARD、ERROR,分别对应 Servlet 容器调用资源的 4 种方式:
如果没有设置 <dispatcher> 子元素,则等效于 REQUEST 的情况。也可以设置多个 <dispatcher> 子元素,用于指定 Filter 对资源的多种调用方式都进行拦截。
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
public class FirstFilter implements Filter {
private FilterConfig filterConfig = null;
String paramValue = null;
@Override
public void init(FilterConfig filterConfig) throws ServletException {
this.filterConfig = filterConfig;
paramValue = filterConfig.getInitParameter("encoding");
}
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
System.out.println("begin headers-------------------");
Enumeration<?> headerNames = ((HttpServletRequest)request).getHeaderNames();
while(headerNames.hasMoreElements()) {
String headerName = (String)headerNames.nextElement();
System.out.println(headerName + ": " + ((HttpServletRequest)request).getHeader(headerName));
}
System.out.println("end headers-------------------");
//在调用目标前写入响应内容
response.setContentType("text/html; charset=gb2312");
PrintWriter out = response.getWriter();
out.println("IP地址为:" + request.getRemoteHost() + "<br>");
chain.doFilter(request, response);
//在目标返回后写入响应内容
out.println("<br>名称为encoding的初始化参数的值为:" + paramValue);
out.println("<br>当前Web程序的真实路径为:" + filterConfig.getServletContext().getRealPath("/"));
//out.println("<br>修改了test.html文件!");
}
@Override
public void destroy() {
this.filterConfig = null;
}
}
<filter>
<filter-name>FirstFilter</filter-name>
<filter-class>FirstFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>GB2312</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>FirstFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
这就是test.html页面的原始内容!
</body>
</html>
访问:http://localhost:8888/testFilter_001/filter/test.html