上班闲得无聊,写写博客学习一下Servlet过滤器吧!无所事实的日子真是难过。自己找事做吧。。。努力努力!!
Servlet过滤器是在Java Servlet规范2.3中定义的,因此所有实现这一规范的Servlet容器都支持Servlet过滤器。
Servlet能够对Servlet容器的请求和响应对象进行检查和修改。Servlet过滤器本身并不生成请求和响应对象,它只提供过滤作用。Servlet过滤器能够在Servlet被调用之前检查Request对象,修改Request Header和Request内容。在Servlet被调用之后检查Response对象,修改Response Header和Response内容。Servlet过滤器负责过滤的Web组件可以是Servlet、JSP或HTML文件。
Servlet过滤器具有以下特点:
1、创建Servlet过滤器
所有的Servlet过滤器类都必须实现javax.servlet.Filter接口。这个接口含有3个过滤器类必须实现的方法:
下面是一个过滤器的例子,这个名叫NoteFilter的过滤器可以拒绝列在黑名单上的客户访问留言簿,而且能将服务器响应客户请求所花的时间写入日志。NoteFilter的源代码如下:
import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class NoteFilter implements Filter{ private FilterConfig config=null; private String blackList=null; public void init(FilterConfig config) throws ServletException{ this.config=config; blackList=config.getInitParameter("blacklist"); } public void destroy(){ config=null; } public void doFilter(ServletRequest request,ServletResponse response, FilterChain chain)throws IOException,ServletException{ String username=((HttpServletRequest) request).getParameter("username"); if(username!=null) username=new String(username.getBytes("ISO-8859-1"),"GB2312"); if(username!=null&&username.indexOf(blackList)!=-1){ response.setContentType("text/html;charset=GB2312"); PrintWriter out=response.getWriter(); out.println("<html><head></head><body>"); out.println("<h1>对不起"+username+",你没有权限留言</h1"); out.println("</body></html>"); out.flush(); return; } long before=System.currentTimeMillis(); config.getServletContext().log.(NoteFilter:before call chain.doFilter()); chain.doFilter(request,response); config.getServletContext().log("NoteFilter:after call chain.doFilter()"); long after=System.currentTimeMillis(); String name=""; if(request instanceOf HttpServletRequest){ name=((HttpServletRequest)request).getRequestURI(); } config.getServletContext().log("NoteFilter:"+name+":"+(after-before)+"ms"); } }
当NoteFilter初始化时,它调用config.getInitParameter("blacklist")方法,从Web.xml文件中读取初始化参数blacklist,这个参数表示被禁止访问留言簿的客户黑名单。
在NoteFilter的doFilter()方法中首先从request对象中读取客户姓名,然后将客户姓名转换为中文字符编码。如果客户姓名中包含黑名单里的字符串,那么将直接向客户端返回一个拒绝网页。由于在这种情况下没有调用chain.doFilter()方法,因此客户请求不会到达所访问的Web组件。
如果客户名不在黑名单里,NoteFilter的doFilter方法就会调用chain.doFilter()方法,这个方法用于调用过滤器链中后续过滤器的doFilter()方法。假如没有后续过滤器,那么就反客户请求传给相应的Web组件。在本例中,在调用 chain.doFilter()方法前后都生成了一些日志,并且记录了调用chain.doFilter()方法前后的时间,从而计算出Web组件响应客户请求所花的时间。
2、发布Servlet过滤器
发布Servlet过滤器时,必须在web.xml文件中加入<filter>元素和<filter-mapping>元素。<filter>元素用来定义一个过滤器,如下所示:
<filter>
<filter-name>NoteFilter</filter-name>
<filter-class>NoteFilter</filter-class>
<init-param>
<param-name>blacklist</param>
<param-value>捣蛋鬼</param-value>
</init-param>
</filter>
以上代码中,<filter-name>属性指定过滤器的名字,<filter-class>指定过滤器的类名。<init-param>子元素为过滤器实例提供初始化参数,它包含一对参数名和参数值,在<filter>元素中可以包含多具<init-param>子元素。在这里定义一个名为blacklist的参数,在NoteFilter中将读取这个参数,它表示禁止留言的客户黑名单。
<filter-mapping>元素用于将过滤器和URL关联,如下所示:
<filter-mapping>
<filter-name>NoteFilter</Filter-name>
<url-pattern>/note</url-pattern>
</filter-mapping>