一、Filter 的基本工作原理

  • 1、Filter 程序是一个实现了特殊接口的 Java 类,与 Servlet 类似,也是由 Servlet 容器进行调用和执行的。
  • 2、当在 web.xml 注册了一个 Filter 来对某个 Servlet 程序进行拦截处理时,它可以决定是否将请求继续传递给 Servlet 程序,以及对请求和响应消息是否进行修改。
  • 3、当 Servlet 容器开始调用某个 Servlet 程序时,如果发现已经注册了一个 Filter 程序来对该 Servlet 进行拦截,那么容器不再直接调用 Servlet 的 service 方法,而是调用 Filter 的 doFilter 方法,再由 doFilter 方法决定是否去激活 service 方法。
  • 4、但在 Filter.doFilter 方法中不能直接调用 Servlet 的 service 方法,而是调用 FilterChain.doFilter 方法来激活目标 Servlet 的 service 方法,FilterChain 对象时通过 Filter.doFilter 方法的参数传递进来的。
  • 5、只要在 Filter.doFilter 方法中调用 FilterChain.doFilter 方法的语句前后增加某些程序代码,这样就可以在 Servlet 进行响应前后实现某些特殊功能。
  • 6、如果在 Filter.doFilter 方法中没有调用 FilterChain.doFilter 方法,则目标 Servlet 的 service 方法不会被执行,这样通过 Filter 就可以阻止某些非法的访问请求。

二、Filter 链

  • 1、在一个 Web 应用程序中可以注册多个 Filter 程序,每个 Filter 程序都可以对一个或一组 Servlet 程序进行拦截。如果有多个 Filter 程序都可以对某个 Servlet 程序的访问过程进行拦截,当针对该 Servlet 的访问请求到达时,Web 容器将把这多个 Filter 程序组合成一个 Filter 链(也叫过滤器链)。
  • 2、Filter 链中的各个 Filter 的拦截顺序与它们在 web.xml 文件中的映射顺序一致,上一个 Filter.doFilter 方法中调用 FilterChain.doFilter 方法将激活下一个 Filter的doFilter 方法,最后一个 Filter.doFilter 方法中调用的 FilterChain.doFilter 方法将激活目标 Servlet的service 方法。
  • 3、只要 Filter 链中任意一个 Filter 没有调用 FilterChain.doFilter 方法,则目标 Servlet 的 service 方法都不会被执行。

三、Filter 接口

一个 Filter 程序就是一个 Java 类,这个类必须实现 Filter 接口。javax.servlet.Filter 接口中定义了三个方法:init、doFilter、destory。

1、init 方法

  • (1)、在 Web 应用程序启动时,Web 服务器(Web 容器)将根据其 web.xml 文件的配置信息来创建每个注册的 Filter 的实例对象,并将其保存在内存中。
  • (2)、Web 容器创建 Filter 的实例对象后,将立即调用该 Filter 对象的 init 方法。init 方法在 Filter 生命周期中仅被执行一次,Web 容器在调用 init 方法时,会传递一个包含 Filter 的配置和运行环境信息的 FilterConfig 对象。

    public voic init(FilterConfig filterConfig)throwsServletException
    

  • (3)开发人员可以在 init 方法中完成与构造方法类似的初始化功能,要注意的是:如果初始化代码要使用到 FilterConfig 对象,这些代码只能在 init 方法中编写,而不能在构造方法中编写(尚未调用 init 方法,即并没有创建 FilterConfig 对象,要使用它则必然出错)。

2、doFilter 方法

当一个 Filter 对象能够拦截访问请求时,Servlet 容器将调用 Filter 对象的 doFilter 方法。

publicvoid doFilter(ServletRequest request,ServletResponse response,FilterChain chain)throws java.io.IOException.ServletException

其中,参数 request 和 response 为 Web 容器或 Filter 链中上一个 Filter 传递过来的请求和响应对象;参数 chain 为代表当前 Filter 链的对象。

3、destroy 方法

该方法在 Web 容器卸载 Filter 对象之前被调用,也仅执行一次。可以完成与 init 方法相反的功能,释放被该 Filter 对象打开的资源,例如:关闭数据库连接和 IO 流。


四、FilterChain 接口

该接口用于定义一个 Filter 链的对象应该对外提供的方法,这个接口只定义了一个 doFilter 方法。

publicvoid doFilter(ServletRequest request,ServletResponse response)throws java.io.IOException.ServletException

FilterChain 接口的 doFilter 方法用于通知 Web 容器把请求交给 Filter 链中的下一个 Filter 去处理,如果当前调用此方法的 Filter 对象是Filter 链中的最后一个 Filter,那么将把请求交给目标 Servlet 程序去处理。


五、FilterConfig 接口

  • 1、与普通的 Servlet 程序一样,Filter 程序也很可能需要访问 Servlet 容器。Servlet 规范将代表 ServletContext 对象和 Filter 的配置参数信息都封装到一个称为 FilterConfig 的对象中。
  • 2、FilterConfig 接口则用于定义 FilterConfig 对象应该对外提供的方法,以便在 Filter 程序中可以调用这些方法来获取 ServletContext 对象,以及获取在 web.xml 文件中为 Filter 设置的友好名称和初始化参数。
  • 3、FilterConfig接口定义的各个方法:

    • getFilterName 方法,返回 <filter-name> 元素的设置值。

    • getServletContext 方法,返回 FilterConfig 对象中所包装的 ServletContext 对象的引用。

    • getInitParameter 方法,用于返回在 web.xml 文件中为 Filter 所设置的某个名称的初始化的参数值。

    • getInitParameterNames 方法,返回一个 Enumeration 集合对象。


六、Filter 的注册与映射

1、注册 Filter

一个 <filter> 元素用于注册一个 Filter。其中,<filter-name> 元素是必需的,<filter-class> 元素也是必需的,<init-param> 元素是可选的,可以有多个 < init-param> 元素。

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

2、映射 Filter

<filter-mapping> 元素用于设置一个 Filter 所负责拦截的资源。一个 Filter 拦截的资源可以通过两种方式来指定:资源的访问请求路径和 Servlet 名称。

第一种:指定资源的访问路径

<filter-mapping><filter-name>FirstFilter</filter-name><url-pattern>/*</url-pattern>
</filter-mapping>

<url-pattern> 元素中的访问路径的设置方式遵循 Servlet 的 URL 映射规范。

  • /*:表示拦截所有的访问请求。
  • /filter/*:表示拦截 filter 目录下的所有访问请求,如:http://localhost:8888/testFilter_001/filter/xxxxxx 。
  • /test.html:表示拦截根目录下以 test.html 为资源名的访问请求,访问链接只会是:http://localhost:8888/test.html。

第二种:指定 Servlet 的名称

<filter-mapping><filter-name>FirstFilter</filter-name><servlet-name>default></servlet-name><dispatcher>INCLUDE</dispatcher><dispatcher>REQUEST</dispatcher>
</filter-mapping>

(1)、<servlet-name> 元素与 <url-pattern> 元素是二选一的关系,其值是某个 Servlet 在 web.xml 文件中的注册名称。

(2)、<dispatcher> 元素的设置值有 4 种:REQUEST、INCLUDE、FORWARD、ERROR,分别对应 Servlet 容器调用资源的 4 种方式:

  • 通过正常的访问请求调用;

  • 通过 RequestDispatcher.include 方法调用;

  • 通过 RequestDispatcher.forward 方法调用;

  • 作为错误响应资源调用。

如果没有设置 <dispatcher> 子元素,则等效于 REQUEST 的情况。也可以设置多个 <dispatcher> 子元素,用于指定 Filter 对资源的多种调用方式都进行拦截。


七、Filter 程序示例

FitstFilter.java

import java.io.IOException;
import java.io.PrintWriter;
import java.util.Enumeration;
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;public class FirstFilter implements Filter {private FilterConfig filterConfig = null;String paramValue = null;@Overridepublic void init(FilterConfig filterConfig) throws ServletException {this.filterConfig = filterConfig;paramValue = filterConfig.getInitParameter("encoding");}@Overridepublic 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();System.out.println(headerName + ": " + ((HttpServletRequest)request).getHeader(headerName));}System.out.println("end headers-------------------");//在调用目标前写入响应内容response.setContentType("text/html; charset=gb2312");PrintWriter out = response.getWriter();out.println("IP地址为:" + request.getRemoteHost() + "<br>");chain.doFilter(request, response);//在目标返回后写入响应内容out.println("<br>名称为encoding的初始化参数的值为:" + paramValue);out.println("<br>当前Web程序的真实路径为:" + filterConfig.getServletContext().getRealPath("/"));//out.println("<br>修改了test.html文件!");}@Overridepublic void destroy() {this.filterConfig = null;}
}

web.xml

<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>
</filter-mapping>

test.html(位于WebContent路径的filter目录中)

<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
这就是test.html页面的原始内容!
</body>
</html>

访问:http://localhost:8888/testFilter_001/filter/test.html

文章来源:https://my.oschina.net/u/1171518/blog/265467

来源:https://www.runoob.com/w3cnote/filter-filterchain-filterconfig-intro.html

Filter、FilterChain、FilterConfig 介绍相关推荐

  1. Filter,FilterChain,FilterConfig

    实例: package com.zillion.app.filter;import java.io.IOException;import javax.servlet.Filter; import ja ...

  2. java过滤器应用实例_Servlet过滤器Filter的简单介绍(附示例)

    本篇文章给大家带来的内容是关于Servlet过滤器Filter的简单介绍(附示例),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. 特点 1)Filter是依赖于Servlet容器,属 ...

  3. Filter 过滤器的介绍及使用

    Filter过滤器 MySql的语法看这篇就够了,传送地址:MySql必知必会 JSP的使用看这篇就够了,传送地址:JSP必知必会 文章目录 Filter过滤器 一.Filter过滤器的介绍 二.Fi ...

  4. FFmpeg filter的使用介绍

    1. 参考 [1] ffmpeg.org/libavfilter documentation [2] ffmpeg.org/Filters Documentation [3] 北雨南萍/FFmpeg- ...

  5. FFmpeg filter语法使用介绍

    目录 参考 FFmpeg filter简介 filter的使用方法 1. 参考 [1] ffmpeg.org/libavfilter documentation [2] ffmpeg.org/Filt ...

  6. FFmpeg video filter FATE测试过程介绍

    FATE (FFmpeg Automated Testing Environment) 是FFmpeg社区开发的自动化测试框架,支持对FFmpeg API的测试,也支持对FFmpeg内部函数的测试.对 ...

  7. HBase - Filter - 过滤器的介绍以及使用

    博文作者:那伊抹微笑 csdn 博客地址:http://blog.csdn.net/u012185296 1 过滤器 HBase 的基本 API,包括增.删.改.查等. 增.删都是相对简单的操作,与传 ...

  8. 数字信号处理matlab卷积函数conv,filter函数详细介绍三秒钟就看懂。

    %x (n) =sin( pi*n/ 5),-10<= 10 (正弦离散函数) n1=-10:1:10; x1=sin(pi*n1/5); subplot(2,2,1); stem(n1,x1, ...

  9. JavaScript 数组filter方法完整介绍

    数组过滤器方法是 JavaScript 中使用最广泛的方法之一. 它允许我们快速过滤出具有特定条件的数组中的元素. 因此,在本文中,您将了解有关过滤器方法及其各种用例的所有内容. 所以让我们开始吧. ...

最新文章

  1. Spring官方都推荐使用的@Transactional事务,为啥我不建议使用!
  2. xampp for Ubuntu安装.run文件
  3. maven pom java版本_Maven更新POM中的JDK版本(比如更新为JDK1.8)
  4. ITK:重新运行管道不断变化的最大可能的地区
  5. 50款漂亮的免费网页PSD模板下载(第三季)
  6. c++动态联编与静态联编
  7. 产品结构图、功能结构图、信息结构图,区别在这里
  8. vray渲染里服务器信息,vray云服务器渲染部署(vray怎么渲染su)
  9. Linux ubuntu 串口调试工具
  10. 相控阵天线方位角俯仰角matlab画图,理解相控阵天线的方向图
  11. 计算机软件工程常用英语词汇,职业常用英文词汇
  12. 小学计算机画线反思,画线段图解决问题教学反思
  13. .Art域名注册局的行为其实早就引起了众多域名界大佬的强烈不满
  14. 使用Photoshop CS 扣公章
  15. Centos服务器 查看不到IP地址
  16. 经济寒冬影响存储专业人士
  17. MySQL 事件跟踪器 , MySQL 无须重启服务 跟踪 SQL , 也无须配置日志
  18. mysql命令行界面出现问题,MySQL命令行界面中出现字符错误提示的原因及解决方法...
  19. 计算机三级网络技术(一、二章)
  20. appium最全安装指南

热门文章

  1. PHP云软件短信接口,php调用云片网接口发送短信的实现方法
  2. windows 下 mySQL 镜像安装文件下载
  3. HAVE FUN | 源码解析活动最新进展
  4. select2的简单使用
  5. Nandflash的寄存器配置
  6. 2016四川职称计算机时间安排,2016年四川职称计算机考试报名通知
  7. Django项目实践(商城): 六、生产者消费者设计模式
  8. 葡萄城活字格 Web 应用生成平台荣获软博会十佳优秀产品
  9. React 引入vconsole
  10. NSIDC海冰运动产品-速度矢量场图绘制(数据下载和处理--年、季节平均)【python/basemap】