过滤器通过doFilter方法的第二个参数ServletResponse将输出发送给客户,但servletResponse参数没有为过滤器提供servlet或jsp页面的访问;执行doFilter方法时,servlet或jsp还没修改,当调用FilterChain的doFilter方法时,修改相应似乎为时已晚,以为数据已经发送给客户端,怎么办呢?

  解决这个问题的办法是创建一个像HttpServletResponse的缓冲区,当servlet或jsp调用response.getWiter或者response.getOutputStream并发送输出时,输出实际上没有被发送到客户端,而是放到了该缓冲区中,这样filter就可以在发送到客户端前检查货修改这个输出。大概过程如下

具体代码如下:

1、实现HttpServletResponseWrapper

public class StringWrapper extends HttpServletResponseWrapper {
private StringWriter stringWriter;//缓存区 public StringWrapper(HttpServletResponse response) {
super(response);
stringWriter = new StringWriter();
}
/** 当servlet或jsp请求Writer时,给它们一个被封装过的writer,
* 其会往缓冲区中写数据
*/
public PrintWriter getWriter() {
return(new PrintWriter(stringWriter));
}
/** 同样,当 调用 getOutputStream,
* 返回一个模拟的output stream
*/
public ServletOutputStream getOutputStream() {
return(new StringOutputStream(stringWriter));
}
/** 返回buffer的字符串表示
*/
public String toString() {
return(stringWriter.toString());
}

2、实现ServletOutputStreanm

public class StringOutputStream extends ServletOutputStream {
private StringWriter stringWriter;//缓冲区引用 public StringOutputStream(StringWriter stringWriter) {
this.stringWriter = stringWriter;
}
/**重写OutputStream write方法
* 这个方法被ServletOutputStream调用而ServletOutputStream extends OutputStream
*/
public void write(int c) {
stringWriter.write(c);
}
}

  看一下ServletOutputStream类print方法

 public void print(String s)
throws IOException
{
if (s == null) s = "null";
int len = s.length();
for (int i = 0; i < len; i++) {
char c = s.charAt(i); if ((c & 0xFF00) != 0) {
String errMsg = lStrings.getString("err.not_iso8859_1");
Object[] errArgs = new Object[1];
errArgs[0] = new Character(c);
errMsg = MessageFormat.format(errMsg, errArgs);
throw new CharConversionException(errMsg);
}
write(c);//在这里被调用
}
}

该类中其他所有输出String信息的方法都调用了该方法  

疑问:当调用FilterChain 的doFilter方法时,怎么说就晚了呢?

  response是一个引用,当调用filterChain doFilter(或者是servlet jsp,没有其他过滤器的话)后,响应就通过这个引用写到端口上去了,所以说为时已晚

过滤器修改response的更多相关文章

  1. java使用Filter过滤器对Response返回值进行修改

    转:java使用Filter过滤器对Response返回值进行修改 练习时只做了对request 的处理,这里记录一下,filter 对 response的处理. 原文地址:java使用Filter过 ...

  2. 转:java使用Filter过滤器对Response返回值进行修改

    练习时只做了对request 的处理,这里记录一下,filter 对 response的处理. 原文地址:java使用Filter过滤器对Response返回值进行修改 有时候在开发过程中会有这样一个 ...

  3. .net中自定义过滤器对Response内容进行处理

    原文:http://www.cnblogs.com/zgqys1980/archive/2008/09/02/1281895.html 代码DEMO:http://files.cnblogs.com/ ...

  4. 测试调试-利用fiddler修改response返回结果

    测试前端过程中,经常需要验证各种功能状态.不同数据层级等返回后的展示效果.一般会通过以下三种方式进行测试: 1.构造满足条件的测试数据:(耗时费力) 2.修改数据库:(前提需要了解数据库数据存储.沟通 ...

  5. nginx处理302、303和修改response返回的header和网页内容

    背景 遇到一个限制域名的平台,于是使用nginx在做网站转发,其中目标网站在访问过程中使用了多个302.303的返回状态,以便跳转到指定目标(为什么限制,就是防止他的网站的镜像). 在查找了一段资料后 ...

  6. 10、Fiddler中设置断点修改Response

    当然Fiddler中也能修改Response 第一种:打开Fiddler 点击Rules-> Automatic Breakpoint  ->After Response  (这种方法会中 ...

  7. 通过HttpServletResponseWrapper修改response输出流

    在项目中遇到一个问题,需要对接口返回的数据进行加密给前端.项目中的controller一般都是返回一个实体form,重写的一个视图解析器继承ModelAndViewResolver,对返回的form转 ...

  8. 怎样修改Response中的内容

    重写Stream public class CatchTextStream : Stream { private Stream output; public CatchTextStream(Strea ...

  9. 3- 设置断点修改Response

    以下是借鉴别人的知识分享.我在这里转载,如有冒犯,还请告知. 只要你会设置断点修改请求内容的话,这个设置断点修改响应内容的方法也是一样的,只需要修改一下命令即可. 修改响应内容也有两种方法: 第一种: ...

随机推荐

  1. Linux中的grep 命令

    介绍grep文本处理命令,它也可以解释正则. 常用选项: -E :开启扩展(Extend)的正则表达式. -i :忽略大小写(ignore case). -v :反过来(invert),只打印没有匹配 ...

  2. python之itertools

    Python的内建模块itertools提供了非常有用的用于操作迭代对象的函数. count 创建一个迭代器,生成从n开始的连续整数,如果忽略n,则从0开始计算(注意:此迭代器不支持长整数) 如果超出 ...

  3. CDH5.16.1的Yarn提交任务默认资源分配

    1 同时运行5个Spark任务的资源分配截图 2 每个任务占用3个Container 3个core以及4.5GB内存 也就是说一个Container需要 1个core 以及 512MB的内存 如果资源 ...

  4. Linux系统下C语言获取Time

    获取时间的函数有很多,具体包括如下: time()/gettimeofday()等等,下面是获取具体到usecond的时间程序: #include <iostream> #include ...

  5. idea 注册码 2月

    https://blog.csdn.net/zhw0596/article/details/81394870 不显示.java后缀 https://segmentfault.com/q/1010000 ...

  6. 根据IP 自动识别国家和城市

    https://www.jianshu.com/p/1b1a018ae729 根据IP 自动识别国家和城市

  7. 跨站请求伪造(csrf),django的settings源码剖析,django的auth模块

    目录 一.跨站请求伪造(csrf) 1. 什么是csrf 2. 钓鱼网站原理 3. 如何解决csrf (1)思路: (2)实现方法 (3)实现的具体代码 3. csrf相关的装饰器 (1)csrf_p ...

  8. [转]C++引用

    引用的概念 引用:就是某一变量(目标)的一个别名,对引用的操作与对变量直接操作完全一样. 引用的声明方法:类型标识符 &引用名=目标变量名: 如下:定义引用ra,它是变量a的引用,即别名. i ...

  9. 【leetcode】1268. Search Suggestions System

    题目如下: Given an array of strings products and a string searchWord. We want to design a system that su ...

  10. Here is a test page for my new blog in cnblogs

    Tell me if I can use Fomula like LaTeX $$\sum\limits_{i = 1}^{n}a_i$$