好久没写日志了,先在在温习Struts2,涉及到Filter,顺便在网上找到了一些Filter的简介,就顺便写点心得。
可以说Filter类似于servlet,但它与servlet又有本质的区别,Filter不能像servlet那样直接对用户生成响应。Filter完整的工作流程:Filter先对用户请求进行预处理,然后交给servlet进行处理并生成用户响应,最后Filter再对服务器响应进行后处理。
Filter有以下几大好处:
- 可以在HttpServletResquest到达servlet之前,拦截客户的HttpServletRequest。
- 根据用户需要检查HttpServletRequest,也可以修改HttpServletRequest头和数据。
- 在HttpServletResponse到达客户端之前拦截HttpServletResponse。
- 可以根据需要检查HttpServletResponse,并修改HttpServletResponse头和数据。
Filter种类:
- 用户授权的Filter:Filter负责检查用户请求,根据请求过滤用户非法请求。
- 日志Filter:详细记录有些用户的特殊请求。
- 能改变xml内容的XSLT Filter等。
Filter可负责拦截一个或多个请求或响应,一个请求或响应也可以同时被多个Filter拦截。
创建一个Filter有两步:建Filter处理类;web.xml配制。
创建Filter类:
创建Filter类必须实现javax.servlet.Filter接口,该接口定义了三个方法:
- void init(FilterConfig config);负责初始化
- void destroy();负责Filter销毁前完成回收资源等操作
- void doFilter(HttpServletRequest request,HttpServletResponse response,FilterChain chain);处理过滤功能。
先介绍一个简单的Filter应用,用于拦截所有用户的请求并将请求记录在日志中。
package com.filter;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
public class FilterImpl implements Filter {
private FilterConfig config;
public void destroy() {
// 实现销毁方法
this.config=null;
}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
// 实现过滤的核心方法
ServletContext context=this.config.getServletContext();
long before=System.currentTimeMillis();
System.out.println("filter start.....");
HttpServletRequest hrequest=(HttpServletRequest)request;
context.log("Filter has received the user's url:"+hrequest.getServletPath());
chain.doFilter(request,response);
long after=System.currentTimeMillis();
context.log("filter over...");
context.log("request被定位到"+hrequest.getRequestURI()+"所花费的时间为:"+(after-before));
}
public void init(FilterConfig config) throws ServletException {
// 实现初始化方法
this.config=config;
}
}
web.xml配制:
<filter>
<filter-name>log</filter-name>
<filter-class>com.filter.FilterImpl</filter-class>
</filter>
<filter-mapping>
<filter-name>log</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
最终控制器窗口的实验结果:
filter start.....
2010-5-3 14:03:26 org.apache.catalina.core.ApplicationContext log
信息: Filter has received the user's url:/index.jsp
2010-5-3 14:03:28 org.apache.catalina.core.ApplicationContext log
信息: filter over...
2010-5-3 14:03:28 org.apache.catalina.core.ApplicationContext log
信息: request被定位到/FilterDemo/index.jsp所花费的时间为:1360
再来介绍一个功能稍微强大而且使用范围比较广的Filter类。该Filter用于设置request编码的字符集,从而避免每个Servlet都要设置;而且还会验证用户是否已经登录,如果没有登录将直接跳转到登录页面。
下面是Filter类的源码:
import java.io.IOException;
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;
import javax.servlet.http.HttpSession;
public class AuthorityFilter implements Filter {
private FilterConfig config;
public void destroy() {
this.config=null;
}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
String encoding=config.getInitParameter("encoding");
String loginPage=config.getInitParameter("loginPage");
String proLogin=config.getInitParameter("proLogin");
request.setCharacterEncoding(encoding);
HttpServletRequest requ=(HttpServletRequest)request;
HttpSession session=requ.getSession(true);
String requestPath=requ.getServletPath();
if(session.getAttribute("user")==null
&&!requestPath.endsWith(loginPage)
&&!requestPath.endsWith(proLogin)){
System.out.println("cunge.........");
request.getRequestDispatcher(loginPage).forward(request, response);
}else{
chain.doFilter(request, response);
}
}
public void init(FilterConfig filterConfig) throws ServletException {
this.config=filterConfig;
}
}
web.xml配制如下:
<filter>
<filter-name>authority</filter-name>
<filter-class>com.filter.AuthorityFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>GBK</param-value>
</init-param>
<init-param>
<param-name>loginPage</param-name>
<param-value>/login.jsp</param-value>
</init-param>
<init-param>
<param-name>proLogin</param-name>
<param-value>/proLogin.jsp</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>authority</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
上面的web.xml为Filter类制定了三个配制参数。