Filter入门

 

Filter基本工作原理:

Filter程序是一个实现了javax.servlet.Filter接口的java类,由Servlet容器进行调用和执行,需要在web.xml中进行注册和设置他所能拦截的资源。当在web.xml中注册了一个Filter来对某个Servlet程序进行拦截时,他可以对Servlet容器发送给Servlet程序的请求和Servlet程序返回给Servlet容器的响应进行拦截,可以决定是否将请求继续传递给Servlet程序以及是否对请求和相应消息进行修改。当Servlet容器开始调用某个Servlet程序时,如果发现已经注册了一个Filter程序对其进行拦截,那么Servlet容器不再直接调用Servlet程序的service方法,而是调用Filter.doFilter方法,再由doFilter方法决定是否调用Servlet程序的service方法

Filter链:

在一个web应用程序中可以有多个Filter程序,每个Filter程序可以对一个或一组Servlet程序进行拦截。如果有多个Filter程序对同一个Servlet程序进行拦截,当对该Servlet程序的请求到达时,web容器将多个Filter程序组成一个Filter链。Filter程序对Servlet的拦截顺序与其在web.xml中的映射顺序一致,上一个Filter程序的doFilter方法中的FilterChain.doFilter方法将激活下一个Filter程序的doFilter方法,最后一个FilterdoFIlter方法中的FilterChain.doFilter方法将激活目标Servletservice方法

Filter接口:

三个方法:init(),doFilter(),destroy()

web应用程序启动时,web服务器讲个据web.xml文件的配置信息来创建每个注册的Filter实例对象,并将其保存在内存中。Web应用程序创建Filter实例对象后将立即调用init()方法,即tomcat启动完毕后就已经调用了init()方法。当一个Filter对象能够拦截的请求到达后,Servlet容器将调用Filter对象的doFilter()方法。在当前的Filter对象的doFilter()方法内部需要调用FilterChain对象的doFilter()方法将请求交给Filter链中的下一个Filter或者目标Servlet程序。只有Filter对象的init()方法成功执行后,Filter对象才会被加入到Filter链中,该Filter对象才会被调用。

Filter的注册和运行:

Filter的注册于Servlet的注册基本一样,只是将Servlet换成filter就可以了,如下所示:

<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的映射,在web.xml文件中,使用<filter-mapping>元素设置一个filter所负责拦截的资源,一个filter拦截的资源可以通过两种方式来指定:Servlet的名称和资源的访问路径。

利用Servlet名称设置的方式如下:

<filter-mapping>

         <filter-name>firstFilter</filter-name>

         <servlet-name>default</servlet-name>

</filter-mapping>

<servlet-name>是某个Servletweb.xml中注册的友好名称。

利用资源的访问路径设置的方式如下:

<filter-mapping>

         <filter-name>firstFilter</filter-name>

         <url-pattern>/test.html</url-pattern>

</filter-mapping>

<url-pattern>指明当以这样一种访问路径访问资源时会使用filter

 

我们知道,Servlet容器调用一个资源时有4中方式,分别是:

1.      通过正常的访问请求调用。

2.      通过RequestDispatcher.include方法调用

3.      通过RequestDispatcher.forward方法调用

4.      作为错误响应资源调用

相应的,可以设置filter,决定资源在以什么方式被调用时才进行拦截,这可以通过<dispatcher>元素指明,<dispatcher>元素只能取四个值,REQUEST,INCLUDE,FORWARD,ERROR分别对应之前说到的四种调用方式。在一个<filter-mapping>元素中可以设置多个<dispatche>子元素,用来指定filter对多种调用方式的拦截。例如:

<filter-mapping>

                  <filter-name>firstFilter</filter-name>

                  <url-pattern>/*</url-pattern>

                  <dispatcher>INCLUDE</dispatcher>

</filter-mapping>

 

在同一个web.xml中可以为同一个Filter设置多个映射,如果设置的多个映射都可以对某个资源进行拦截,那么这些Filter将构成一个针对该资源的Filter链,web容器按照如下的顺序构造Filter链:

1. 将通过<url-pattern>元素匹配的Filter加入到链中,如果有多个,按照它们在web.xml中的顺序依次加入。

2. 将通过<servlet-name>元素匹配的Filter加入到链中,如果有多个,按照它们在web.xml中的顺序依次加入。

如果为同一个Filter设置的多个<filter-mapping>元素都可以对某一资源进行拦截,那么所形成的Filter链中将多次出现同一个Filter,也就是说,该FilterdoFilter()方法将被调用多次,但是,该Filterinit()只被调用一次。

 

 

 

 

例子程序

Filter程序:

import java.io.IOException;

import javax.servlet.Filter;

import javax.servlet.FilterChain;

import javax.servlet.FilterConfig;

import javax.servlet.ServletContext;

import javax.servlet.ServletException;

import javax.servlet.ServletRequest;

import javax.servlet.ServletResponse;

import java.util.Enumeration;

import javax.servlet.http.HttpServletRequest;

import java.io.PrintWriter;

 

public class FirstFilter implements Filter

{

 

    private FilterConfig filterConfig = null;

    private String paramValue=null;

   

    public void init(FilterConfig filterConfig) throws ServletException

    {

             this.filterConfig=filterConfig;

             paramValue=filterConfig.getInitParameter("encoding");

             System.out.println("----------------init");

    }

 

    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();

                     String value=((HttpServletRequest)request).getHeader(headerName);

                     System.out.println(headerName+":"+value);

             }

             System.out.println("End Headers---------------------------");

            

             //在调用Servlet前写入response中的内容

             response.setCharacterEncoding("gb2312");

             response.setContentType("text/html");

             PrintWriter out=response.getWriter();

             String ip=request.getRemoteHost();

             out.println("您的IP地址为:"+ip+"<br>");

            

      chain.doFilter(request, response);

     

      //Servlet返回后写入response中的内容

      out.println("<br>名称为encoding的初始化参数的值为:"+paramValue+"<br>");

      out.println("当前web应用程序的真实路径为:"+filterConfig.getServletContext().getRealPath("/")+"<br>");

      out.println(filterConfig.getServletContext()/*.getServletContextName()+"<br>"*/);

                  }

                 

    public void destroy()

    {

        this.filterConfig = null;

    }

 

}

 

Web.xml文件:

<?xml version="1.0" encoding="UTF-8"?>

<web-app version="2.4" xmlns=" http://java.sun.com/xml/ns/j2ee"

         xmlns:xsi=" http://www.w3.org/2001/XMLSchema-instance"

         xsi:schemaLocation=" http://java.sun.com/xml/ns/j2ee

          http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

 

         <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>

                  <dispatcher>INCLUDE</dispatcher>

         </filter-mapping>

        

         <filter-mapping>

                  <filter-name>firstFilter</filter-name>

                  <url-pattern>/test.html</url-pattern>

         </filter-mapping>

        

         <filter-mapping>

                  <filter-name>firstFilter</filter-name>

                  <servlet-name>default</servlet-name>

         </filter-mapping>

        

</web-app>

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值