一、Filter简介

  Filter也称之为过滤器,它是Servlet技术中最激动人心的技术,WEB开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp, Servlet, 静态图片文件或静态 html 文件等进行拦截,从而实现一些特殊的功能。例如实现URL级别的权限访问控制、过滤敏感词汇、压缩响应信息等一些高级功能。
  Servlet API中提供了一个Filter接口,开发web应用时,如果编写的Java类实现了这个接口,则把这个java类称之为过滤器Filter。通过Filter技术,开发人员可以实现用户在访问某个目标资源之前,对访问的请求和响应进行拦截,如下所示:

  

二、Filter是如何实现拦截的?

  Filter接口中有一个doFilter方法,当我们编写好Filter,并配置对哪个web资源进行拦截后,WEB服务器每次在调用web资源的service方法之前,都会先调用一下filter的doFilter方法,因此,在该方法内编写代码可达到如下目的:

  1. 调用目标资源之前,让一段代码执行。
  2. 是否调用目标资源(即是否让用户访问web资源)。
  3. 调用目标资源之后,让一段代码执行。

  web服务器在调用doFilter方法时,会传递一个filterChain对象进来,filterChain对象是filter接口中最重要的一个对 象,它也提供了一个doFilter方法,开发人员可以根据需求决定是否调用此方法,调用该方法,则web服务器就会调用web资源的service方 法,即web资源就会被访问,否则web资源不会被访问。

三、Filter开发入门

3.1、Filter开发步骤

  Filter开发分为二个步骤:

  1. 编写java类实现Filter接口,并实现其doFilter方法。
  2. 在 web.xml 文件中使用<filter>和<filter-mapping>元素对编写的filter类进行注册,并设置它所能拦截的资源。

  过滤器范例:

  1. package me.gacl.web.filter;
  2.  
  3. import java.io.IOException;
  4.  
  5. import javax.servlet.Filter;
  6. import javax.servlet.FilterChain;
  7. import javax.servlet.FilterConfig;
  8. import javax.servlet.ServletException;
  9. import javax.servlet.ServletRequest;
  10. import javax.servlet.ServletResponse;
  11.  
  12. /**
  13. * @ClassName: FilterDemo01
  14. * @Description:filter的三种典型应用: 1、可以在filter中根据条件决定是否调用chain.doFilter(request,
  15. * response)方法, 即是否让目标资源执行
  16. * 2、在让目标资源执行之前,可以对request\response作预处理,再让目标资源执行
  17. * 3、在目标资源执行之后,可以捕获目标资源的执行结果,从而实现一些特殊的功能
  18. * @author: 孤傲苍狼
  19. * @date: 2014-8-31 下午10:09:24
  20. */
  21. public class FilterDemo01 implements Filter {
  22.  
  23. @Override
  24. public void init(FilterConfig filterConfig) throws ServletException {
  25. System.out.println("----过滤器初始化----");
  26. }
  27.  
  28. @Override
  29. public void doFilter(ServletRequest request, ServletResponse response,
  30. FilterChain chain) throws IOException, ServletException {
  31.  
  32. // 对request和response进行一些预处理
  33. request.setCharacterEncoding("UTF-8");
  34. response.setCharacterEncoding("UTF-8");
  35. response.setContentType("text/html;charset=UTF-8");
  36.  
  37. System.out.println("FilterDemo01执行前!!!");
  38. chain.doFilter(request, response); // 让目标资源执行,放行
  39. System.out.println("FilterDemo01执行后!!!");
  40. }
  41.  
  42. @Override
  43. public void destroy() {
  44. System.out.println("----过滤器销毁----");
  45. }
  46. }

在web. xml中配置过滤器:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
  5. http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
  6. <display-name></display-name>
  7. <welcome-file-list>
  8. <welcome-file>index.jsp</welcome-file>
  9. </welcome-file-list>
  10.  
  11. <!--配置过滤器 -->
  12. <filter>
  13. <filter-name>FilterDemo01</filter-name>
  14. <filter-class>me.gacl.web.filter.FilterDemo01</filter-class>
  15. </filter>
  16.  
  17. <!--映射过滤器 -->
  18. <filter-mapping>
  19. <filter-name>FilterDemo01</filter-name>
  20. <!--“/*”表示拦截所有的请求 -->
  21. <url-pattern>/*</url-pattern>
  22. </filter-mapping>
  23.  
  24. </web-app>

3.2、Filter链

  在一个web应用中,可以开发编写多个Filter,这些Filter组合起来称之为一个Filter链。
  web服务器根据Filter在web.xml文件中的注册顺序,决定先调用哪个Filter,当第一个Filter的doFilter方法被调用时,web服务器会创建一个代表Filter链的FilterChain对象传递给该方法。在doFilter方法中,开发人员如果调用了FilterChain对象的doFilter方法,则web服务器会检查FilterChain对象中是否还有filter,如果有,则调用第2个filter,如果没有,则调用目标资源。

四、Filter的生命周期

4.1、Filter的创建

  Filter的创建和销毁由WEB服务器负责。 web 应用程序启动时,web 服务器将创建Filter 的实例对象,并调用其init方法,完成对象的初始化功能,从而为后续的用户请求作好拦截的准备工作filter对象只会创建一次,init方法也只会执行一次。通过init方法的参数,可获得代表当前filter配置信息的FilterConfig对象。

4.2、Filter的销毁

  Web容器调用destroy方法销毁Filter。destroy方法在Filter的生命周期中仅执行一次。在destroy方法中,可以释放过滤器使用的资源。

4.3、FilterConfig接口

  用户在配置filter时,可以使用<init-param>为filter配置一些初始化参数,当web容器实例化Filter对象,调用其init方法时,会把封装了filter初始化参数的filterConfig对象传递进来。因此开发人员在编写filter时,通过filterConfig对象的方法,就可获得:
  String getFilterName():得到filter的名称。
  String getInitParameter(String name): 返回在部署描述中指定名称的初始化参数的值。如果不存在返回null.
  Enumeration getInitParameterNames():返回过滤器的所有初始化参数的名字的枚举集合。
  public ServletContext getServletContext():返回Servlet上下文对象的引用。
范例:利用FilterConfig得到filter配置信息

  1. package me.gacl.web.filter;
  2.  
  3. import java.io.IOException;
  4. import java.util.Enumeration;
  5. import javax.servlet.Filter;
  6. import javax.servlet.FilterChain;
  7. import javax.servlet.FilterConfig;
  8. import javax.servlet.ServletException;
  9. import javax.servlet.ServletRequest;
  10. import javax.servlet.ServletResponse;
  11.  
  12. public class FilterDemo02 implements Filter {
  13.  
  14. /*
  15. * 过滤器初始化
  16. *
  17. * @see javax.servlet.Filter#init(javax.servlet.FilterConfig)
  18. */
  19. @Override
  20. public void init(FilterConfig filterConfig) throws ServletException {
  21. System.out.println("----过滤器初始化----");
  22. /**
  23. * <filter> <filter-name>FilterDemo02</filter-name>
  24. * <filter-class>me.gacl.web.filter.FilterDemo02</filter-class>
  25. * <!--配置FilterDemo02过滤器的初始化参数--> <init-param>
  26. * <description>配置FilterDemo02过滤器的初始化参数</description>
  27. * <param-name>name</param-name> <param-value>gacl</param-value>
  28. * </init-param> <init-param>
  29. * <description>配置FilterDemo02过滤器的初始化参数</description>
  30. * <param-name>like</param-name> <param-value>java</param-value>
  31. * </init-param> </filter>
  32. *
  33. * <filter-mapping> <filter-name>FilterDemo02</filter-name>
  34. * <!--“/*”表示拦截所有的请求 --> <url-pattern>/*</url-pattern> </filter-mapping>
  35. */
  36. // 得到过滤器的名字
  37. String filterName = filterConfig.getFilterName();
  38. // 得到在web.xml文件中配置的初始化参数
  39. String initParam1 = filterConfig.getInitParameter("name");
  40. String initParam2 = filterConfig.getInitParameter("like");
  41. // 返回过滤器的所有初始化参数的名字的枚举集合。
  42. Enumeration<String> initParameterNames = filterConfig
  43. .getInitParameterNames();
  44.  
  45. System.out.println(filterName);
  46. System.out.println(initParam1);
  47. System.out.println(initParam2);
  48. while (initParameterNames.hasMoreElements()) {
  49. String paramName = (String) initParameterNames.nextElement();
  50. System.out.println(paramName);
  51. }
  52. }
  53.  
  54. @Override
  55. public void doFilter(ServletRequest request, ServletResponse response,
  56. FilterChain chain) throws IOException, ServletException {
  57. System.out.println("FilterDemo02执行前!!!");
  58. chain.doFilter(request, response); // 让目标资源执行,放行
  59. System.out.println("FilterDemo02执行后!!!");
  60. }
  61.  
  62. @Override
  63. public void destroy() {
  64. System.out.println("----过滤器销毁----");
  65. }
  66. }

五、Filter的部署

  Filter的部署分为两个步骤:

  1、注册Filter

  2、映射Filter

5.1、注册Filter

  开发好Filter之后,需要在web.xml文件中进行注册,这样才能够被web服务器调用

  在web.xml文件中注册Filter范例:

  1. <filter>
  2. <description>FilterDemo02过滤器</description>
  3. <filter-name>FilterDemo02</filter-name>
  4. <filter-class>me.gacl.web.filter.FilterDemo02</filter-class>
  5. <!--配置FilterDemo02过滤器的初始化参数 -->
  6. <init-param>
  7. <description>配置FilterDemo02过滤器的初始化参数</description>
  8. <param-name>name</param-name>
  9. <param-value>gacl</param-value>
  10. </init-param>
  11. <init-param>
  12. <description>配置FilterDemo02过滤器的初始化参数</description>
  13. <param-name>like</param-name>
  14. <param-value>java</param-value>
  15. </init-param>
  16. </filter>

  <description>用于添加描述信息,该元素的内容可为空,<description>可以不配置。

  <filter-name>用于为过滤器指定一个名字,该元素的内容不能为空。
  <filter-class>元素用于指定过滤器的完整的限定类名。
  <init-param>元素用于为过滤器指定初始化参数,它的子元素<param-name>指定参数的名字,<param-value>指定参数的值。在过滤器中,可以使用FilterConfig接口对象来访问初始化参数。如果过滤器不需要指定初始化参数,那么<init-param>元素可以不配置。

5.2、映射Filter

  在web.xml文件中注册了Filter之后,还要在web.xml文件中映射Filter

  1. <!--映射过滤器 -->
  2. <filter-mapping>
  3. <filter-name>FilterDemo02</filter-name>
  4. <!--“/*”表示拦截所有的请求 -->
  5. <url-pattern>/*</url-pattern>
  6. </filter-mapping>

  <filter-mapping>元素用于设置一个 Filter 所负责拦截的资源。一个Filter拦截的资源可通过两种方式来指定:Servlet 名称和资源访问的请求路径
  <filter-name>子元素用于设置filter的注册名称。该值必须是在<filter>元素中声明过的过滤器的名字
  <url-pattern>设置 filter 所拦截的请求路径(过滤器关联的URL样式)
  <servlet-name>指定过滤器所拦截的Servlet名称。
  <dispatcher>指定过滤器所拦截的资源被 Servlet 容器调用的方式,可以是REQUEST,INCLUDE,FORWARD和ERROR之一,默认REQUEST。用户可以设置多个<dispatcher> 子元素用来指定 Filter 对资源的多种调用方式进行拦截。如下:

  1. <filter-mapping>
  2. <filter-name>testFilter</filter-name>
  3. <url-pattern>/index.jsp</url-pattern>
  4. <dispatcher>REQUEST</dispatcher>
  5. <dispatcher>FORWARD</dispatcher>
  6. </filter-mapping>

  <dispatcher> 子元素可以设置的值及其意义:

  1. REQUEST:当用户直接访问页面时,Web容器将会调用过滤器。如果目标资源是通过RequestDispatcher的include()或forward()方法访问时,那么该过滤器就不会被调用。
  2. INCLUDE:如果目标资源是通过RequestDispatcher的include()方法访问时,那么该过滤器将被调用。除此之外,该过滤器不会被调用。
  3. FORWARD:如果目标资源是通过RequestDispatcher的forward()方法访问时,那么该过滤器将被调用,除此之外,该过滤器不会被调用。
  4. ERROR:如果目标资源是通过声明式异常处理机制调用时,那么该过滤器将被调用。除此之外,过滤器不会被调用。

原文地址:http://www.cnblogs.com/xdp-gacl/p/3948353.html

Filter(过滤器)学习的更多相关文章

  1. Filter过滤器学习

    一.Filter简介 Filter也称之为过滤器,它是Servlet技术中最激动人心的技术,WEB开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp, Servlet, 静态 ...

  2. javaweb学习总结(四十二)——Filter(过滤器)学习

    一.Filter简介 Filter也称之为过滤器,它是Servlet技术中最激动人心的技术,WEB开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp, Servlet, 静态 ...

  3. javaWeb学习总结(10)- Filter(过滤器)学习

    一.Filter简介 Filter也称之为过滤器,它是Servlet技术中最激动人心的技术,WEB开发人员通过Filter技术,对web服务器管理的所有 web资源:例如Jsp, Servlet, 静 ...

  4. javaWeb学习总结(10)- Filter(过滤器)学习(2)

    在filter中可以得到代表用户请求和响应的request.response对象,因此在编程中可以使用Decorator(装饰器)模式对request.response对象进行包装,再把包装对象传给目 ...

  5. Servlet的学习之Filter过滤器技术(1)

    本篇将讲诉Servlet中一项非常重要的技术,Filter过滤器技术.通过过滤器,可以对来自客户端的请求进行拦截,进行预处理或者对最终响应给客户端的数据进行处理后再输出. 要想使用Filter过滤器, ...

  6. [转]Servlet的学习之Filter过滤器技术

    本篇将讲诉Servlet中一项非常重要的技术,Filter过滤器技术.通过过滤器,可以对来自客户端的请求进行拦截,进行预处理或者对最终响应给客户端的数据进行处理后再输出. 要想使用Filter过滤器, ...

  7. angularjs学习第三天笔记(过滤器第二篇---filter过滤器及其自定义过滤器)

    您好,我是一名后端开发工程师,由于工作需要,现在系统的从0开始学习前端js框架之angular,每天把学习的一些心得分享出来,如果有什么说的不对的地方,请多多指正,多多包涵我这个前端菜鸟,欢迎大家的点 ...

  8. SpringBoot+Shiro学习(七):Filter过滤器管理

    SpringBoot+Shiro学习(七):Filter过滤器管理 Hiwayz 关注  0.5 2018.09.06 19:09* 字数 1070 阅读 5922评论 1喜欢 20 先从我们写的一个 ...

  9. JavaWeb学习篇--Filter过滤器

    Filter过滤器简介 ServletAPI中提供了一个Filter接口,开发web应用时,如果编写的 java 类实现了这个接口,则把这个java类称之为过滤器Filter. WEB服务器每次在调用 ...

随机推荐

  1. 【iOS】在Swift中使用JSONModel

    前言 首先所有的Model还是使用oc来写——看到这一句是不是想关网页了- - #,在swift里面直接写一直报错所以就将就用oc来写了,这里主要是分享一下搭配Alamofire使用的经验. 声明 欢 ...

  2. Starling中通过PivotX 和 PivotY 修改原点

    一个显示对象的默认原点在左上角.addChild 是将它的左上角放在了父容器的(0, 0)位置. 如果将该显示对象的PivotX 和 PivotY 修改为其宽高的一半,那么它的原点就变到了该对象的中心 ...

  3. iframe大小自适应

    前几天,舍友去某互联网公司面前端研发工程师.回来后,他就跟我们聊了下面试官给他出的题.其中,有一道题是“如何实现iframe高度的自适应?”.好吧,我承认,我听到iframe这个词的第一反应就是:这个 ...

  4. 用EF访问Centos下的MySQL

    环境 : MySQL 5.6.21 64位 CentOS 6.5 64位 VMware 10 Navicat for MySQL 11 VS2013 1.首先搭建centos 的MySQL开发环境 : ...

  5. SQLServer 日期函数大全

    一.统计语句 1.--统计当前[>当天00点以后的数据] ) ) ORDER BY dateandtime DESC 2.--统计本周 3.--统计本月 4.统计当前 SELECT * FROM ...

  6. 1. 什么是Docker?

    ##### 一.什么是Dokcer?> Docker是一个开源项目, 诞生于2013年初, 最初是dotCloud公司内部的一个业余项目. 它基于Google公司推出的Go语言实现. 项目后来加 ...

  7. ANDROID STDUIO 项目里的R文件突然丢失的解决办法N种之一

    刚刚项目里的R文件突然挂了,清理项目,关闭重开Studio,都不能解决.快没折了. 然后只好在项目上右击,看看有没有解决的办法.发现有个 Make Module ,姑且试试吧. 结果,竟然修复了.这是 ...

  8. jackson annotations注解详解

    jackson中常用到的注解 猛击下面的连接地址 http://blog.csdn.net/sdyy321/article/details/40298081

  9. log4j2 不使用配置文件,动态生成logger对象

    大家平时使用Log4j一般都是在classpath下放置一个log4j的配置文件,比如log4j.xml,里面配置好Appenders和Loggers,但是前一阵想做某需求的时候,想要的效果是每一个任 ...

  10. linux 搜索相关命令(2)

    文件搜索相关命令 1:locate命令 需要 yum install mlocate locate 文件名 在后台数据库中按文件名搜索,搜索速度更快 /var/lib/mlocate #locate命 ...