Servlet过滤器简介
- 格式:doc
- 大小:134.50 KB
- 文档页数:22
onceperrequestfilter的用法在Java Web开发中,Filter是一种常用的技术,用于在请求处理过程中执行特定的操作,例如验证用户身份、清理输出流等。
Filter按照它们的作用方式可以分为两种:过滤所有请求的过滤器和仅过滤特定请求的过滤器。
其中,OncePerRequestFilter是一种仅过滤特定请求的过滤器,它的用法对于一些特定的场景非常重要。
OncePerRequestFilter是一种特殊的过滤器,它只对每个请求执行一次。
这意味着,无论请求被多次调用,OncePerRequestFilter只执行一次。
这对于一些需要在请求处理过程中保持状态的场景非常有用,例如缓存某些结果或跟踪用户行为。
要使用OncePerRequestFilter,需要实现javax.servlet.Filter接口,并重写其doFilter方法。
在doFilter方法中,可以实现只执行一次请求的处理逻辑。
以下是一个简单的示例,展示了如何使用OncePerRequestFilter:```javaimport javax.servlet.*;import javax.servlet.http.HttpServletRequest;import java.io.IOException;public class OncePerRequestFilter implements Filter {@Overridepublic void init(FilterConfig filterConfig) throws ServletException {// 初始化方法,可以在这里进行一些配置}@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)throws IOException, ServletException {// 获取HttpServletRequest对象HttpServletRequest httpRequest = (HttpServletRequest) request;// 检查是否是第一次访问该请求if (!isFirstTime(httpRequest)) {// 如果不是第一次访问,直接将请求传递给下一个过滤器或Servlet处理chain.doFilter(request, response);return;}// 第一次访问时执行的处理逻辑,例如记录用户行为或缓存数据// ...// 将请求传递给下一个过滤器或Servlet处理chain.doFilter(request, response);}private boolean isFirstTime(HttpServletRequest request) { // 实现判断是否是第一次访问的逻辑,这里可以根据实际情况进行定制// 例如,可以记录请求的唯一标识符,并与之前访问的标识符进行比较String uniqueId = request.getHeader("UniqueId");return uniqueId == null|| !uniqueId.equals(getLastAccessedUniqueId(request));}private StringgetLastAccessedUniqueId(HttpServletRequest request) { // 实现获取上次访问的唯一标识符的逻辑,这里可以根据实际情况进行定制// 可以从数据库、缓存或其他数据源中获取该标识符return "123456"; // 示例值,实际应用中需要根据实际情况获取标识符}@Overridepublic void destroy() {// 销毁方法,可以在这里进行一些清理操作}}```上述示例中,OncePerRequestFilter实现了对特定请求的处理逻辑只执行一次。
java-过滤器Filter_多个Filter的执⾏顺序【Filter链】*在⼀个web应⽤中,可以开发编写多个Filter,这些Filter组合起来称为⼀个Filter链。
*web服务器根据Filter在web.xml中的注册顺序,决定先调⽤哪个Filter,当第⼀个Filter的doFilter⽅法被调⽤时,web服务器会创建⼀个代表Filter链的FilterChain对象传递给该⽅法,在doFilter⽅法中,开发⼈员如果调⽤了FilterChain对象的doFilter⽅法,则web服务器会检查FilterChain对象中是否还有filter,如果有,则调⽤第⼆个filter,如果没有,则调⽤⽬标资源。
【⼯程截图】设计了两个Filter和⼀个Servlet,访问Servlet时,查看Filter的执⾏顺序。
【web.xml】<?xml version="1.0" encoding="UTF-8"?><web-app xmlns:xsi="/2001/XMLSchema-instance" xmlns="/xml/ns/javaee" xsi:schemaLocation="/xml/ns/javaee /xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" <display-name>FilterDemo01</display-name><welcome-file-list><welcome-file>index.jsp</welcome-file></welcome-file-list><!-- 过滤顺序:谁的写在上⾯,谁先被过滤 --><filter><filter-name>FilterTest01</filter-name><filter-class>com.Higgin.web.filter.FilterTest01</filter-class></filter><filter-mapping><filter-name>FilterTest01</filter-name><url-pattern>/*</url-pattern> <!-- 过滤所有 --></filter-mapping><filter><filter-name>FilterTest02</filter-name><filter-class>com.Higgin.web.filter.FilterTest02</filter-class></filter><filter-mapping><filter-name>FilterTest02</filter-name><url-pattern>/*</url-pattern> <!-- 过滤所有 --></filter-mapping></web-app>【FilterTest01.java】package com.Higgin.web.filter;import java.io.IOException;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 FilterTest01 implements Filter{@Overridepublic void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) throws IOException, ServletException {System.out.println("FilterTest01 执⾏前---");chain.doFilter(request, response);//让⽬标资源执⾏,即:放⾏System.out.println("FilterTest01 执⾏后---");}@Overridepublic void init(FilterConfig arg0) throws ServletException {}@Overridepublic void destroy() {}}【FilterTest02.java】package com.Higgin.web.filter;import java.io.IOException;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 FilterTest02 implements Filter{@Overridepublic void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) throws IOException, ServletException {System.out.println("FilterTest02 执⾏前---");chain.doFilter(request, response); //放⾏System.out.println("FilterTest02 执⾏后---");}@Overridepublic void init(FilterConfig arg0) throws ServletException {}@Overridepublic void destroy() {}}【ServletTest01.java】package com.Higgin.web.servlet;import java.io.IOException;import javax.servlet.ServletException;import javax.servlet.annotation.WebServlet;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;/*** Servlet implementation class ServletTest01*/@WebServlet("/ServletTest01")public class ServletTest01 extends HttpServlet {private static final long serialVersionUID = 1L;public ServletTest01() {super();}protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //response.getWriter().write("中国加油!China Come on!");System.out.println("执⾏ServletTest01---");}protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request,response);}}【运⾏结果】在浏览器中输⼊:http://localhost:8080/FilterDemo01/ServletTest01查看控制台输出结果⾃⼰可以尝试分别注释FilterTest01和FilterTest02中的chain.doFilter⽅法,⽤Junit查看具体的执⾏过程。
springboot过滤器FilterRegistrationBean有2种⽅式可以实现过滤器1:通过FilterRegistrationBean实例注册2:通过@WebFilter注解⽣效这⾥选择第⼀种,因为第⼆种不能设置过滤器之间的优先级为了演⽰优先级,这⾥创建2个测试过滤器类:Test1Filter、Test2Filter通过实现javax.servlet.Filter接⼝,覆盖其doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2)⽅法,决定拦截或放⾏public class Test1Filter implements Filter {@Overridepublic void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2)throws IOException, ServletException {// TODO Auto-generated method stubHttpServletRequest request=(HttpServletRequest)arg0;System.out.println("⾃定义过滤器filter1触发,拦截url:"+request.getRequestURI());arg2.doFilter(arg0,arg1);}}public class Test2Filter implements Filter {@Overridepublic void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2)throws IOException, ServletException {// TODO Auto-generated method stubHttpServletRequest request=(HttpServletRequest)arg0;System.out.println("⾃定义过滤器filter2触发,拦截url:"+request.getRequestURI());arg2.doFilter(arg0,arg1);}}通过在springboot的configuration中配置不同的FilterRegistrationBean实例,来注册⾃定义过滤器这⾥创建⼀个configuration类import org.springframework.boot.web.servlet.FilterRegistrationBean;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import com.example.demo.filter.Test1Filter;import com.example.demo.filter.Test2Filter;@Configurationpublic class DemoConfiguration {@Beanpublic FilterRegistrationBean<Test1Filter> RegistTest1(){//通过FilterRegistrationBean实例设置优先级可以⽣效//通过@WebFilter⽆效FilterRegistrationBean<Test1Filter> bean = new FilterRegistrationBean<Test1Filter>();bean.setFilter(new Test1Filter());//注册⾃定义过滤器bean.setName("flilter1");//过滤器名称bean.addUrlPatterns("/*");//过滤所有路径bean.setOrder(1);//优先级,最顶级return bean;}@Beanpublic FilterRegistrationBean<Test2Filter> RegistTest2(){//通过FilterRegistrationBean实例设置优先级可以⽣效//通过@WebFilter⽆效FilterRegistrationBean<Test2Filter> bean = new FilterRegistrationBean<Test2Filter>();bean.setFilter(new Test2Filter());//注册⾃定义过滤器bean.setName("flilter2");//过滤器名称bean.addUrlPatterns("/test/*");//过滤所有路径bean.setOrder(6);//优先级,越低越优先return bean;}}其中1第⼀个bean拦截所有路径,⽽第⼆个只拦截/test/*路径2第⼀个bean优先级设置了1,⽽第⼆个设置了6,越低越优先,所以过滤器1应该在过滤器2前⾯拦截运⾏springboot,访问/test/*请求如下图,再访问/v请求如下图只拦截了过滤器1,⽽过滤器2路径不匹配如果把.addUrlPatterns();中拦截路径改成⼀样/test/*,则所有请求,都会触发2个过滤器,⽽且过滤器1永远在最先拦截。
Web过滤器的处理流程通常包括以下几个关键步骤:
1.初始化阶段:当Web容器启动时,过滤器会被创建并初始化。
在
这个阶段,过滤器可以读取配置参数,获取`FilterConfig`对象,并进行一些初始化操作。
2.请求预处理阶段:在请求到达Servlet之前,过滤器可以对请求进
行预处理。
这个环节常用于执行如日志记录、权限验证、字符编码设置等操作。
3.Servlet执行阶段:经过过滤器预处理后,请求会被传递给目标
Servlet进行处理。
如果存在多个过滤器,那么这些过滤器会按照它们在配置文件中的顺序依次执行。
4.响应后处理阶段:在Servlet生成响应之后,过滤器还可以对服务
器的响应进行后处理。
例如,可以对输出的内容进行压缩或者添加额外的头部信息。
5.销毁阶段:在Web容器关闭时,过滤器会被销毁。
在这个阶段,
可以进行资源的清理工作。
需要注意的是,在编写过滤器时,需要实现`javax.servlet.Filter`接口,并重写其中的`doFilter`方法。
该方法接收`ServletRequest`、`ServletResponse`和`FilterChain`三个参数,分别代表请求、响应和过滤器链。
在`doFilter`方法中,可以编写预处理和后处理的逻辑代码。
此外,还需要通过注解`@WebFilter`或者在`web.xml`文件中配置过滤器的映射信息,以指定过滤器应用于哪些URL模式。
tomcat 过滤规则Tomcat的过滤规则可以通过配置web.xml文件来实现。
过滤器是Web应用程序中一种特殊的组件,用于对Web请求进行预处理或后处理。
以下是配置Tomcat过滤器的一般步骤:1. 在项目的WEB-INF目录下创建一个名为web.xml的文件(如果已存在,则直接打开)。
2. 在web.xml文件中的<web-app>标签中添加过滤器的配置。
示例如下:xml<filter><filter-name>MyFilter</filter-name><filter-class>com.example.MyFilter</filter-class></filter>3. 在web.xml文件中的<web-app>标签中添加过滤器映射的配置。
示例如下:xml<filter-mapping><filter-name>MyFilter</filter-name><url-pattern>/*</url-pattern></filter-mapping>上述示例中,过滤器名称为"MyFilter",过滤器类为com.example.MyFilter。
url-pattern指定了过滤器要处理的URL模式,"*"表示所有的URL。
4. 编写过滤器类com.example.MyFilter。
该类需要继承javax.servlet.Filter 接口,并实现doFilter方法。
在doFilter方法中可以编写具体的过滤逻辑。
示例如下:javaimport javax.servlet.*;import javax.servlet.http.HttpServletRequest;import java.io.IOException;public class MyFilter implements Filter {@Overridepublic void init(FilterConfig config) throws ServletException { 过滤器初始化时执行的代码}@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { 过滤逻辑代码HttpServletRequest httpRequest = (HttpServletRequest) request;对请求进行处理...将请求转发给下一个过滤器或Servletchain.doFilter(request, response);}@Overridepublic void destroy() {过滤器销毁时执行的代码}}在doFilter方法中,可以对请求进行处理,并通过调用chain.doFilter方法将请求转发给下一个过滤器或Servlet。
get request filter参数关于GET请求中的Filter参数在Web开发中,我们经常会遇到需要从服务器获取数据的场景。
而GET请求是最常用的一种请求方式,使用GET请求可以从服务器获取特定资源的数据。
而为了更精确地获取所需的数据,我们常常会使用Filter参数来进行筛选和过滤。
本文将详细介绍GET请求中的Filter参数,并一步一步回答您关于此参数的疑问。
1. 什么是Filter参数?Filter参数是GET请求中的一种参数,用于对请求的资源数据进行筛选和过滤。
通常,我们可以通过Filter参数指定特定的条件,以限制服务器返回的数据结果。
例如,在一个商品列表接口中,我们可以使用Filter参数来筛选出价格大于某个值且库存大于某个数量的商品。
2. 如何使用Filter参数?使用Filter参数需要注意以下几个方面:- 首先,需要了解服务器接口支持的Filter参数及其语法规则。
通常,服务器接口文档会提供详细的说明,告诉我们可以使用哪些Filter参数以及如何使用。
- 其次,可以在GET请求的URL中添加Filter参数。
一般情况下,Filter参数会以问号(?)作为分隔符,紧跟在资源路径后面。
例如,假设我们的商品列表接口为:`/api/products`,我们可以使用Filter参数来筛选价格在100到200之间的商品,URL可以写为:`/api/products?price_gt=100&price_lt=200`。
- 最后,需要根据服务器接口的要求,将Filter参数的值进行编码。
特殊字符(如空格、符号等)在URL中必须进行编码,以确保数据能正确传递到服务器端。
3. 常见的Filter参数语法有哪些?常见的Filter参数语法包括:- 等于(eq):筛选出指定属性值等于某个值的数据。
例如,`/api/products?category_eq=electronics` 可以筛选出分类为"electronics"的商品。
过滤器,拦截器,aop区别与使⽤场景1. 什么是过滤器过滤器,顾名思义就是起到过滤筛选作⽤的⼀种事物,只不过相较于现实⽣活中的过滤器,这⾥的过滤器过滤的对象是客户端访问的web资源,也可以理解为⼀种预处理⼿段,对资源进⾏拦截后,将其中我们认为的杂质(⽤户⾃⼰定义的)过滤,符合条件的放⾏,不符合的则拦截下来。
1.1 过滤器常见使⽤场景统⼀设置编码过滤敏感字符登录校验URL级别的访问权限控制数据压缩1.2 springboot整合过滤器bean注⼊⽅式a) 编写Filterpublic class HeFilter implements Filter {@Overridepublic void init(FilterConfig filterConfig) throws ServletException {}@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)throws IOException, ServletException {System.out.println("您已进⼊filter过滤器,您的请求正常,请继续遵规则...");chain.doFilter(request, response);}@Overridepublic void destroy() {}}b) 编写Filter配置类@Configurationpublic class ServletConfig {@Beanpublic FilterRegistrationBean heFilterRegistration() {FilterRegistrationBean registration = new FilterRegistrationBean(new HeFilter());registration.addUrlPatterns("/*");return registration;}}注解⽅式@Slf4j@Component// filterName就是当前类名称,还有⼀个urlPattens的参数,这个参数表⽰要过滤的URL上的后缀名,是多参数,可以⽤数组表⽰。
Interceptor的基本介绍和使⽤简介java⾥的拦截器是动态拦截Action调⽤的对象,它提供了⼀种机制可以使开发者在⼀个Action执⾏的前后执⾏⼀段代码,也可以在⼀个Action执⾏前阻⽌其执⾏,同时也提供了⼀种可以提取Action中可重⽤部分代码的⽅式。
在AOP中,拦截器⽤于在某个⽅法或者字段被访问之前,进⾏拦截然后再之前或者之后加⼊某些操作。
⽬前,我们需要掌握的主要是Spring的拦截器,Struts2的拦截器不⽤深究,知道即可。
原理⼤部分时候,拦截器⽅法都是通过代理的⽅式来调⽤的。
Struts2的拦截器实现相对简单。
当请求到达Struts2的ServletDispatcher时,Struts2会查找配置⽂件,并根据配置实例化相对的拦截器对象,然后串成⼀个列表(List),最后⼀个⼀个的调⽤列表中的拦截器。
Struts2的拦截器是可插拔的,拦截器是AOP的⼀个实现。
Struts2拦截器栈就是将拦截器按⼀定的顺序连接成⼀条链。
在访问被拦截的⽅法或者字段时,Struts2拦截器链中的拦截器就会按照之前定义的顺序进⾏调⽤。
⾃定义拦截器的步骤第⼀步:⾃定义⼀个实现了Interceptor接⼝的类,或者继承抽象类AbstractInterceptor。
第⼆步:在配置⽂件中注册定义的拦截器。
第三步:在需要使⽤Action中引⽤上述定义的拦截器,为了⽅便也可以将拦截器定义为默认的拦截器,这样在不加特殊说明的情况下,所有的Action都被这个拦截器拦截。
Spring拦截器5.1,抽象类HandlerInterceptorAdapter我们如果在项⽬中使⽤了Spring框架,那么,我们可以直接继承HandlerInterceptorAdapter.java这个抽象类,来实现我们⾃⼰的拦截器。
框架,对java的拦截器概念进⾏了包装,这⼀点和Struts2很类似。
HandlerInterceptorAdapter继承了抽象接⼝HandlerInterceptor。
过滤器filter的配置推荐:多个filter拦截的同⼀个请求,按web.xml配置顺序进⾏过滤返回的响应的从最后配置的filter开始过滤具体配置步骤:编写Filter实现类1package cn.kihyou.b2c.filter;23import java.io.IOException;45import javax.servlet.Filter;6import javax.servlet.FilterChain;7import javax.servlet.FilterConfig;8import javax.servlet.ServletException;9import javax.servlet.ServletRequest;10import javax.servlet.ServletResponse;1112//实现接⼝:javax.servlet.Filter;13public class AdminFilter implements Filter {1415// 三个重要⽅法:初始化:init();拦截到要执⾏的⽅法:doFilter();销毁:destroy();1617 @Override18public void init(FilterConfig filterConfig) throws ServletException {19// TODO Auto-generated method stub20// Filter.super.init(filterConfig);21 }2223 @Override24public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)25throws IOException, ServletException {26// TODO Auto-generated method stub27// 1.拦截客户端/上⼀个filter发来的请求,是否放⾏到Servlet/下⼀个Filter28 System.out.println("AdminFilter拦截到请求");29// 放⾏(放不放⾏您可以⾃⼰看着办)30 chain.doFilter(request, response);31// 2.拦截servlet/filter发回的响应,是否放⾏到客户端/上⼀个filter32 System.out.println("AdminFilter拦截到响应");3334 }3536 @Override37public void destroy() {38// TODO Auto-generated method stub39// Filter.super.destroy();40 }4142 }配置web.xml1<!-- Filter,过滤器 -->2<filter>3<!-- filter名,随便起 -->4<filter-name>AdminFilter</filter-name>5<!-- 实现类所在⽬录 -->6<filter-class>cn.kihyou.b2c.filter.AdminFilter</filter-class>7<!-- 初始化参数 -->8<!-- 设置字符集,charset:UTF-8 -->9<init-param>10<!-- 参数名 -->11<param-name>charset</param-name>12<!-- 参数值 -->13<param-value>UTF-8</param-value>14</init-param>1516<!-- 设置内容类型及其字符集,contentType:text/html;charset=UTF-8 -->17<init-param>18<param-name>contentType</param-name>19<param-value>text/html;charset=UTF-8</param-value>20</init-param>21</filter>2223<!-- filter的映射 -->24<filter-mapping>25<!-- 对应的filter名 -->26<filter-name>AdminFilter</filter-name> 27<!-- 要进⾏拦截过滤的⽬录 -->28<url-pattern>/web/admin/*</url-pattern> 29</filter-mapping>3031<session-config>32<!-- 超时时间,单位:分钟 -->33<session-timeout>30</session-timeout> 34</session-config>。
14.1 Servlet过滤器简介 很早之前,Servlet API就已成为企业应用开发的重要工具。现在,Servlet中的过滤器和监听器功能则是对J2EE体系的一个补充。过滤器使得Servlet开发者能够在请求到达Servlet之前截取请求,在Servlet处理请求之后修改应答;而Servlet监听器可以监听客户端的请求、服务端的操作,通过监听器,可以自动激发一些操作,如监听应用的启动和停止等。本章将接着介绍Servlet过滤器和监听器的相关知识以及在实际开发中如何使用这些技术。 本章重点: ● Servlet过滤器简介 ● Servlet过滤器的实现 ● Servlet过滤文本信息 ● Servlet监听器简介 14.1 Servlet过滤器简介
Servlet过滤器是小型的Web组件,能拦截请求和响应,以便查看、提取或以某种方式操作正在客户机和服务器之间交换的数据。过滤器是封装了一些功能的Web组件,这些功能虽然很重要,但是对于处理客户机请求或发送响应来说不是决定性的。典型的例子包括记录关于请求和响应的数据、处理安全协议、管理会话属性等。 一个过滤器可以被关联到任意多个资源,一个资源也可以关联到任意多个过滤器。例如,在图14.1中就有如下的关联关系。 ● F1同时被关联到S1、S2、S3。 ● F1、F2、F3都和S2关联。 图14.1 Web资源与过滤器相关联 关联到同一个资源的过滤器形成一个过滤器链。例如,对S2进行访问时,F1、F2、F3就形成了一个过滤器链,客户要访问资源S2,就要经过F1过滤器,然后是F2、F3,最后才是要访问的资源。如果在经过上面这3个过滤器时出现了错误或者被禁止访问,客户的请求就无法到达资源S2。在Servlet过滤器中,这个过滤器传递的过程是通过FilterChain.dofilter()方法实现的,当过滤器链到达末尾时,这个方法调用请求的资源。建立一个过滤器,一般需要下面4个步骤: (1)建立一个实现Filter接口的类。这个类需要3个方法,即doFilter、init和destroy。doFilter方法包含主要的过滤代码(见第(2)步),在init方法中进行一些初始化的设置,而destroy方法进行清除过滤器占用的资源。 (2)在doFilter方法中放入过滤行为。doFilter方法的第一个参数为ServletRequest对象,为过滤器提供了对进入的信息(包括表单数据、cookie和HTTP请求头)的完全访问。第二个参数为ServletResponse,通常在简单的过滤器中忽略此参数。最后一个参数为FilterChain,用来调用过滤器链中下一个过滤器或者在到达过滤器末尾时调用Servlet或JSP页。 (3)调用FilterChain对象的doFilter方法。Filter接口的doFilter方法将一个FilterChain对象作为它的一个参数。在调用此对象的doFilter方法时,激活下一个相关的过滤器。如果没有另一个过滤器与Servlet或JSP页面关联,则Servlet或JSP页面被激活。 (4)对相应的Servlet和JSP页面注册过滤器。在部署描述符文件(web.xml)中使用filter和filter-mapping元素对需要进行过滤的资源进行配置。 14.2 实现一个Servlet过滤器 Servlet过滤器API包含3个简单的接口,即Filter、FilterChain和FilterConfig,它们位于javax.servlet包中。从编程的角度看,过滤器类将实现Filter接口,然后使用这个过滤器类中的FilterChain和FilterConfig接口。该过滤器类的一个引用将传递给FilterChain对象,以允许过滤器将控制权传递给过滤器链中的下一个过滤器或者资源。FilterConfig对象将由容器提供给过滤器,以允许访问该过滤器的初始化数据。 14.2.1 编写实现类的程序
下面是一个简单的Servlet过滤器的例子,其中将获取一个Web服务器给客户提供服务需要的时间,也就是响应时间。 【本节示例参考:资料光盘\源代码\第14章\14-2\Servlet.java】 【实例14-1】这是一个实现类的程序,主要是使用过滤器处理请求,在处理时可能要耗费很多 时间。 程序14-1 Servlet.java 01 package cn.ac.ict.Filter; 02 import java.io.IOException; 03 import java.io.PrintWriter; 04 import java.io.StringWriter; 05 import java.util.Date; 06 import javax.servlet.*; 07 public class ResponseTimeFilter implements Filter { 08 private FilterConfig filterConfig = null; 09 public void init(FilterConfig config) throws ServletException {//初始化函数 10 this.filterConfig = config; 11 } 12 public void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) throws IOException, ServletException { 13 Date startTime, endTime; 14 double totalTime; 15 startTime = new Date(); 16 StringWriter sw = new StringWriter(); 17 PrintWriter writer = new PrintWriter(sw); 18 writer.println(); 19 writer.println("ResponseTimeFilter Before call chain.doFilter"); 20 chain.doFilter(request, response); //将请求转发给过滤器链中下一个资源 21 //下面是资源的响应时间 22 //下面计算开始时间和结束时间的差,也就是响应时间 23 endTime = new Date(); 24 totalTime = endTime.getTime() - startTime.getTime(); 25 totalTime = totalTime / 1000; //将毫秒时间转换为以秒为单位 26 writer.println("ResponseTimeFilter Before call chain.doFilter"); 27 writer.println("==============="); 28 writer.println("Total elapsed time is: " + totalTime + " seconds." ); 29 writer.println("==============="); 30 filterConfig.getServletContext().log(sw.getBuffer().toString()); //将信息输出到日志中 31 writer.flush(); 32 } 33 public void destroy() { 34 this.filterConfig = null; 35 } 36 public FilterConfig getFilterConfig() { 37 return null; 38 } 39 public void setFilterConfig(FilterConfig config) { 40 } 41 } 【深入学习】当容器第一次加载该过滤器时,init()方法将被调用。该类在这个方法中包含了一个指向FilterConfig对象的引用。过滤器的大多数时间都消耗在执行过滤操作上,第20行中的doFilter()方法被容器调用,同时传入分别指向这个请求/响应链中的ServletRequest、ServletResponse和FilterChain对象的引用。然后过滤器就有机会处理请求,将处理任务传递给链中的下一个资源(通过调用FilterChain对象引用上的doFilter()方法),之后在处理控制权返回该过滤器时处理响应。 14.2.2 配置发布Servlet过滤器
发布Servlet过滤器时,必须在web.xml文件中加入和ng>元素,其中,元素用来定义一个过滤器,在本例中使用了如下代码: Request Response Time cn.ac.ict.Filter.ResponseTimeFilter 以上代码中,指定过滤器的名字,指定过滤器的完整类名,也可以在元素中内嵌元素来为过滤器提供初始化参数。 元素用于将过滤器和URL关联,本例中的代码如下: Request Response Time /ShowCounter.jsp 当客户请求的URL和指定的URL相匹配时,就会触发ResponseTimeFilter过滤器,这里的元素的值和元素中的name>值应该相同。 说明:如果希望Servlet过滤器能过滤所有的客户请求,可以将的值设置为/*。