与servlet类似,过滤器就是Java组件,请求发送到servlet之前,可以用过滤器截获和处理请求,另外servlet结束工作之后,但在响应发回给客户之前,可以用过滤器处理响应。
<?xml version="1.0"encoding="UTF-8"?>
<web-app version="2.5"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<display-name></display-name>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<filter>
<filter-name>BeerRequest</filter-name>
<filter-class>com.BeerRequestFilter</filter-class>
<init-param> <!-- 可选,可以有多个 -->
<param-name>LogFileName</param-name>
<param-value>UserLog.txt</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>BeerRequest</filter-name>
<url-pattern>*.do</url-pattern> <!-- 开头没有/-->
<!--
url-pattern 对应URL模式的过滤器映射,定义哪些Web应用资源使用这个过滤器
servlet-name 对应Servlet名的过滤器映射
如:<servlet-name>AdviceServlet</servlet-name>
-->
<!-- 2.4版本
<dispatcher>REQUEST</dispatcher>为通过请求分派请求的Web资源声明一个过滤器映射
REQUEST(默认) INCLUDE FORWARDERROR (可包含0~4个)
-->
</filter-mapping>
</web-app>
建立请求跟踪过滤器
package com;
import java.io.IOException;
import javax.servlet.*;
import javax.servlet.http.*;
public class RequestFilter implementsFilter {
privateFilterConfig fc;
publicvoid init(FilterConfig config) throws ServletException {
this.fc= config;
}
//参数不取HTTP请求和响应对象做参数,而只是常规的ServletRequest和ServletResponse对象
publicvoid doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
throwsServletException, IOException {
HttpServletRequesthttpReq = (HttpServletRequest) req;
Stringname = httpReq.getRemoteUser();
if(name!= null) {
fc.getServletContext().log("User" + name + "is updating");
}
chain.doFilter(req,resp); //链接到下一个组件(Servlet或过滤器)
}
publicvoid destroy() {
}
}
**如果要用响应过滤器对响应做出处理再发回给客户**
在正常情况下tomcat容器connector处理一次客户端http请求时的处理流程是:创建HttpServletRequest请求、HttpServletResponse响应和ClientJSPorServlet客户JSP或Servlet对象实例,然后调用service方法完成处理。加入过滤器Filter和封装类Wrapper后情况有所改变,使调用过程发生了变化。容器在初始化时先创建Filter对象示例,当用客户端请求时将先转给Filter进行处理(根据过滤器的url-pattern设置拦截那些请求),由Filter过滤器决定滞后的处理流程(或正常处理或中断、转向等有代码控制);Filter将HttpServletRequest请求和封装后的HttpServletResponseWrapper响应转给客户JSP或Servlet对象进行处理,处理结束后又回到过滤器,我们在这里加入信息过滤处理过程,然后再将数据写回HttpServletResponse对象,响应客户端。由此可见,HttpServletResponseWrapper是一个封装后的“假”响应对象,我们真是使用假的响应对象获取了响应数据,只是在写回数据调用输出流时发生了问题:在JSP或Servket(Java Servlet)中调用了getWriter()或getOutputStream()方法时,如果在Wrapper中实现了(覆盖)这两个方法,则调用Wrapper中的方法;如果没有实现,则相当于调用HttpServletResponse中方法;而我们在写回数据时必须调用getWriter()或getOutputStream()方法。
如:
public void doFilter(ServletRequest req,ServletResponse resp, FilterChain chain)
throwsServletException, IOException {
//定制包装器类包装响应
MyResponseWrappermrw = new MyResponseWrapper((HttpServletResponse)resp);
//发送定制的响应对象
chain.doFilter(req,mrw);
/*
* 这里完成响应处理
*/
}
包装器
如果你想创建定制请求或响应对象,只需要派生某个便利请求或响应“包装器”类。包装器包装了实际的请求或响应对象,而且吧调用委托传给实际的对象,还允许你对定制请求或响应做所需的额外处理。
*ServletRequestWrapper
*HttpServletRequestWrapper
*ServletResponseWrapper
*HttpServletResponseWrapper