Java Servlet Filter
做web开发的人对于Filter应该不会陌生,一直在很简单的使用,但是一直没有系统的总结一下,随着年纪的慢慢长大,喜欢总结一些事情,下面说说我对Filter的理解,官方给出的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
<filter>
<display-name>EcodingFilter</display-name>
<filter-name>EcodingFilter</filter-name>
<filter-class>org.nb.filter.EnCodeFilter</filter-class>
<init-param>
<param-name>EncodeCoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
我们可以使用如下方法来给Filter匹配指定的servlet 资源或者url-pattern:
<filter-mapping>
<filter-name>EcodingFilter</filter-name>
<servlet-name>*</servlet-name>
<url-pattern>*</url-pattern>
</filter-mapping>
在这里需要注意的是,在给servlet注册filter环,container首先处理的是url-patterns,然后才处理servlet-names,所以如果要对filter的执行顺序有要求,那么在此需要注意。下面我们创建一个web工程,来实践一下Filter:

web.xml内容:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
<display-name>FilterTest</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
<filter>
<display-name>EcodingFilter</display-name>
<filter-name>EcodingFilter</filter-name>
<filter-class>org.nb.filter.EnCodeFilter</filter-class>
<init-param>
<param-name>EncodeCoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>EcodingFilter</filter-name>
<servlet-name>hello</servlet-name>
<url-pattern>*</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>hello</servlet-name>
<servlet-class></servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>
HelloServlet.java内容:
package org.nb.action; import java.io.IOException;
import java.io.PrintWriter; import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; @WebServlet("/helloServlet")
public class HelloServlet extends HttpServlet {
private static final long serialVersionUID = 1L; protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
PrintWriter out = response.getWriter();
out.println("<font color=red>Hello.</font>");
}
}
EnCodeFilter.xm内容:
package org.nb.filter; import java.io.IOException;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map; import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse; public class EnCodeFilter implements Filter { Map<String, String> params = new HashMap<String, String>(); @Override
public void destroy() {
System.out.println("EncodeFilter destroy");
} @Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
String encodeCoding = params.get("EncodeCoding");
request.setCharacterEncoding(encodeCoding);
response.setCharacterEncoding(encodeCoding);
chain.doFilter(request, response);
System.out.println("EncodeFilter doFilter");
} @Override
public void init(FilterConfig cfg) throws ServletException {
Enumeration<String> names = cfg.getInitParameterNames();
while (names.hasMoreElements()) {
String name = names.nextElement();
params.put(name, cfg.getInitParameter(name));
}
System.out.println("EncodeFilter init");
} }
在tomcat启动的时候Console输出的内容:
三月 , :: 下午 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.\;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.\;C:\Program Files\Microsoft\Web Platform Installer\;C:\Program Files (x86)\Microsoft ASP.NET\ASP.NET Web Pages\v1.\;C:\Program Files (x86)\Windows Kits\8.0\Windows Performance Toolkit\;C:\Program Files\Microsoft SQL Server\\Tools\Binn\;E:\Program Files\Java\jdk1..0_40\bin;C:\Program Files (x86)\Microsoft SQL Server\\Tools\Binn\;C:\Program Files\Microsoft SQL Server\\Tools\Binn\;C:\Program Files\Microsoft SQL Server\\DTS\Binn\;F:\instantclient;.;;.;;.
三月 , :: 下午 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.
三月 , :: 下午 org.apache.coyote.AbstractProtocolHandler init
信息: Initializing ProtocolHandler ["http-bio-8080"]
三月 , :: 下午 org.apache.coyote.AbstractProtocolHandler init
信息: Initializing ProtocolHandler ["ajp-bio-8009"]
三月 , :: 下午 org.apache.catalina.startup.Catalina load
信息: Initialization processed in ms
三月 , :: 下午 org.apache.catalina.core.StandardService startInternal
信息: Starting service Catalina
三月 , :: 下午 org.apache.catalina.core.StandardEngine startInternal
信息: Starting Servlet Engine: Apache Tomcat/7.0.
EncodeFilter init
三月 , :: 下午 org.apache.catalina.startup.HostConfig deployDirectory
信息: Deploying web application directory docs
三月 , :: 下午 org.apache.catalina.startup.HostConfig deployDirectory
信息: Deploying web application directory examples
三月 , :: 下午 org.apache.catalina.core.ApplicationContext log
信息: ContextListener: contextInitialized()
三月 , :: 下午 org.apache.catalina.core.ApplicationContext log
信息: SessionListener: contextInitialized()
三月 , :: 下午 org.apache.catalina.startup.HostConfig deployDirectory
信息: Deploying web application directory host-manager
三月 , :: 下午 org.apache.catalina.startup.HostConfig deployDirectory
信息: Deploying web application directory manager
三月 , :: 下午 org.apache.catalina.startup.HostConfig deployDirectory
信息: Deploying web application directory ROOT
三月 , :: 下午 org.apache.coyote.AbstractProtocolHandler start
信息: Starting ProtocolHandler ["http-bio-8080"]
三月 , :: 下午 org.apache.coyote.AbstractProtocolHandler start
信息: Starting ProtocolHandler ["ajp-bio-8009"]
三月 , :: 下午 org.apache.catalina.startup.Catalina start
信息: Server startup in ms
其中有filter,init方法的输出,下面创建一个index.html文件,内容如下:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<form action="http://localhost:8080/FilterTest/helloServlet" method="post">
<input type="submit" value="Login">
</form>
</body>
</html>
点击index.html页面的按钮,

此时Console输出内容:
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
Java Servlet Filter的更多相关文章
- java Servlet Filter 拦截Ajax请求
/** * 版权:Copyright 2016-2016 AudaqueTech. Co. Ltd. All Rights Reserved. * 描述: * 创建人:赵巍 * 创建时间:2016年1 ...
- Java Servlet Filter(转)
做web开发的人对于Filter应该不会陌生,一直在很简单的使用,但是一直没有系统的总结一下,随着年纪的慢慢长大,喜欢总结一些事情,下面说说我对Filter的理解,官方给出的Filter的定义是在请求 ...
- java Servlet Filter 拦截Ajax请求,统一处理session超时的问题
后台增加filter,注意不要把druid也屏蔽了 import java.io.IOException; import javax.servlet.Filter; import javax.serv ...
- Java中Filter、Servlet、Listener的学习
1.Filter的功能filter功能,它使用户可以改变一个 request和修改一个response. Filter 不是一个servlet,它不能产生一个response,它能够在一个reques ...
- 转 Java中Filter、Servlet、Listener的学习
1.Filter的功能filter功能,它使用户可以改变一个 request和修改一个response. Filter 不是一个servlet,它不能产生一个response,它能够在一个requ ...
- java.lang.ClassCastException: org.springframework.web.filter.CharacterEncodingFilter cannot be cast to javax.servlet.Filter
java.lang.ClassCastException: org.springframework.web.filter.CharacterEncodingFilter cannot be cast ...
- java.lang.ClassNotFoundException: javax.servlet.Filter
java.lang.ClassNotFoundException: javax.servlet.Filter:有两个原因:(1)在maven中的作用域,不能是provided,需要是compile就是 ...
- 【Servlet】Java Serlvet Filter 过滤器
Filter的设计思想Filter是一种AOP(aspect-oriented programming)的设计思想 : 面向切面编程.用于的请求和响应都会走 使用filter的登录案例我们通过一张图片 ...
- Java Servlet (1) —— Filter过滤请求与响应
Java Servlet (1) -- Filter过滤请求与响应 版本: Java EE 6 参考来源: Oracle:The Java EE 6 Tutorial: Filtering Reque ...
随机推荐
- 一个iOS程序员眼中的跨域问题
摘要: 跨域问题是web开发领域一个常见的问题,相信每个web开发者都遇到"跨域"的问题 最近公司的iOS开发任务比较少,所以自己最近开始了Web开发的任务,在用H5做了很多页面, ...
- CSS查缺补漏篇
前面的话:关于CSS,之前我已经做过一些基础的知识点介绍.CSS主要是用来给页面设置样式的,一般说来,在一个网站中,CSS应该独立封装在一个单独的.css外部文件中.样式的设置总体来说是不难的,但是需 ...
- nyoj 题目6 喷水装置
喷水装置(一) 时间限制:3000 ms | 内存限制:65535 KB 难度:3 描述 现有一块草坪,长为20米,宽为2米,要在横中心线上放置半径为Ri的喷水装置,每个喷水装置的效果都会让以 ...
- Java Socket实战之三 传输对象
首先需要一个普通的对象类,由于需要序列化这个对象以便在网络上传输,所以实现java.io.Serializable接口就是必不可少的了,入下: public class User implements ...
- [ZJOI2014][bzoj3527]力 [FFT]
题面 传送门 思路 把要求的公式列出来: $E_i=\frac{F_i}{q_i}=\sum_{j=1}^i\frac{q_j}{\left(i-j\right)^2}-\sum_{j=i+1}^n\ ...
- xml读取 避开并发(xml的一些操作)
很多地方读取文件可能会出现并发现象 处理: 使用FileMode.Open, FileAccess.Read, FileShare.ReadWrite 避开并发 public static List& ...
- Juice Junctions
Juice Junctions 题目描述 你被雇佣升级一个旧果汁加工厂的橙汁运输系统.系统有管道和节点构成.每条管道都是双向的,且每条管道的流量都是11升每秒.管道可能连接节点,每个节点最多可以连接3 ...
- Java语法糖(二)
语法糖之四:内部类 内部类:顾名思义,在类的内部在定义一个类.内部类仅仅是编译时的概念,编译成字节码后,内部类会生成单独的Class文件. 四种:成员内部类.局部内部类.匿名内部类.静态内部类. 1. ...
- input输入框与元素间有间隙
<div class="container"> <button>1</button> <button>2</button> ...
- C#去除字符串的最后一个字符 与 JavaScript去除最后一个字符
原文发布时间为:2009-04-29 -- 来源于本人的百度文章 [由搬家工具导入] 例子: C#.NET中去掉字符串的最后一个逗号 字符串为 (a,b,c,)最后一个逗号即c后面的逗号 答: &qu ...