1 过滤器概述

  当web容器接收到对一个资源的请求时,它将判断是否有过滤器与这个资源相关联,如果有,那么容器将把这个请求交给过滤器进行处理。在过滤器中,你可以改变请求的内容或者重新设置请求的报头信息,然后再将请求发送给目标资源。当目标资源对请求作出响应时,容器同样会将响应先转发给过滤器,在过滤器中,你可以对响应的内容进行转换,然后再将响应发送给客户端。从此过程中可以看出,客户端和目标资源并不需要知道过滤器的存在,也就是说,在web应用中部署过滤器,对客户端和目标资源是透明的。

  在web应用中,你可以部署多个过滤器,这些过滤器组成过滤器链,过滤器链中的每一个过滤器负责特定的操作和任务,客户端的请求在这些过滤器之间传递,直到目标资源。

  在请求资源时,过滤器链中的过滤器将依次对请求进行处理,并将请求传递给下一个过滤器,直到目标资源,在发送响应时,则按照相反的顺序对响应进行处理,直到客户端。

  如图所示,由多个过滤器组成的过滤器链。

  

  过滤器并不是必须要将请求传递给下一个过滤器(或者目标资源),它也可以自行处理请求,然后发送响应给客户端,或者将请求发送给另外一个目标资源。

  过滤器在web开发的一些主要应用:

  1)对用户请求进行统一认证

  2)对用户的访问请求进行记录和审核

  3)对用户发送的数据进行过滤或者替换

  4)对响应内容进行压缩,减少传输容量

  5)对请求和响应进行加解密处理

  6)触发资源访问事件


2 Filter API

与过滤器开发相关的接口和类都包含在javax.servlet或者javax.servlet.http包中,主要有:

javax.servlet.Filter接口

javax.servlet.FilterConfig接口

javax.servlet.FilterChain接口

javax.servlet.ServletRequestWrapper类

javax.servlet.ServletResponseWrapper类

javax.servlet.http.HttpServletRequestWrapper类

javax.servlet.http.HttpServletResponseWrapper类

1)Filter接口

开发过滤器要实现该接口,并提供一个公共的不带参数的构造方法。

该接口的方法:

public abstract void init(FilterConfig filterconfig)throws ServletException;
  web容器调用该方法初始化过滤器,容器在调用该方法时,向过滤器传递FiterConfig对象,FiterConfig对象的用法和ServletConfig类似。利用FilterConfig对象可以得到ServletContext对象,以及在配置文件配置的过滤器的初始化参数,这个方法可以抛出ServletException异常,通知容器过滤器不能正常工作。

public abstract void doFilter(ServletRequest servletrequest, ServletResponse servletresponse, FilterChain filterchain)throws IOException, ServletException;
  doFilter()方法类似于Servlet中service()方法。当客户端请求目标资源时,容器就会调用与这个目标资源相关联的过滤器的doFilter()方法。在这个方法里,可以对请求和响应进行处理。在实现特定的操作后,可以调用chain.doFilter(request,response)将请求传给下一个过滤器,也可以直接向客户端返回响应,或者利用RequestDispatcher的forward()和include()方法,以及HttpServletResponse的sendRedirect()方法将请求转向其他资源。这个方法的请求和响应参数是ServletRequest ServletResponse ,也就是说,过滤器的使用并不依赖于具体的协议。

public abstract void destroy();

  web容器调用该方法表示过滤器的生命周期结束,在这个方法中,可以释放过滤器使用的资源,

与Servlet不同的是,Filter接口并没有相应的实现类可供继承,要开发过滤器,只能实现Filter接口。

2)FilterConfig接口

类似于ServletConfig接口,用于在过滤器初始化时向其传递信息。FilterConfig接口由容器实现,容器将其实例作为参数传入过滤器对象的init()方法中,在FilterConfig接口中,定义了四个方法:

public abstract String getFilterName();  以字符串形式返回在web.xml中配置的Filter的名字

public abstract ServletContext getServletContext();返回Servlet上下文对象的引用

public abstract String getInitParameter(String s);  返回在web.xml中指定名字为s的初始化参数的值

public abstract Enumeration getInitParameterNames(); 返回过滤器的所有初始化参数名字的枚举集合,如果没有初始化参数,返回一个空的枚举集合。

3)FilterChain接口

该接口由容器实现,容器将其作为参数传入过滤器对象的doFilter()方法中。过滤器对象使用FiterChain对象调用过滤器链中的下一个过滤器。如果此过滤器是链中的最后一个过滤器,那么将调用目标资源。FilterChain接口只有一个方法:

public abstract void doFilter(ServletRequest servletrequest, ServletResponse servletresponse)throws IOException, ServletException;


3 过滤器在web.xml中的配置

在实现一个过滤器后,需要在web.xml进行配置,这是通过<filter>和<filter-mapping>元素来完成的

1)filter元素

<filter>元素用于在web应用程序中声明一个过滤器。<filter>元素的结构为:

其中<description> <display-name> <icon>元素的作用是相同的。

<filter-name>元素用于指定过滤器的名字,该元素的内容不能为空。<filter-class>元素指定过滤器的完整的限定类名。

<init-param>元素用于为过滤器指定初始化参数,它的子元素<param-name>指定参数的名字,<param-value>指定参数的值,在过滤器中可以使用FilterConfig对象获取这些初始化参数

Servlet容器对在web.xml中配置的每一个过滤器,只创建一个实例。与Servlet相似,容器将在同一个过滤器实例上运行多个线程来同时为多个请求服务,因此开发过滤器时,也应该注意线程安全的问题。如果在web.xml中,对同一个过滤器类声明了两次,那么容器会创建两个相同的过滤器类的实例。

2)filter-mapping元素

<filter-mapping>元素用于指定过滤器关联的URL或者Servlet。<filter-mapping>元素的结构:

注意:

  Servlet2.5规范允许<url-pattern>和<servlet-name>元素出现多次,之前的规范只允许一个<filter--mapping>元素包含一个<url-pattern>或者一个<servlet-name>子元素。如:

<filter-mapping>

  <filter-name>DemoFilter</filter-name>

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

  <servlet-name>Servlet1</servlet-name>

  <servlet-name>Servelt2</servlet-name>

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

</filter-mapping>

此外,Servlet2.5规范还允许为<servlet-name>元素指定*号,来匹配所有的Servlet。

<filter-mapping>

  <filter-name>AllDispather</filter-name>

  <servlet-name>*</servlet-name>

  <dispatcher>FORWARD</dispatcher>

</filter-mapping>

<filter-mapping>元素结构解析:

其中<filter-name>子元素的值必须是在<filter>元素中声明过的过滤器的名字。

<url-pattern>元素和<servlet-name>元素可以选择一个,<url-pattern>元素指定过滤关联的URL样式,<servlet-name>元素指定过滤器对应的Servlet。用户在访问<url-pattern>元素指定的URL上的资源或者<servlet-name>元素指定的Servlet时,该过滤器才会被容器调用。

<filter-mapping>还可以包含0到4个<dispatcher>元素,<dispatcher>元素指定过滤器对应的请求方式,可以是REQUEST INCLUDE FORWARD ERROR四种之一或者多种,默认是REQUEST。

REQUEST:当用户直接访问页面时,web容器将会调用过滤器。如果目标资源是通过RequestDispatcher的include()或者forward()方法访问时,那么该过滤器将不会被调用。

INCLUDE:如果目标资源是通过RequestDispatcher的include()方法访问时,那么该过滤器将被调用,除此之外,过滤器不会被调用。

FORWARD:如果目标资源时通过ResquestDispatcher的forward()方法访问时,那么该过滤器将会被调用,除此之外,过滤器不会被调用。

ERROR:如果目标资源是通过声明式异常处理机制调用时,那么该过滤器将被调用。除此之外,过滤器不会被调用。

例如:

1)

<filter-mapping>

  <filter-name>bookFilter</filter-name>

  <url-pattern>/process.jsp</url-pattern>

</filter-mapping>

当用户访问process.jsp时,容器会调用bookFilter过滤器

2)

<filter-mapping>

  <filter-name>bookFilter</filter-name>

  <url-pattern>/index.jsp</url-pattern>

  <dispatcher>REQUEST</dispatcher>

  <dispatcher>FORWARD</dispatcher>

</filter-mapping>

当用户直接访问index.jsp页面时,或者通过RequestDispatcher的forward()方法访问时,容器会调用bookFilter过滤器。


web应用中的Filter过滤器之基础概述的更多相关文章

  1. HBase Filter 过滤器之RowFilter详解

    前言:本文详细介绍了HBase RowFilter过滤器Java&Shell API的使用,并贴出了相关示例代码以供参考.RowFilter 基于行键进行过滤,在工作中涉及到需要通过HBase ...

  2. HBase Filter 过滤器之FamilyFilter详解

    前言:本文详细介绍了 HBase FamilyFilter 过滤器 Java&Shell API 的使用,并贴出了相关示例代码以供参考.FamilyFilter 基于列族进行过滤,在工作中涉及 ...

  3. HBase Filter 过滤器之QualifierFilter详解

    前言:本文详细介绍了 HBase QualifierFilter 过滤器 Java&Shell API 的使用,并贴出了相关示例代码以供参考.QualifierFilter 基于列名进行过滤, ...

  4. HBase Filter 过滤器之 ValueFilter 详解

    前言:本文详细介绍了 HBase ValueFilter 过滤器 Java&Shell API 的使用,并贴出了相关示例代码以供参考.ValueFilter 基于列值进行过滤,在工作中涉及到需 ...

  5. web应用中Filter过滤器之开发应用

    1 过滤器的简单开发应用部署 首先讲解过滤器的开发部署运行基本流程,在这里先通过一个简单的示例: 1)编写过滤器类 编写一个简单的过滤器类:SimpleFilter,实现Filter接口,完整的代码为 ...

  6. [转]web.xml中servlet ,filter ,listener ,interceptor的作用与区别

    原文链接:https://blog.csdn.net/netdevgirl/article/details/51483273 一.概念: 1.servlet:servlet是一种运行服务器端的java ...

  7. Web API中常用Filter的执行顺序举例讲解

    在WEB Api中,引入了面向切面编程(AOP)的思想,在某些特定的位置可以插入特定的Filter进行过程拦截处理.引入了这一机制可以更好地践行DRY(Don’t Repeat Yourself)思想 ...

  8. HBase Filter 过滤器之 Comparator 原理及源码学习

    前言:上篇文章HBase Filter 过滤器概述对HBase过滤器的组成及其家谱进行简单介绍,本篇文章主要对HBase过滤器之比较器作一个补充介绍,也算是HBase Filter学习的必备低阶魂技吧 ...

  9. web,xml中关于filter的使用

    从J2EE1.3开始,Servlet2.3规范中加入了对过滤器的支持.过滤器能够对目标资源的请求和响应进行截取.过滤器的工作方式分为四种,下面让我们分别来看看这四种过滤器的工作方式:1.request ...

随机推荐

  1. Linux学习笔记之Centos7设置Linux静态IP

    ***如下资料源自互联网*** 这里以CentOS 7系列为例设置静态IP,原来RedHat系列的Linux发行版可以通过setup工具方便的设置静态IP,但是在版本7之后setup工具的功能就逐渐减 ...

  2. 20145221 《Java程序设计》课程总结

    20145221 <Java程序设计>课程总结 每周读书笔记链接汇总 Atom使用心得 - 21世纪的编辑器 网络安全攻防学习平台 - 基础关 Java实现:数据结构之排序 2014522 ...

  3. 《Effective Java 2nd》第7章 方法

    目录 第38条 检查参数的有效性 第39条 必要时进行保护性拷贝 第40条 谨慎设计方法签名 第41条 慎用重载 第42条 慎用可变参数 第43条 返回零长度的数组或集合,而不是null 第44条 为 ...

  4. asp.net和.net的区别

    http://zhidao.baidu.com/link?url=BEIkzsJqo-tnOmWKwzsiuXeohqVJzb_iRCZ5gWCozAGVdw2FSnWW95r3vaUAecUnKsW ...

  5. UVa 11582 巨大的斐波那契数!(幂取模)

    https://vjudge.net/problem/UVA-11582 题意: 输入两个非负整数a.b和正整数n,你的任务是计算f(a^b)除以n的余数.f[0]=0,f[1]=1,f[i+2]=f ...

  6. R语言绘制正太分布图,并进行正太分布检验

    正态分布 判断一样本所代表的背景总体与理论正态分布是否没有显著差异的检验.   方法一概率密度曲线比较法 看样本与正太分布概率密度曲线的拟合程度,R代码如下: #画样本概率密度图s-rnorm(100 ...

  7. [java]java String.split()函数的用法分析

    转自:http://swiftlet.net/archives/709 一.在java.lang包中有String.split()方法的原型是: public String[] split(Strin ...

  8. Rails 5 Test Prescriptions 第10章 Unit_Testing JavaScript(新工具,learn曲线太陡峭,pass)

    对Js的单元测试是一个大的题目.作者认为Ruby的相关测试工具比Js的测试工具更灵活 大多数Js代码最终是关于响应用户的行为和改变DOM中的元素 没有什么javascript的知识点.前两节用了几个新 ...

  9. 2-14 MySQL初步认识,及CentOS6.8环境,源码方式安装MySQL

    什么是数据库: 存放数据的仓库RDBMS-->(Relational Database Management System) 关系型数据库管理系统DBMS--->(Database Man ...

  10. sqlplus环境设置

    1.0 --column 命令集                         改变列格式                {                column column_name1 f ...