一、概念

Filter也称之为过滤器,它是Servlet技术中比较激动人心的技术,WEB开发人员通过Filter技术,对web服务器管理的所有web资源:例如Jsp, Servlet, 静态图片文件或静态 html 文件等进行拦截,从而实现一些特殊的功能。例如实现URL级别的权限访问控制、过滤敏感词汇、压缩响应信息等一些高级功能。

二、Filter简介

Servlet API中提供了一个Filter接口,开发web应用时,如果编写的Java类实现了这个接口,则把这个java类称之为过滤器Filter。通过Filter技术,开发人员可以实现用户在访问某个目标资源之前,对访问的请求和响应进行拦截。简单说,就是可以实现web容器对某资源的访问前截获进行相关的处理,还可以在某资源向web容器返回响应前进行截获进行处理。

三、事例

1、新建一个类,实现Filter接口
2、实现doFilter()方法,打印一句话,来证明能够进行拦截
3、在web.xml中进行配置(参照Servlet配置)
4、访问一个页面,看看能不能拦截

Demo1Filter.java

  1. package com.test.filter;
  2. import java.io.IOException;
  3. import javax.servlet.Filter;
  4. import javax.servlet.FilterChain;
  5. import javax.servlet.FilterConfig;
  6. import javax.servlet.ServletException;
  7. import javax.servlet.ServletRequest;
  8. import javax.servlet.ServletResponse;
  9. public class Demo1Filter implements Filter {
  10. private FilterConfig filterConfig;
  11. public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
  12. System.out.println("Demo1过滤前");
  13. System.out.println(filterConfig.getInitParameter("param1"));
  14. chain.doFilter(request, response);//放行。让其走到下个链或目标资源中
  15. System.out.println("Demo1过滤后");
  16. }
  17.  
  18. public void init(FilterConfig filterConfig) throws ServletException {
  19. System.out.println("初始化了");
  20. this.filterConfig = filterConfig;
  21. }
  22.  
  23. public void destroy() {
  24. System.out.println("销毁了");
  25. }
  26. }

web.xml

  1. <filter>
  2. <filter-name>Demo1Filter</filter-name>
  3. <filter-class>com.itheima.filter.Demo1Filter</filter-class>
  4. <init-param>
  5. <param-name>param1</param-name>
  6. <param-value>value在这里呢</param-value>
  7. </init-param>
  8. </filter>
  9. <filter-mapping>
  10. <filter-name>Demo1Filter</filter-name>
  11. <url-pattern>/*</url-pattern>
  12. <dispatcher>REQUEST</dispatcher> <!-- 没有配置dispatcher就是默认request方式的 -->
  13. <dispatcher>FORWARD</dispatcher>
  14. <dispatcher>ERROR</dispatcher>
  15. <dispatcher>INCLUDE</dispatcher>
  16. </filter-mapping>

四、Filter的应用场景

通过对filter过滤器的了解,可以得知在以下三种情况下可以做些处理:

  • 通过控制对chain.doFilter的方法的调用,来决定是否需要访问目标资源。比如,可以在用户权限验证等等。判断用户是否有访问某些资源的权限,有权限放行,没权限不执行chain.doFilter方法。
  • 通过在调用chain.doFilter方法之前,做些处理来达到某些目的。比如,解决中文乱码的问题等等。可以在doFilter方法前,执行设置请求编码与响应的编码。甚至可以对request接口进行封装装饰来处理get请求方式的中文乱码问题(重写相应的request.getParameter方法)。UTF8编码事例如下:
  1. <filter>
  2. <filter-name>encodingFilter</filter-name>
  3. <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
  4. <init-param>
  5. <param-name>encoding</param-name>
  6. <param-value>utf-8</param-value>
  7. </init-param>
  8. </filter>
  9.  
  10. <filter-mapping>
  11. <filter-name>encodingFilter</filter-name>
  12. <url-pattern>/rest/elevenwarning/*</url-pattern>
  13. </filter-mapping>
  14.  
  15. <filter-mapping>
  16. <filter-name>encodingFilter</filter-name>
  17. <url-pattern>/rest/pageconfig/*</url-pattern>
  18. </filter-mapping>
  • 通过在调用chain.doFilter方法之后,做些处理来达到某些目的。比如对整个web网站进行压缩。在调用chain.doFilter方法之前用类A对response对象进行封装装饰,重写getOutputStream和重写getWriter方法。在类A内部中,将输出内容缓存进ByteArrayOutputStream流中,然后在chain.doFilter方法执行后,获取类A中ByteArrayOutputStream流缓存数据,用GZIPOutputStream流进行压缩下。

五、Filter实现拦截的原理

Filter接口中有一个doFilter方法,当开发人员编写好Filter类实现doFilter方法,并配置对哪个web资源进行拦截后,WEB服务器每次在调用web资源的service方法之前(服务器内部对资源的访问机制决定的),都会先调用一下filter的doFilter方法。

六、Filter生命周期

和Servlet一样Filter的创建和销毁也是由WEB服务器负责。不过与Servlet区别的是,它是

  1. 在应用启动的时候就进行装载Filter类(与Servlet的load-on-startup配置效果相同)。
  2. 容器创建好Filter对象实例后,调用init()方法。接着被Web容器保存进应用级的集合容器中去了等待着,用户访问资源。
  3. 当用户访问的资源正好被Filter的url-pattern拦截时,容器会取出Filter类调用doFilter方法,下次或多次访问被拦截的资源时,Web容器会直接取出指定Filter对象实例调用doFilter方法(Filter对象常驻留Web容器了)。
  4. 当应用服务被停止或重新装载了,则会执行Filter的destroy方法,Filter对象销毁。

注意:init方法与destroy方法只会启动一次。

七、Filter部署应用注意事项

  1. filter-mapping标签中servlet-name与url-pattern。

    • Filter不仅可以通过url-pattern来指定拦截哪些url匹配的资源。而且还可以通过servlet-name来指定拦截哪个指定的servlet(专门为某个servlet服务了,servlet-name对应Servlet的相关配置)。
  2. filter-mapping标签中dispatcher。
    • 指定过滤器所拦截的资源被 Servlet 容器调用的方式,可以是REQUEST,INCLUDE,FORWARD和ERROR之一,默认REQUEST。用户可以设置多个<dispatcher> 子元素用来指定 Filter 对资源的多种调用方式进行拦截。

      • REQUEST:当用户直接访问页面时,Web容器将会调用过滤器。如果目标资源是通过RequestDispatcher的include()或forward()方法访问或ERROR情况时,那么该过滤器就不会被调用。
      • INCLUDE:如果目标资源是通过RequestDispatcher的include()方法访问时,那么该过滤器将被调用。除此之外,该过滤器不会被调用。
      • FORWARD:如果目标资源是通过RequestDispatcher的forward()方法访问时,那么该过滤器将被调用,除此之外,该过滤器不会被调用。
      • ERROR:如若在A.jsp页面page指令中指定了error属性=examError.jsp,那么A.jsp中若出现了异常,会跳转到examError.jsp中处理。而在跳转到examError.jsp时,若过滤器配置了ERROR的dispather那么则会拦截,否则不会拦截。

FILTER——JAVA的更多相关文章

  1. lambda -- Filter Java Stream to 1 and only 1 element

    up vote10down votefavorite I am trying to use Java 8 Streams to find elements in a LinkedList. I wan ...

  2. java.lang.ClassNotFoundException: org.springframework.web.filter.CharacterEncodingFilter

    今天在用git merge 新代码后报了如下错误:java.lang.ClassNotFoundException: org.springframework.web.filter.CharacterE ...

  3. 转 Java中Filter、Servlet、Listener的学习

      1.Filter的功能filter功能,它使用户可以改变一个 request和修改一个response. Filter 不是一个servlet,它不能产生一个response,它能够在一个requ ...

  4. Java Spring Boot VS .NetCore (二)实现一个过滤器Filter

    Java Spring Boot VS .NetCore (一)来一个简单的 Hello World Java Spring Boot VS .NetCore (二)实现一个过滤器Filter Jav ...

  5. SpringMVC------报错:java.lang.ClassNotFoundException: org.springframework.web.filter.CharacterEncodingFilter

    详细信息: java.lang.ClassNotFoundException: org.springframework.web.filter.CharacterEncodingFilter 严重: E ...

  6. java.lang.IllegalStateException: class utils.filter.ContentFilter is not a javax.servlet.Filter

    1.错误描写叙述 2016-01-12 11:27:01.787:WARN:oejuc.AbstractLifeCycle:FAILED ContentFilter: java.lang.Illega ...

  7. java web学习总结(三十一) -------------------EL表达式

    一.EL表达式简介 EL 全名为Expression Language.EL主要作用: 1.获取数据 EL表达式主要用于替换JSP页面中的脚本表达式,以从各种类型的web域 中检索java对象.获取数 ...

  8. 20145308刘昊阳 《Java程序设计》第8周学习总结

    20145308刘昊阳 <Java程序设计>第8周学习总结 教材学习内容总结 第15章 通用API 15.1 日志 15.1.1 日志API简介 java.util.loggging包提供 ...

  9. 20145222黄亚奇《Java程序设计》第8周学习总结

    教材学习内容总结 第15章 通用API 1 日志 1 日志API简介 java.util.loggging包提供了日志功能相关类与接口. 使用日志的起点是Logger类,Logger类的构造函数表示为 ...

随机推荐

  1. Android实现对HOME键的捕获和屏蔽

    1.1. 在AndroidManifest.xml中加上权限,禁止HOME键. <uses-permission android:name="android.permission.DI ...

  2. linux dig命令 转

    dig 命令主要用来从 DNS 域名服务器查询主机地址信息. 查询单个域名的 DNS 信息 dig 命令最典型的用法就是查询单个主机的信息. $ dig baidu.com dig 命令默认的输出信息 ...

  3. Android Activity之间切换出现短暂黑屏的处理方法

    转自:http://www.cppblog.com/fwxjj/archive/2013/01/14/197259.html 在默认情况下,Android应用程序启动时,会有一个黑屏的时期,原因是,首 ...

  4. java根据jar包反编译后修改再打包回jar的做法

    1. 得到一个待要修改的jar包 2. 我的环境是windows,然后解压这个jar包,得到一堆class文件,这时候就找到你需要的那个class文件 3. 我首先是使用jd-gui工具看一下这个cl ...

  5. 得到view坐标的各种方法

    这篇文章讲的方法全是再控件可以获取焦点的情况下执行的,如果在oncreat()里面执行,那么得到的都是0 1.getLocationInWindow 这个方法得到的是view相对于当前Activity ...

  6. Material Designer的低版本兼容实现(三)——Color

    在Material Designer中,色彩再一次被摆到了重要的位置上.官方文档中竟然给出了500种配色方案进行选择.就是为了给不同的手机.电视.手表上带来一直的用户体验. 更多用于控制色彩的属性,可 ...

  7. 深入理解多线程(四)—— Moniter的实现原理

    在深入理解多线程(一)——Synchronized的实现原理中介绍过关于Synchronize的实现原理,无论是同步方法还是同步代码块,无论是ACC_SYNCHRONIZED还是monitorente ...

  8. Error: Program type already present: android.arch.lifecycle.LifecycleRegistry$1

    com.firebaseui:firebase-ui-firestore:3.1.0 depends on android.arch.lifecycle:extensions:1.0.0-beta1. ...

  9. 基于DPI(深度报文解析)的应用识别

    一.概述 1.DPI(Deep packet inspection,深度报文解析) 所谓“深度”是和普通的报文分析层次相比较而言的,“普通报文检测”仅分析IP包4 层以下的内容,包括源地址.目的地址. ...

  10. vim的翻页、跳转到某一行功能

    第一种方式 :$ 跳转到最后一行 :1 跳转到第一行 :n 跳转到第n行 第二种方式 shift+g 跳转到最后一行 gg 跳转到第一行 command+上下箭头