官方给出的Filter的定义是在请求一个资源或者从一个资源返回信息的时候执行过滤操作的插件。我们使用过滤起最多的场景估计就是在请求和返回时候的字符集转换,或者权限控制,比如一个用户没有登录不能请求某些资源。下面看一下Filter的集中类型:

  • Authentication Filters
  • Logging and Auditing Filters
  • Image conversion Filters
  • Data compression Filters
  • Encryption Filters
  • Tokenizing Filters
  • Filters that trigger resource access events
  • XSL/T filters
  • Mime-type chain Filter

Filters是在web.xml中配置的插件,Servlets和Filters相互没有依赖,如果通过编辑web.xml来添加和删除过滤器。

   实现过滤器非常简单,只需要实现javax.servlet.Filter接口,就可以实现一个过滤器,Filter接口定义的方法如下:

  • void init(FilterConfig filterConfig))--在filter被加载到service中的时候被container调用,Servlet container实例化完filter以后立即调用Filter的init方法,init方法中的工作必须在执行过滤过滤任务之前正确的完成。

    在以下情况下web container不能把filter加载到service中:

    • 抛出ServletException异常。
    • 在container定义的时间内没有返回。
  • void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)--Filter中的doFilter方法在每次request/response时候会被container调用,能够传递到doFilter中的request或者response可以传递到Filter环中的下一个环节。 此时的Filter在设计模式中被称作责任链模式结构,这里面抽象处理者的角色就是javax.servlet.Filter这个接口,注册的所有Filter是具体的处理者,在doFilter方法中实现具体处理逻辑,在这里面责任链是一条直线,构成这条直线的就是所有注册的Filter。
  • destroy--当filter从service中移除的时候,container调用destroy方法,通过调用这个方法,释放Filter所占有的系统资源。

如何在web.xml中配置Filter

1 <filter>
2 <display-name>EcodingFilter</display-name>
3 <filter-name>EcodingFilter</filter-name>
4 <filter-class>org.nb.filter.EnCodeFilter</filter-class>
5 <init-param>
6 <param-name>EncodeCoding</param-name>
7 <param-value>UTF-8</param-value>
8 </init-param>
9 </filter>

我们可以使用如下方法来给Filter匹配指定的servlet 资源或者url-pattern:

1 <filter-mapping>
2 <filter-name>EcodingFilter</filter-name>
3 <servlet-name>*</servlet-name>
4 <url-pattern>*</url-pattern>
5 </filter-mapping>

在这里需要注意的是,在给servlet注册filter环,container首先处理的是url-patterns,然后才处理servlet-names,所以如果要对filter的执行顺序有要求,那么在此需要注意。下面我们创建一个web工程,来实践一下Filter:

web.xml内容:

 1 <?xml version="1.0" encoding="UTF-8"?>
2 <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3 xmlns="http://java.sun.com/xml/ns/javaee"
4 xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
5 version="3.0">
6 <display-name>FilterTest</display-name>
7 <welcome-file-list>
8 <welcome-file>index.html</welcome-file>
9 </welcome-file-list>
10 <filter>
11 <display-name>EcodingFilter</display-name>
12 <filter-name>EcodingFilter</filter-name>
13 <filter-class>org.nb.filter.EnCodeFilter</filter-class>
14 <init-param>
15 <param-name>EncodeCoding</param-name>
16 <param-value>UTF-8</param-value>
17 </init-param>
18 </filter>
19 <filter-mapping>
20 <filter-name>EcodingFilter</filter-name>
21 <servlet-name>hello</servlet-name>
22 <url-pattern>*</url-pattern>
23 </filter-mapping>
24 <servlet>
25 <servlet-name>hello</servlet-name>
26 <servlet-class></servlet-class>
27 </servlet>
28 <servlet-mapping>
29 <servlet-name>hello</servlet-name>
30 <url-pattern>/*</url-pattern>
31 </servlet-mapping>
32 </web-app>

HelloServlet.java内容:

 1 package org.nb.action;
2
3 import java.io.IOException;
4 import java.io.PrintWriter;
5
6 import javax.servlet.ServletException;
7 import javax.servlet.annotation.WebServlet;
8 import javax.servlet.http.HttpServlet;
9 import javax.servlet.http.HttpServletRequest;
10 import javax.servlet.http.HttpServletResponse;
11
12 @WebServlet("/helloServlet")
13 public class HelloServlet extends HttpServlet {
14 private static final long serialVersionUID = 1L;
15
16 protected void doPost(HttpServletRequest request,
17 HttpServletResponse response) throws ServletException, IOException {
18 PrintWriter out = response.getWriter();
19 out.println("<font color=red>Hello.</font>");
20 }
21 }

EnCodeFilter.xm内容:

 1 package org.nb.filter;
2
3 import java.io.IOException;
4 import java.util.Enumeration;
5 import java.util.HashMap;
6 import java.util.Map;
7
8 import javax.servlet.Filter;
9 import javax.servlet.FilterChain;
10 import javax.servlet.FilterConfig;
11 import javax.servlet.ServletException;
12 import javax.servlet.ServletRequest;
13 import javax.servlet.ServletResponse;
14
15 public class EnCodeFilter implements Filter {
16
17 Map<String, String> params = new HashMap<String, String>();
18
19 @Override
20 public void destroy() {
21 System.out.println("EncodeFilter destroy");
22 }
23
24 @Override
25 public void doFilter(ServletRequest request, ServletResponse response,
26 FilterChain chain) throws IOException, ServletException {
27 String encodeCoding = params.get("EncodeCoding");
28 request.setCharacterEncoding(encodeCoding);
29 response.setCharacterEncoding(encodeCoding);
30 chain.doFilter(request, response);
31 System.out.println("EncodeFilter doFilter");
32 }
33
34 @Override
35 public void init(FilterConfig cfg) throws ServletException {
36 Enumeration<String> names = cfg.getInitParameterNames();
37 while (names.hasMoreElements()) {
38 String name = names.nextElement();
39 params.put(name, cfg.getInitParameter(name));
40 }
41 System.out.println("EncodeFilter init");
42 }
43
44 }

在tomcat启动的时候Console输出的内容:

三月 24, 2014 5:56:12 下午 org.apache.catalina.core.AprLifecycleListener init
信息: The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: E:\Program Files\Java\jre7\bin;C:\Windows\Sun\Java\bin;C:\Windows\system32;C:\Windows;C:\Program Files (x86)\M1 Licensing;C:\Program Files\Broadcom\Broadcom 802.11 Network Adapter\Driver;C:\Program Files (x86)\NVIDIA Corporation\PhysX\Common;C:\PROGRAM FILES (X86)\INTEL\ICLS CLIENT\;C:\PROGRAM FILES\INTEL\ICLS CLIENT\;C:\Windows\SYSTEM32;C:\Windows;C:\Windows\SYSTEM32\WBEM;C:\Windows\SYSTEM32\WINDOWSPOWERSHELL\V1.0\;C:\PROGRAM FILES (X86)\INTEL\OPENCL SDK\2.0\BIN\X86;C:\PROGRAM FILES (X86)\INTEL\OPENCL SDK\2.0\BIN\X64;C:\PROGRAM FILES\INTEL\INTEL(R) MANAGEMENT ENGINE COMPONENTS\DAL;C:\PROGRAM FILES\INTEL\INTEL(R) MANAGEMENT ENGINE COMPONENTS\IPT;C:\PROGRAM FILES (X86)\INTEL\INTEL(R) MANAGEMENT ENGINE COMPONENTS\DAL;C:\PROGRAM FILES (X86)\INTEL\INTEL(R) MANAGEMENT ENGINE COMPONENTS\IPT;C:\PROGRAM FILES (X86)\LENOVO\ACCESS CONNECTIONS\;C:\Program Files\WIDCOMM\Bluetooth Software\;C:\Program Files\WIDCOMM\Bluetooth Software\syswow64;C:\Program Files (x86)\Intel\OpenCL SDK\3.0\bin\x86;C:\Program Files (x86)\Intel\OpenCL SDK\3.0\bin\x64;E:\Ruby200\bin;E:\Program Files\TortoiseSVN\bin;E:\Program Files\MySQL\MySQL Utilities 1.3.4\;C:\Program Files\Microsoft\Web Platform Installer\;C:\Program Files (x86)\Microsoft ASP.NET\ASP.NET Web Pages\v1.0\;C:\Program Files (x86)\Windows Kits\8.0\Windows Performance Toolkit\;C:\Program Files\Microsoft SQL Server\110\Tools\Binn\;E:\Program Files\Java\jdk1.7.0_40\bin;C:\Program Files (x86)\Microsoft SQL Server\100\Tools\Binn\;C:\Program Files\Microsoft SQL Server\100\Tools\Binn\;C:\Program Files\Microsoft SQL Server\100\DTS\Binn\;F:\instantclient;.;;.;;.
三月 24, 2014 5:56:12 下午 org.apache.tomcat.util.digester.SetPropertiesRule begin
警告: [SetPropertiesRule]{Server/Service/Engine/Host/Context} Setting property 'source' to 'org.eclipse.jst.jee.server:FilterTest' did not find a matching property.
三月 24, 2014 5:56:13 下午 org.apache.coyote.AbstractProtocolHandler init
信息: Initializing ProtocolHandler ["http-bio-8080"]
三月 24, 2014 5:56:13 下午 org.apache.coyote.AbstractProtocolHandler init
信息: Initializing ProtocolHandler ["ajp-bio-8009"]
三月 24, 2014 5:56:13 下午 org.apache.catalina.startup.Catalina load
信息: Initialization processed in 1031 ms
三月 24, 2014 5:56:13 下午 org.apache.catalina.core.StandardService startInternal
信息: Starting service Catalina
三月 24, 2014 5:56:13 下午 org.apache.catalina.core.StandardEngine startInternal
信息: Starting Servlet Engine: Apache Tomcat/7.0.8
EncodeFilter init

三月 24, 2014 5:56:13 下午 org.apache.catalina.startup.HostConfig deployDirectory
信息: Deploying web application directory docs
三月 24, 2014 5:56:13 下午 org.apache.catalina.startup.HostConfig deployDirectory
信息: Deploying web application directory examples
三月 24, 2014 5:56:13 下午 org.apache.catalina.core.ApplicationContext log
信息: ContextListener: contextInitialized()
三月 24, 2014 5:56:13 下午 org.apache.catalina.core.ApplicationContext log
信息: SessionListener: contextInitialized()
三月 24, 2014 5:56:13 下午 org.apache.catalina.startup.HostConfig deployDirectory
信息: Deploying web application directory host-manager
三月 24, 2014 5:56:13 下午 org.apache.catalina.startup.HostConfig deployDirectory
信息: Deploying web application directory manager
三月 24, 2014 5:56:14 下午 org.apache.catalina.startup.HostConfig deployDirectory
信息: Deploying web application directory ROOT
三月 24, 2014 5:56:14 下午 org.apache.coyote.AbstractProtocolHandler start
信息: Starting ProtocolHandler ["http-bio-8080"]
三月 24, 2014 5:56:14 下午 org.apache.coyote.AbstractProtocolHandler start
信息: Starting ProtocolHandler ["ajp-bio-8009"]
三月 24, 2014 5:56:14 下午 org.apache.catalina.startup.Catalina start
信息: Server startup in 978 ms

其中有filter,init方法的输出,下面创建一个index.html文件,内容如下:

 1 <!DOCTYPE html>
2 <html>
3 <head>
4 <meta charset="UTF-8">
5 <title>Insert title here</title>
6 </head>
7 <body>
8 <form action="http://localhost:8080/FilterTest/helloServlet" method="post">
9 <input type="submit" value="Login">
10 </form>
11 </body>
12 </html>

点击index.html页面的按钮,

此时Console输出内容:

1 EncodeFilter doFilter

每次请求都会有这样一条输出。

关闭tomcat的时候,注意观察Console输出的内容:

三月 24, 2014 6:08:33 下午 org.apache.catalina.core.StandardServer await
信息: A valid shutdown command was received via the shutdown port. Stopping the Server instance.
三月 24, 2014 6:08:33 下午 org.apache.coyote.AbstractProtocolHandler pause
信息: Pausing ProtocolHandler ["http-bio-8080"]
三月 24, 2014 6:08:34 下午 org.apache.coyote.AbstractProtocolHandler pause
信息: Pausing ProtocolHandler ["ajp-bio-8009"]
三月 24, 2014 6:08:35 下午 org.apache.catalina.core.StandardService stopInternal
信息: Stopping service Catalina
EncodeFilter destroy
三月 24, 2014 6:08:36 下午 org.apache.catalina.core.ApplicationContext log
信息: SessionListener: contextDestroyed()
三月 24, 2014 6:08:36 下午 org.apache.catalina.core.ApplicationContext log
信息: ContextListener: contextDestroyed()
三月 24, 2014 6:08:37 下午 org.apache.coyote.AbstractProtocolHandler stop
信息: Stopping ProtocolHandler ["http-bio-8080"]
三月 24, 2014 6:08:37 下午 org.apache.coyote.AbstractProtocolHandler stop
信息: Stopping ProtocolHandler ["ajp-bio-8009"]

此时Fileter的Destroy方法被调用。Filter的生命周期结束。这篇文章中包含一些信息,如Server,Service,Container等,可能有些人跟我一样开始的时候对此很不了解,如果这样大家可以查一下Tomcat等web容器的工作原理,如果有什么地方我说的不清楚,或者有错误,那么请提醒我,谢谢。

参考:http://www.journaldev.com/1933/java-servlet-filter-example-tutorial

Introduction of filter in servlet的更多相关文章

  1. springboot之filter/listener/servlet

    简介 SpringBoot可以简化开发流程,但是在其中如何使用传统的J2EE servlet/listener/filter呢 @Bean配置 在Configuration类中加入filter和ser ...

  2. Filter and servlet

    filter与servlet的区别与联系呢? 1. Filter    实现javax.servlet.Filter接口,在web.xml中配置与标签指定使用哪个Filter实现类过滤哪些URL链接. ...

  3. Filter与Servlet的区别与联系

    Filter与Servlet的区别与联系 转自 http://blog.csdn.net/gaibian0823/article/details/51027495 在我们写代码时,在web.xml中总 ...

  4. Spring 管理Filter和Servlet

    本文转载自:http://www.open-open.com/lib/view/open1417248512252.html 在使用spring容器的web应用中,业务对象间的依赖关系都可以用cont ...

  5. weblogic中配置自定义filter和servlet

    情景:最近公司产品要接入其它厂商的单点服务器,本来我是在Tomcat上进行测试,使用的是spring boot 的注解方式@webFilter和@webServlet注解写过滤器和servlet类,启 ...

  6. web容器调用Filter和Servlet顺序学习

    web容器调用Filter和Servlet顺序学习    一直对Filter和Servlet在哪里被web容器调用迷惑,后查看tomcat源码,揭开了其面纱.1. 下面是一个简单的时序图: 2. 对上 ...

  7. filter与servlet的比较

    filter与servlet的比较   主要从如下四个方面介绍他们之间的区别:                1.概念.                2.生命周期.                3 ...

  8. Spring管理Filter和Servlet(在servlet中注入spring容器中的bean)

    在使用spring容器的web应用中,业务对象间的依赖关系都可以用context.xml文件来配置,并且由spring容器来负责依赖对象 的创建.如果要在servlet中使用spring容器管理业务对 ...

  9. A filter or servlet of the current chain does not support asynchronous operations. 错误解决记录

    做视频文件上传一直报这个错误: java.lang.IllegalStateException: A filter or servlet of the current chain does not s ...

随机推荐

  1. java的一些基本概念——java11、jdk、jre、jvm等

    Java字节码 先介绍下c语言的编译过程,写好代码用编译器(比如gcc)编译过后是机器能够直接执行的二进制机器码. java也类似这种情况,但是java代码文件编译过后不是任何机器都能识别的机器码,而 ...

  2. tp剩余未验证内容-6

    杂项 系统中的电感线圈元件, 虽然不消耗电能, 但是会 占用系统的容量(相当于占用资源但是不做事), 会使系统 的发电量的使用效率降低, 线路损耗增大, 发出同样有功用电量所需的设备容量扩大 将感性元 ...

  3. Java问题解决:The project cannot be built until build path errors are resolved

    参考:http://blog.csdn.net/marty_zhu/article/details/2566299 1,看看project -- Build Automatically有没有勾上?如果 ...

  4. SpringBoot 配置阿里巴巴Druid连接池

    在Spring Boot下默认提供了若干种可用的连接池(dbcp,dbcp2, tomcat, hikari),当然并不支持Druid,Druid来自于阿里系的一个开源连接池,它提供了非常优秀的监控功 ...

  5. css新单位vw,vh在响应式设计中的应用

    考虑到未来响应式设计的开发,如果你需要,浏览器的高度也可以基于百分比值调整.但使用基于百分比值并不总是相对于浏览器窗口的大小定义的最佳方式,比如字体大小不会随着你窗口改变而改变,如今css3引入的新单 ...

  6. pc远程控制凭证不工作的解决办法

    感谢这位博主写的文章https://blog.csdn.net/u010433704/article/details/50679874 前提是要控制的电脑设置了密码,之前想不明白为什么需要这一项,后来 ...

  7. mongoose手动生成ObjectId

    用mongoose驱动保存数据,如果_id没有定义,那么在save的时候,mongoose驱动会自己生成一个_id.那么如果需要手动生成可以用mongoose.Types.ObjectId()方法. ...

  8. bsxfun.h multiple threads backup

    https://code.google.com/p/deep-learning-faces/source/browse/trunk/cuda_ut/include/bsxfun.h?r=7&s ...

  9. 学习笔记-AngularJs(十)

    前面一直在说自定义指令,但是却一直没有一次系统地去了解,现在需要我们一起来学习如何去使用自定义指令,去丰富html标签.属性,实现多元化.多功能的标签(或是属性).辣么,啥是指令?要了解指令,首先需要 ...

  10. netty源码分析之二:accept请求

    我在前面说过了server的启动,差不多可以看到netty nio主要的东西包括了:nioEventLoop,nioMessageUnsafe,channelPipeline,channelHandl ...