Filter对Response的改变:HttpServletResponseWrapper的工作原理
7)Filter对Response的改变:HttpServletResponseWrapper的工作原理
马 克-to-win:前面我们讲的知识,主要说的是由于Filter的参与,用户的访问路径被改变的问题。底下我们就要讲一点更难的话题,就是Filter 如何改变一个现有的html。比如我写的新浪博客,写完以后,一上传,内容有时有些改变,谁动的手脚?肯定是新浪公司编了什么Filter过滤器,把我的 html的内容给改变了。马克-to-win:现在问题是:这是如何实现的呢?这里核心问题其实就是如何改变Response?本来我的html在原来的 Response里,准备返回给客户端。但现在在Filter当中被改变了。但这又是怎么改变的呢?这里涉及到一个 HttpServletResponseWrapper的类实例myWrapper问题。Wrapper英文就是包裹者的意思。正常情况下,我们过去的认 识是:chain.doFilter(request, response);的意思就是访问完后面的目标资源以后,目标资源把要返回给客户端的内容放在Response当中。而现在这里的例子就不同了:通过 chain.doFilter(request, myWrapper);目标资源就会把 要返回给客户端的内容放在myWrapper当中了。这时在Filter当中,我们就可以从myWrapper当中取出返回给客户端的内容,接着就可以大 大方方的对其进行改变了。要想做成这件事儿,当然还得符合sun公司制定的有关HttpServletResponseWrapper的所有规章制度。首 先通过MarkToWinWrapper myWrapper = new MarkToWinWrapper((HttpServletResponse) response);让response和myWrapper联系起来。马克-to-win:之后,在我编的MarkToWinWrapper这个普通类 当中,需要初始化一个CharArrayWriter的实例:myContent = new CharArrayWriter();和PrintWriter的实例pw=new PrintWriter(myContent);之后通过编写public PrintWriter getWriter() { return pw; }。当你执行chain.doFilter(request, myWrapper);时,系统其中一步会调用getWriter(),得到pw以后,就会把你myWrapper构造函数里得到的response和CharArrayWriter的实例:myContent联系起来。 最后当你执行 public String getResultMarkToWin() { return myContent.toString(); }时,返回给客户端的内容就被你得到了,因为response和myContent已经被你联系起来了。注意要想正确应用 HttpServletResponseWrapper,必须遵守它的规则。下面的例子把AAA.html的“淘宝”俩字儿都变成了“百度”。
例 1.2.7
AAA.html
既然这是首页,像淘宝首页一样,这底下是首页的一些泛泛信息。
package com;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;
public class MarkToWinFilter implements Filter {
public void destroy() {
}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
response.setCharacterEncoding("GBK");
PrintWriter out = response.getWriter();
MarkToWinWrapper myWrapper = new MarkToWinWrapper(
(HttpServletResponse) response);
/*下句话之后目标jsp的东西都装在myWrapper中了,不像Hello World的filter,那时都装在response的out中,本例到目前为止,out是空的*/
chain.doFilter(request, myWrapper);
String result=myWrapper.getResultMarkToWin();
System.out.println("content : " +result );
result=result.replace("淘宝", "百度");
out.println("content : " + result);
}
public void init(FilterConfig fConfig) throws ServletException {
}
}
更多内容请见原文,原文转载自:https://blog.csdn.net/qq_44638460/article/details/104087849