如何读取和复制HTTP Servlet响应输出流内容以进行日志记录

我已经在Java网络服务器(实际上是appengine)中创建了一个过滤器,用于记录传入请求的参数。我还想记录我的网络服务器写入的结果响应。尽管我可以访问响应对象,但是我不确定如何从中获取实际的字符串/内容响应。

有任何想法吗?

回答:

你需要创建一个,在Filter其中ServletResponse用自定义HttpServletResponseWrapper实现包装参数,在其中覆盖getOutputStream()getWriter()并返回一个自定义ServletOutputStream实现,在该实现中你将写入的字节复制到基本抽象OutputStream#write(int b)方法中。然后,你将包装的自定义传递HttpServletResponseWrapperFilterChain#doFilter()调用,最后,你应该能够在调用之后获得复制的响应。

换句话说Filter:

@WebFilter("/*")

public class ResponseLogger implements Filter {

@Override

public void init(FilterConfig config) throws ServletException {

// NOOP.

}

@Override

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException {

if (response.getCharacterEncoding() == null) {

response.setCharacterEncoding("UTF-8"); // Or whatever default. UTF-8 is good for World Domination.

}

HttpServletResponseCopier responseCopier = new HttpServletResponseCopier((HttpServletResponse) response);

try {

chain.doFilter(request, responseCopier);

responseCopier.flushBuffer();

} finally {

byte[] copy = responseCopier.getCopy();

System.out.println(new String(copy, response.getCharacterEncoding())); // Do your logging job here. This is just a basic example.

}

}

@Override

public void destroy() {

// NOOP.

}

}

习惯HttpServletResponseWrapper:

public class HttpServletResponseCopier extends HttpServletResponseWrapper {

private ServletOutputStream outputStream;

private PrintWriter writer;

private ServletOutputStreamCopier copier;

public HttpServletResponseCopier(HttpServletResponse response) throws IOException {

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();

copier = new ServletOutputStreamCopier(outputStream);

}

return copier;

}

@Override

public PrintWriter getWriter() throws IOException {

if (outputStream != null) {

throw new IllegalStateException("getOutputStream() has already been called on this response.");

}

if (writer == null) {

copier = new ServletOutputStreamCopier(getResponse().getOutputStream());

writer = new PrintWriter(new OutputStreamWriter(copier, getResponse().getCharacterEncoding()), true);

}

return writer;

}

@Override

public void flushBuffer() throws IOException {

if (writer != null) {

writer.flush();

} else if (outputStream != null) {

copier.flush();

}

}

public byte[] getCopy() {

if (copier != null) {

return copier.getCopy();

} else {

return new byte[0];

}

}

}

习惯ServletOutputStream:

public class ServletOutputStreamCopier extends ServletOutputStream {

private OutputStream outputStream;

private ByteArrayOutputStream copy;

public ServletOutputStreamCopier(OutputStream outputStream) {

this.outputStream = outputStream;

this.copy = new ByteArrayOutputStream(1024);

}

@Override

public void write(int b) throws IOException {

outputStream.write(b);

copy.write(b);

}

public byte[] getCopy() {

return copy.toByteArray();

}

}

以上是 如何读取和复制HTTP Servlet响应输出流内容以进行日志记录 的全部内容, 来源链接: utcz.com/qa/433327.html

回到顶部