首页 > 代码库 > Servlet之过滤器Filter详解

Servlet之过滤器Filter详解

一、过滤器的基本工作原理

1、过滤器的基本工作原理 

过滤器的基本工作原理如图4-8示。


2、过滤器的特点 
过滤器具备有以下特点: 
(1)它是声明式的 
(2)它是动态的
(3)它是模块化的 
(4)它是可移植的 
(5)它是可重用的 
(6)它是透明的 


二、过滤器的API接口及部署信息 
1、javax.servlet.Filter接口 
(1)public void init(FilterConfig filterConfig) throws ServletException 
init()方法执行初始化操作
(2) public void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) throws java.io.IOException,ServletException 
过滤器的业务逻辑代码在doFilter()方法内实现 
(3)public void destroy() 
在销毁一个过滤器对象之前,此方法被调用来释放init()中申请的资源,这个方法的执行,表示一个过滤器的生命期结束

2、 javax.servlet.FilterConfig接口
(1)public java.util.Enumeration getInitParameterNames() 
将初始化参数的变量名读至枚举型对象中。 
(2)public java.lang.String
                                 getInitParameter(java.lang.String name) 
读取指定变量名的初始化参数值,如果没有此参数,则返回Null值。 
(3)public ServletContext getServletContext() 
获得当前Web应用的ServletContext对象。 

3、javax.servlet. FilterChain接口 
接口中关键的方法为:
public void doFilter(ServletRequest  request,
ServletResponse response)  throws  java.io.IOException,ServletException 

4、过滤器的部署 
在WEB-INF\web.xml中部署一个过滤器的过程有:注册过滤器、映射过滤器
(1)注册过滤器 
过滤器在Web应用中注册后才会被容器加载运行。在web.xml中注册过滤器的方法如下示:

<filter>
      <filter-name>my1</filter-name>
      <filter-class>com.abc.mis.Filter1</filter-class>
      <init-param>
        <param-name>password</param-name>
        <param-value>123</param-value>
      </init-param>
</filter>

容器为一个<filter></filter>元素创建一个过滤器实例,同一个过滤器类可以生成多个实例,此时只需要部署多个<filter></filter>元素,例如:
 <filter>
      <filter-name>my1</filter-name>
      <filter-class>com.abc.mis.Filter1</filter-class>
      <init-param>
        <param-name>password</param-name>
        <param-value>123</param-value>
      </init-param>
</filter>

(2)映射过滤器 
过滤器映射就是定义此过滤器的激活条件,一般是通过目标资源的URI模式和请求的类型来定义。URI中可以使用通配符“*”来表达请求的URI模式。过滤器映射的基本方法如下示: 
<filter-mapping>
      <filter-name>my1</filter-name>
      <url-pattern>/test/*</url-pattern>
      <dispatcher>REQUEST</dispatcher>
      <dispatcher>FORWARD</dispatcher>
</filter-mapping>


三、第一个过滤器程序
过滤器的基本编程过程是: 
第一步:编辑与编译过滤器程序,把编译后得到的包文件夹及*.class类发布到ROOT\WEB-INF\classes文件夹下。 
第二步:编辑WEB-INF\web.xml文件,添加过滤器的部署信息。 
第三步:重启Tomcat或重载Web应用,使过滤器生效。 

【例】:定义三个过滤器:
如果用户访问“/test”下的资源时,过滤器1被激活,它判断用户是否已经登录,如果没有登录则中断请求,并返回404错误信息,如果已经登录则将请求转发给下一个过滤器。
定义过滤器2,当请求“/*”资源并且请求是来自客户端时它才被激活,显示提示信息,然后把请求转发给下一个过滤器。
过滤器3的功能同过滤器2,但它的请求类型为REQUEST或FORWARD。

操作步骤如下:
(1) 启动JC4,新建一个类“Filter1”,在代码编辑窗口中输入如下的代码: 

<span style="font-family:SimSun;"><span style="font-family:FangSong_GB2312;font-size:14px;">package my;

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class Filter1 implements Filter {

  private FilterConfig config = null;

  public void init(FilterConfig config) throws ServletException {
    this.config = config;
  }

  public void destroy() {
    config = null;
  }

  public void doFilter(ServletRequest request, ServletResponse response,
                     FilterChain chain) throws IOException, ServletException 
 {
    response.setCharacterEncoding("GB2312");
    PrintWriter out=response.getWriter();
	HttpSession session=((HttpServletRequest)request).getSession();
	
     System.out.println("过滤器1工作,请求转下一个处理..");
     out.print("<br>请求到达目标资源前过滤器2添加的信息<br>");
     
     String loginStatus=(String)session.getAttribute("loginName");
     if(loginStatus==null)
       {
     	    out.print("<br>你没有登陆,无房访问资源!<br>");
     	    return;
     	  }
     else 
         chain.doFilter(request, response);	 
    
    System.out.println("目标资源输出信息返回到过滤器1...");
    out.print("<br>目标资源输出信息返回时过滤器2添加的信息<br>"); 
    
    
  }
}</span></span>

(2)编译Filter1程序,成功后,Filter1.class文件会被JC4自动存放至c:\tomcat\webapps\ROOT\WEB-INF\classes文件夹下,用“我的电脑”查看并核实。 
(3)启动JC4,新建一个类“Filter2”,在代码编辑窗口中输入如下的代码:

<span style="font-family:SimSun;"><span style="font-family:FangSong_GB2312;font-size:14px;">package my;

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class Filter2 implements Filter {

  private FilterConfig config = null;

  public void init(FilterConfig config) throws ServletException {
    this.config = config;
  }

  public void destroy() {
    config = null;
  }

  public void doFilter(ServletRequest request, ServletResponse response,
                     FilterChain chain) throws IOException, ServletException 
 {
        response.setCharacterEncoding("GB2312");
        PrintWriter out=response.getWriter();
        
        System.out.println("过滤器2工作,请求转下一个处理..");
        out.print("<br>请求到达目标资源前过滤器2添加的信息<br>");
        
        chain.doFilter(request, response);	
        
        </span><pre name="code" class="java"><span style="font-family:FangSong_GB2312;font-size:14px;"> <span style="white-space:pre">	</span>System.out.println("目标资源输出信息返回到过滤器2...");
        out.print("<br>目标资源输出信息返回时过滤器2添加的信息<br>"); </span></span>
}}

(4)编译Filter2程序。 (5)启动JC4,新建一个类 “Filter3”,在代码编辑窗口中输入如下的代码:

<span style="font-family:SimSun;"><span style="font-family:FangSong_GB2312;font-size:14px;">package my;

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

public class Filter3 implements Filter {

  private FilterConfig config = null;

  public void init(FilterConfig config) throws ServletException {
    this.config = config;
  }

  public void destroy() {
    config = null;
  }

  public void doFilter(ServletRequest request, ServletResponse response,
                     FilterChain chain) throws IOException, ServletException 
 {
       </span><pre name="code" class="java"><span style="font-family:FangSong_GB2312;font-size:14px;"><span style="white-space:pre">	</span>System.out.println("过滤器3工作,请求转下一个处理..");
        out.print("<br>请求到达目标资源前过滤器3添加的信息<br>");
        
        chain.doFilter(request, response);	
        
        </span><pre name="code" class="java"><span style="font-family:FangSong_GB2312;font-size:14px;"> <span>	</span>System.out.println("目标资源输出信息返回到过滤器3...");
        out.print("<br>目标资源输出信息返回时过滤器3添加的信息<br>"); </span></span>

}}
(6)编译Filter3程序。 
(7)部署以上三个过滤器,得到一个过滤器链为:过滤器3→过滤器1→过滤器2。
编辑WEB-INF\web.xml文件,添加如下的部署信息:




(8)定义实验用JSP资源。启动DW8,完成以下任务: 
新建exam406.jsp,在设计视图中输入提示文字“当前是/exam406.jsp 资源”。 
新建exam407.jsp,在代码视图中输入以下代码: 
<body>
  <%
     session.setAttribute("loginName","tom");
out.print("成功登录,可以访问/test下的资源了!");
  %>
</body> 

新建exam408.jsp,在设计视图中,将站点中的“ROOT\tomcat.gif”图片插入文档中。 
在站点根文件夹下新建一个/test下级文件夹。
在/test文件夹下建立一个index.jsp文件,在设计视图中输入提示文字“/test的首页”。 
新建exam409.jsp,在代码视图中输入以下代码: 

<body>
<%
    RequestDispatcher go=application.getRequestDispatcher("/exam406.jsp");
go.forward(request,response);
%>
</body> 
(9)启动Tomcat,自行完成测试即可。



Servlet之过滤器Filter详解