博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Filter的过滤链理解
阅读量:5112 次
发布时间:2019-06-13

本文共 4217 字,大约阅读时间需要 14 分钟。

一、Filter过滤链

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

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

  

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

  

 

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

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

    ResponseFilter.java

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

 

   SecondFilter.java

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

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

1 
2
ResponseFilter
3
filter.ResponseFilter
4
5
6
ResponseFilter
7
/*
8
9
10
SecondFilter
11
filter.SecondFilter
12
13
14
SecondFilter
15
/*
16

   执行结果:

  

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

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

   CustomPrintWriter.java (重写PrintWriter方法)

1 public class CustomPrintWriter extends PrintWriter{ 2     private StringBuilder buffer; 3  4     public CustomPrintWriter(Writer out) { 5         super(out); 6         buffer = new StringBuilder(); 7     } 8  9     @Override10     public void write(char[] buf, int off, int len) {11         char[] dest =  new char[len];12         System.arraycopy(buf,off,dest,0,len);//深复制字符数组13         buffer.append(dest);14     }15 16     public String getContent() {17         return buffer.toString();18     }19 }

 

  CustomResponseWrapper.java (重写HttpServletResponseWrapper方法)

1 public class CustomResponseWrapper extends HttpServletResponseWrapper{ 2     private CustomPrintWriter customPrintWriter; 3  4     public CustomResponseWrapper(HttpServletResponse response) { 5         super(response); 6     } 7  8     @Override 9     public PrintWriter getWriter() throws IOException {10         customPrintWriter = new CustomPrintWriter(super.getWriter());11         return customPrintWriter;12     }13 14     public CustomPrintWriter getCustomPrintWriter() {15         return customPrintWriter;16     }17 }

 

  ResponseFilter.java (过滤器)

1 public class ResponseFilter implements Filter{ 2     public void init(FilterConfig filterConfig) throws ServletException {} 3  4     public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { 5         CustomResponseWrapper customResponseWrapper = new CustomResponseWrapper((HttpServletResponse) servletResponse); 6         filterChain.doFilter(servletRequest,customResponseWrapper);//转发请求获取请求返回结果 7         CustomPrintWriter writer = customResponseWrapper.getCustomPrintWriter();//获取请求的返回结果 8         if(writer != null){ 9             String content = writer.getContent();10             /**11              * 在不修改jsp源码的情况下修改展示内容12              */13             content = content.replace("XXX", LoginCheckServlet.username);14             servletResponse.getWriter().write(content);15         }16     }17 18     public void destroy() {}19 }

 

   

   

 

转载于:https://www.cnblogs.com/caijh/p/7677270.html

你可能感兴趣的文章
文本隐藏(图片代替文字)
查看>>
three.map.control
查看>>
二叉树的深度
查看>>
java面试题
查看>>
提高码力专题(未完待续)
查看>>
IOS第17天(3,Quartz2D画板和画线)
查看>>
pair的例子
查看>>
前端框架性能对比
查看>>
@property中 retain 详解
查看>>
java8 stream初试,map排序,list去重,统计重复元素个数,获取map的key集合和value集合...
查看>>
Python爬虫个人记录(四)利用Python在豆瓣上写一篇日记
查看>>
jdk8 Function
查看>>
第二次作业
查看>>
迷茫中的自己
查看>>
burp suite 的intruder 四种攻击方式
查看>>
机器学习----人脸对齐的算法-ASM.AAM..CLM.SDM
查看>>
自定义文本选中样式
查看>>
python3 字符串/列表/元组(str/list/tuple)相互转换方法及join()函数的使用
查看>>
MySQL 数据库 的安装和基本管理
查看>>
MyEclipse中JavaMail冲突问题
查看>>