一、Filter过滤链

   web.xml配置了filter过滤器,在容器启动的时候执行了init()方法进行了初始化,然后在容器关闭的时候执行了destroy()方法销毁过滤器,在每次服务器接受请求的时候每次都会先过一遍过滤器,如果有合适的过滤器就会执行相应过滤器的doFilter方法。

   doFilter方法有3个参数 ServletRequest、ServletResponse、FilterChain;前两个分别是请求和返回对象,为的是过滤后还能够进行请求或转发。FilterChain是一个过滤链,他包含了相同过滤条件的所有过滤器,例如:

  

  类似这种相同匹配模式的过滤器会存在于同一个过滤链中,然后按照初始化的先后顺一次排列,实现逐层过滤。其中filterChain中有个doFilter方法,他的作用是将当前请求转发给过滤链中的下一个过滤器进行过滤,然后将过滤结果,只有等待下一个过滤器执行过滤完成后才能继续执行。该执行过程类似如下图:

  

  如上图,通过过滤链逐层执行过滤就像一层嵌套,一层套一层,如果过滤链中只有一个过滤器(或者执行到最后一个)的话,执行了chain.doFilter()他会直接将请求转发出去,获取request resource资源,因为从始至终都是同一个request和response在传递,所以每次过滤都可以修改请求或返回结果,实现了过滤修改的目的。

  代码实例:(只贴主要代码)

    ResponseFilter.java

 public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
CustomResponseWrapper customResponseWrapper = new CustomResponseWrapper((HttpServletResponse) servletResponse);
System.out.println("ResponseFilter 执行前");
filterChain.doFilter(servletRequest,customResponseWrapper);//执行下一层过滤
System.out.println("ResponseFilter 执行后");
}
}

   SecondFilter.java

 public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("Second doFilter执行前");
filterChain.doFilter(servletRequest,servletResponse);//这是最后一层过滤器,会直接请求resource
System.out.println("Second doFilter执行后");
}

  web.xml (两个过滤器使用了相同的匹配模式‘/*’,所以会处于同一过滤链中)

 <filter>
<filter-name>ResponseFilter</filter-name>
<filter-class>filter.ResponseFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>ResponseFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<filter>
<filter-name>SecondFilter</filter-name>
<filter-class>filter.SecondFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>SecondFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

  执行结果:

  

  从执行结果并结合以上分析可以很清楚的看出doFilter的执行顺序

二、通过Filter过滤器实现对response内容的修改

  CustomPrintWriter.java (重写PrintWriter方法)

 public class CustomPrintWriter extends PrintWriter{
private StringBuilder buffer; public CustomPrintWriter(Writer out) {
super(out);
buffer = new StringBuilder();
} @Override
public void write(char[] buf, int off, int len) {
char[] dest = new char[len];
System.arraycopy(buf,off,dest,0,len);//深复制字符数组
buffer.append(dest);
} public String getContent() {
return buffer.toString();
}
}

  CustomResponseWrapper.java (重写HttpServletResponseWrapper方法)

 public class CustomResponseWrapper extends HttpServletResponseWrapper{
private CustomPrintWriter customPrintWriter; public CustomResponseWrapper(HttpServletResponse response) {
super(response);
} @Override
public PrintWriter getWriter() throws IOException {
customPrintWriter = new CustomPrintWriter(super.getWriter());
return customPrintWriter;
} public CustomPrintWriter getCustomPrintWriter() {
return customPrintWriter;
}
}

  ResponseFilter.java (过滤器)

 public class ResponseFilter implements Filter{
public void init(FilterConfig filterConfig) throws ServletException {} public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
CustomResponseWrapper customResponseWrapper = new CustomResponseWrapper((HttpServletResponse) servletResponse);
filterChain.doFilter(servletRequest,customResponseWrapper);//转发请求获取请求返回结果
CustomPrintWriter writer = customResponseWrapper.getCustomPrintWriter();//获取请求的返回结果
if(writer != null){
String content = writer.getContent();
/**
* 在不修改jsp源码的情况下修改展示内容
*/
content = content.replace("XXX", LoginCheckServlet.username);
servletResponse.getWriter().write(content);
}
} public void destroy() {}
}

  

  

Filter的过滤链理解的更多相关文章

  1. filter 请求过程中过滤链组装和调用解析

    自定义filter需要先下载依赖包 首先过滤链不是责任链的设计模式,因为一个request可以被链条上的多个filter处理.但是,对于责任链来说,一个request只能被链条中的一个handler处 ...

  2. Filter体现职责链模式

    1. 前言 Filter—Filter 技术是servlet2.3 新增加的功能.完成的流程:对用户请求进行预处理,接着将请求交给Servlet进行处理并生成响应,最后Filter再对服务器响应进行后 ...

  3. Filter技术+职责链模式

    Filter是一个过滤器,存在Webclient与请求的资源之间.这里的资源能够说是jsp或servlet.它的作用就是在请求达到资源之前,先对请求进行预处理.而且也能够对servlet处理后的res ...

  4. 使用Groovy的mixin方法注入,和mixedIn属性实现过滤链

    mixin方法注入不多说,这里只是用这个属性搞一个过滤器链的功能 假设我现在有个方法,输入一个字符串,然后需求提出需要进行大写转换输出, 过了一天又要加个前缀,再过了一天,需要把一些字符过滤掉.... ...

  5. fiddler filters 使用(fiddler只显示指定请求,fiddler不显示指定请求,即filter请求过滤)(转)

    fiddler filters 使用(fiddler只显示指定请求,fiddler不显示指定请求,即filter请求过滤) Fiddler 有一个filters可以很好的帮助我们只显示我们关系的请求或 ...

  6. Spring Security 学习笔记-securityContext过滤器过滤链学习

    web.xml配置委托代理filter,filter-name默认与filter bean的名字保持一致. <filter> <filter-name>springSecuri ...

  7. 基础设计模式-03 从过滤器(Filter)校验链学习职责链模式

    1.职责链路模式 1.1UML图 1.2 职责链路模式的概念 为了避免处理对象的耦合关系,将对象连成一个链,沿着这个链进行访问,直到有一个对象处理位置: 1.3 优点 1.按照一定的顺序执行判断: 2 ...

  8. Spring Security 多过滤链的使用

    Spring Security 多过滤链的使用 一.背景 二.需求 1.给客户端使用的api 2.给网站使用的api 三.实现方案 方案一: 方案二 四.实现 1.app 端 Spring Secur ...

  9. Filter Conditions 过滤条件

    <pre name="code" class="html">Filter Conditions 过滤条件: Rsyslog 提供4种不同类型的&qu ...

随机推荐

  1. 洛谷P3390【模板】矩阵快速幂——矩阵运算入门笔记

    作为一个因为极度畏惧数学 而选择成为一名OIer的蒟蒻 终于还是迎来了要面对的这一天 一般题目中矩阵运算好像只用到矩阵乘法 (或许只是蒟蒻我做的题太少) 而且矩阵的乘法也是较难理解的一部分 所以就简单 ...

  2. Redis入门_下

    本文主要介绍redis一些高级特性. 1.Redis HyperLogLog Redis HyperLogLog 是用来做基数统计的算法,HyperLogLog 的优点是,在输入元素的数量或者体积非常 ...

  3. JBoss AS7(Application Server 7)的Standalone模式和Domain模式

    JBoss AS7(Application Server 7)支持两种引导模式:standalone和domain(域). Standalone模式对于很多应用,并不需要domain管理能力,JBos ...

  4. 【netty这点事儿】ByteBuf 的使用模式

    堆缓冲区 最常用的 ByteBuf 模式是将数据存储在 JVM 的堆空间中. 这种模式被称为支撑数组(backing array), 它能在没有使用池化的情况下提供快速的分配和释放. 直接缓冲区 直接 ...

  5. AVFoundation 框架初探究(四)

    叨叨两句 动手写这篇总结时候也是二月底过完年回来上班了,又开始新的一年了,今年会是什么样子?这问题可能得年底再回答自己了.在家窝了那么久,上班还是的接着看我们要看的东西,毕竟我们要做的事还真的太多的. ...

  6. 用yii2给app写接口(上)

    Yii2如何实现RESTful风格的API 1.建立单独的应用程序 为了增加程序的可维护性,易操作性,我们选择新建一套应用程序,这也是为了和前台应用.后台应用区分开操作.有些人要嚷嚷了,为啥非得单独搞 ...

  7. B2B2C商品模块数据库设计

    kentzhu: 在电子商务里,一般会提到这样几个词:商品.单品.SPU.SKU 简单理解一下,SPU是标准化产品单元,区分品种:SKU是库存量单位,区分单品:商品特指与商家有关的商品,可对应多个SK ...

  8. 叼叼叼,HTML5日期(Date)类型和文本(Text)类型互相转换

    <input placeholder="From" class="form-control" type="text" onfocus= ...

  9. Redis笔记3-redis事务

    Redis的事务机制允许同时执行多条指令,它是原子性操作,事务中的命令要么全部执行,要么全部不执行,另外,事务中的所有指令都会被序列化,而且其开始执行过程中,不回被即时过来的指令所打断,其需要经历三个 ...

  10. SMJobBless官方Demo笔记

    SMJobBless是苹果官方提供的用于"MacOS app获取root权限"的demo. 具体思路 使用Security.framework和ServiceManagement. ...