spring mvc架构的web应用中,spring框架将数据model渲染至jsp页面并将最终结果输出到客户端,model和jsp模板可以由程序定义,但是页面渲染及结果输出过程是由spring封装,对程序员来说是不可控的。想要取得输出的内容有一种方法就是自定义ServletOutputStream对象,在数据写入至目标流同时写入我们自定义的字节流,通过字节流便可取得输出内容。代码如下:
public class CustomServletOutputStream extends ServletOutputStream {
private OutputStream outputStream;
private ByteArrayOutputStream byteArrayOutputStream;
public CustomServletOutputStream(OutputStream outputStream){
this.outputStream=outputStream;
byteArrayOutputStream=new ByteArrayOutputStream();
}
@Override
public boolean isReady() {
return false;
}
@Override
public void setWriteListener(WriteListener writeListener) {
}
@Override
public void write(int b) throws IOException {
outputStream.write(b);
byteArrayOutputStream.write(b);
}
public byte[] getCopy(){
return byteArrayOutputStream.toByteArray();
}
}
自定义response类为获取字节流数据提供接口
public class CustomHttpServletResponse extends HttpServletResponseWrapper {
private ServletOutputStream outputStream;
private PrintWriter writer;
private CustomServletOutputStream cout;
/**
* Constructs a response adaptor wrapping the given response.
*
* @throws IllegalArgumentException
* if the response is null
*/
public CustomHttpServletResponse(HttpServletResponse response) {
super(response);
}
@Override
public ServletOutputStream getOutputStream() throws IOException {
if (writer != null) {
throw new IllegalStateException("getWriter() has already been called on this response.");
}
if (outputStream == null) {
outputStream = getResponse().getOutputStream();
cout = new CustomServletOutputStream(outputStream);
}
return cout;
}
@Override
public PrintWriter getWriter() throws IOException {
if (outputStream != null) {
throw new IllegalStateException("getOutputStream() has already been called on this response.");
}
if (writer == null) {
cout = new CustomServletOutputStream(getResponse().getOutputStream());
writer = new PrintWriter(new OutputStreamWriter(cout, getResponse().getCharacterEncoding()), true);
}
return writer;
}
@Override
public void flushBuffer() throws IOException {
if (writer != null) {
writer.flush();
} else if (outputStream != null) {
cout.flush();
}
}
public byte[] getCopy() {
if (cout != null) {
return cout.getCopy();
} else {
return new byte[0];
}
}
}
Filter类
public class LXCFFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest hrequest=(HttpServletRequest)request;
CustomHttpServletResponse cresponse=new CustomHttpServletResponse((HttpServletResponse)response);
chain.doFilter(request,cresponse);
// cresponse.flushBuffer();
byte[] data=cresponse.getCopy();
String htmStr=new String(data,response.getCharacterEncoding());
//do something
}
@Override
public void destroy() {
}
}
在web.xml中添加filter
<filter>
<filter-name>lxcfFilter</filter-name>
<filter-class>com.gtan.lxcf.common.LXCFFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>lxcfFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
参考链接 http://stackoverflow.com/questions/8933054/how-to-log-response-content-from-a-java-web-server