对sevletresponse的输出内容一般情况下,只能追加一些内容,但不能得到输出的内容,很典型的比如在过滤器里面
public void doFilter(ServletRequest req, ServletResponse res,
FilterChain chain) throws IOException, ServletException {
chain.doFilter(req, res);
}
要得到 chain.doFilter(req, res)里输出的内容,在后面的流程里处理,这个仅靠servletresponse是得不到的,因为
servletresponse的输出方向已经固定了,根本就不能截获,也没有相关api调用。在这里,有一个方案,那就是实现一个servletresponse代理,将servletresponse作为参数传进去,先保存当前的字符流,然后再调用servletresponse输出,因为servletresponse输出实际上调用的是PrintWriter的
public void write(char[] buf, int off, int len),因此PrintWriter也要实现代理。又因为servlet,jsp都是多线程方式工作的,因为过滤器也是的,那么存储的内容必须按线程存取。
全部代码实现如下
一:SservletResponse代理
package com.ipanel.usermanage.communicate.http;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Locale;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
/**
* HttpServletResponse代理
* @author wangxiaoxue
* @time Aug 1, 2007 11:38:22 AM
*/
public class ServletResponseProxy implements HttpServletResponse {
private HttpServletResponse obj;//实际的HttpServletResponse 实例
public ServletResponseProxy(HttpServletResponse obj) {
this.obj = obj;
HtmlBuffer.cleanStr(); //清空缓存
}
/**
* 获得printWriterProxy
*/
public PrintWriter getWriter() throws IOException {
PrintWriter pw = obj.getWriter();
PrintWriterProxy pwp = new PrintWriterProxy(pw);
return (PrintWriter) pwp;
}
public void addCookie(Cookie arg0) {
// TODO Auto-generated method stub
}
public void addDateHeader(String arg0, long arg1) {
// TODO Auto-generated method stub
}
public void addHeader(String arg0, String arg1) {
// TODO Auto-generated method stub
}
public void addIntHeader(String arg0, int arg1) {
// TODO Auto-generated method stub
}
public boolean containsHeader(String arg0) {
// TODO Auto-generated method stub
return false;
}
public String encodeRedirectURL(String arg0) {
// TODO Auto-generated method stub
return null;
}
public String encodeRedirectUrl(String arg0) {
// TODO Auto-generated method stub
return null;
}
public String encodeURL(String arg0) {
// TODO Auto-generated method stub
return null;
}
public String encodeUrl(String arg0) {
// TODO Auto-generated method stub
return null;
}
public void sendError(int arg0) throws IOException {
// TODO Auto-generated method stub
}
public void sendError(int arg0, String arg1) throws IOException {
// TODO Auto-generated method stub
}
public void sendRedirect(String arg0) throws IOException {
// TODO Auto-generated method stub
}
public void setDateHeader(String arg0, long arg1) {
// TODO Auto-generated method stub
}
public void setHeader(String arg0, String arg1) {
// TODO Auto-generated method stub
}
public void setIntHeader(String arg0, int arg1) {
// TODO Auto-generated method stub
}
public void setStatus(int arg0) {
// TODO Auto-generated method stub
}
public void setStatus(int arg0, String arg1) {
// TODO Auto-generated method stub
}
public void flushBuffer() throws IOException {
// TODO Auto-generated method stub
}
public int getBufferSize() {
// TODO Auto-generated method stub
return 0;
}
public String getCharacterEncoding() {
// TODO Auto-generated method stub
return null;
}
public String getContentType() {
// TODO Auto-generated method stub
return null;
}
public Locale getLocale() {
// TODO Auto-generated method stub
return null;
}
public boolean isCommitted() {
// TODO Auto-generated method stub
return false;
}
public void reset() {
// TODO Auto-generated method stub
}
public void resetBuffer() {
// TODO Auto-generated method stub
}
public void setBufferSize(int arg0) {
// TODO Auto-generated method stub
}
public void setCharacterEncoding(String arg0) {
// TODO Auto-generated method stub
}
public void setContentLength(int arg0) {
// TODO Auto-generated method stub
}
public void setContentType(String arg0) {
// TODO Auto-generated method stub
}
public void setLocale(Locale arg0) {
// TODO Auto-generated method stub
}
public ServletOutputStream getOutputStream() throws IOException {
// TODO Auto-generated method stub
return null;
}
}
二:PrintWriter代理
package com.ipanel.usermanage.communicate.http;
import java.io.PrintWriter;
/**
* PrintWriter代理,输出用的是public void write(char[] buf, int off, int len)
* @author wangxiaoxue
* @time Aug 1, 2007 11:38:47 AM
*/
public class PrintWriterProxy extends PrintWriter {
private PrintWriter pw = null;
public PrintWriterProxy(PrintWriter pw) {
super(pw);
this.pw = pw;
}
/**
* 截获写内容写入buffer
*/
public void write(int c) {
char a = (char) c;
String s = new String(new char[] {a});
HtmlBuffer.addStr(s);
pw.write(c);
}
/**
* 截获写内容写入buffer
*/
public void write(char[] buf) {
String s = new String(buf);
HtmlBuffer.addStr(s);
pw.write(buf);
}
/**
* 截获写内容写入buffer
*/
public void write(String s) {
HtmlBuffer.addStr(s);
pw.write(s);
}
/**
* 截获写内容写入buffer
*/
public void write(char[] buf, int off, int len) {
String s=buf.toString();
StringBuffer sf=new StringBuffer("");
int size=off+len;
for(int i=off;i<size;i++){
sf.append(buf[i]);
}
s=sf.toString();
HtmlBuffer.addStr(s);
pw.write(buf,off,len);
}
/**
* 截获写内容写入buffer
*/
public void write(String s, int off, int len) {
s=s.substring(off,off+len);
HtmlBuffer.addStr(s);
pw.write(s,off,len);
}
}
三:截获的字符缓冲区
package com.ipanel.usermanage.communicate.http;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
/**
* html缓冲区
* @author wangxiaoxue
* @time Aug 1, 2007 11:45:32 AM
*/
public class HtmlBuffer {
private static class HtmlInfo extends ThreadLocal {
private Map values = Collections.synchronizedMap(new HashMap());
public Object initialValue() {
return new String();
}
public String getHtmlStr() {
return (String) this.get();
}
public Object get() {
Thread curThread = Thread.currentThread();
Object o = values.get(curThread);
if (o == null && !values.containsKey(curThread)) {
o = initialValue();
values.put(curThread, o);
}
return o;
}
public void set(Object newValue) {
values.put(Thread.currentThread(), newValue);
}
}
private static HtmlInfo htmlInfo = new HtmlInfo();
public static void cleanStr(){
htmlInfo.set( "");
}
public static void addStr(String htmlStr) {
String htmlstr = (String)htmlInfo.get();
if(htmlstr == null) htmlstr ="";
htmlstr += htmlStr;
htmlInfo.set( htmlstr);
}
public static String getStr() {
return (String)htmlInfo.get();
}
}
那么再在过滤器里调用就可以这样子
public void doFilter(ServletRequest req, ServletResponse res,
FilterChain chain) throws IOException, ServletException {
chain.doFilter(req, new ServletResponseProxy((HttpServletResponse)res));
}
可以调用HtmlBuffer的getStr方法得到刚才向客户端输出的内容,将其打印出来,如
public void doFilter(ServletRequest req, ServletResponse res,
FilterChain chain) throws IOException, ServletException {
chain.doFilter(req, new ServletResponseProxy((HttpServletResponse)res));
System.out.println(HtmlBuffer.getStr());
}