您的位置:首页 > Web前端 > JavaScript

使用filter拦截servlet和jsp页面的内容,进行过滤后输出

2012-09-17 08:54 901 查看
思路:使用filter拦截servlet或者jsp页面内容,比如内容替换,再向用户展现修改后的页面

使用普通的filter拦截页面内容,会出现这种情况

从入中可以看出,输出内容并没有通过过滤器就输出了。


从入中可以看出,输出内容并没有通过过滤器就输出了。

既然使用普通filter不能达到目的,那么就换一种方法,在Servlet或者jsp接收到response之前,将response使用一个“假的response”替换,让servlet或者jsp的内容输出到这个“假的response”中,然后再对输出内容进行处理,最后再将整个通过真的response输出给客户端

图示如下:



实现上图的步骤:

1.创建一个filter--用来使用"假的response"替换掉实际的response

2.创建一个“假的response"--继承HttpServletResponseWrapper类即可

3.在filter进行替换内容和实际输出

主要类的代码如下:

filter:

public class ContentChangeFilter implements Filter{

public void destroy() {

}

public void doFilter(ServletRequest request, ServletResponse response, FilterChain fc) throws IOException, ServletException {
CoverResponse cr = new CoverResponse((HttpServletResponse)response);
fc.doFilter(request, cr);
//处理替换
String content = cr.getContent();
content = content.replace("test", "actual");
response.getWriter().print(content);
}

public void init(FilterConfig arg0) throws ServletException {

}
}


假的resonse:

public class CoverResponse extends HttpServletResponseWrapper{
private MyPrintWriter tmpWriter;
private ByteArrayOutputStream output;

public CoverResponse(HttpServletResponse response) {
super(response);
output = new ByteArrayOutputStream();
tmpWriter = new MyPrintWriter(output);
}

public void finalize() throws Throwable {
super.finalize();
output.close();
tmpWriter.close();
}

public String getContent() {
try {
tmpWriter.flush();   //刷新该流的缓冲,详看java.io.Writer.flush()
String s = tmpWriter.getByteArrayOutputStream().toString("UTF-8");
//此处可根据需要进行对输出流以及Writer的重置操作
//比如tmpWriter.getByteArrayOutputStream().reset()
return s;
} catch (UnsupportedEncodingException e) {
return "UnsupportedEncoding";
}
}

//覆盖getWriter()方法,使用我们自己定义的Writer
public PrintWriter getWriter() throws IOException {
return tmpWriter;
}

public void close() throws IOException {
tmpWriter.close();
}

//自定义PrintWriter,为的是把response流写到自己指定的输入流当中
//而非默认的ServletOutputStream
private static class MyPrintWriter extends PrintWriter {
ByteArrayOutputStream myOutput;   //此即为存放response输入流的对象
public MyPrintWriter(ByteArrayOutputStream output) {
super(output);
myOutput = output;
}
public ByteArrayOutputStream getByteArrayOutputStream() {
return myOutput;
}
}
}


功能是将输出页面中的test替换为actual.

经过测试发现,如果向“假的response”添加cookie,是可以将cookie正常放到客户端的。这可能也是为什么创建“假的response”需要原response的一个引用的原因之一吧。

modify 2012-09-20

经过实际使用,发现使用字符流作为PrintWriter的目的地会造成乱码的情况,鉴于反复编码比较困难,所以使用更简单的StringWriter作为输出目的地。

package com.aspire.pams.tag.sichuan.tools;

import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;

import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;

public class CoverResponse extends HttpServletResponseWrapper{
private PrintWriter tmpWriter;
private StringWriter output;

public CoverResponse(HttpServletResponse response) {
super(response);
output = new StringWriter();
tmpWriter = new PrintWriter(output);
}

public void finalize() throws Throwable {
super.finalize();
output.close();
tmpWriter.close();
}

public String getContent() {
tmpWriter.flush();   //刷新该流的缓冲,详看java.io.Writer.flush()
String s = output.toString();
//此处可根据需要进行对输出流以及Writer的重置操作
//比如tmpWriter.getByteArrayOutputStream().reset()
return s;
}

//覆盖getWriter()方法,使用我们自己定义的Writer
public PrintWriter getWriter() throws IOException {
return tmpWriter;
}

public void close() throws IOException {
tmpWriter.close();
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐