我有一个来自HttpServletResponse
的PrintWriter
,我想知道是否有任何方法可以读取它的缓冲区(考虑到HttpServletResponse.getWriter()
PrintWriter不是自动刷新的(。
我知道有一些方法可以通过InputStream.transferTo()
将输入流转换为输出流,但是有没有办法以另一种方式将我的PrintWriter转换为任何类型的输出流?或者有什么方法可以读取HttpServletResponse
的响应正文?
到目前为止,我已经尝试了未覆盖的toString()
方法。我试图通过不同的流(如PipedInputStream
和ByteArrayOutputStream
(通过管道传输它。
顺便说一句,我正在使用弹簧启动微服务架构。
我终于找到了一种方法,通过覆盖HttpServletResponseWrapper
来通过春季启动Filter
来处理这个问题。 所以这是我的代码(覆盖HttpServletResponseWrapper
将响应默认输出流更改为我的自定义ServletOutputStream
的类(:
public class HttpServletResponseCopier extends HttpServletResponseWrapper {
private ServletOutputStreamCopier copier;
private ServletOutputStream outputStream;
private PrintWriter writer;
/**
* @param response
*/
public HttpServletResponseCopier(HttpServletResponse response) {
super(response);
}
@Override
public ServletOutputStream getOutputStream() throws IOException
{
if (outputStream != null)
throw new IOException("output stream already called for this response");
else {
outputStream = getResponse().getOutputStream();
copier = new ServletOutputStreamCopier(this.outputStream);
return copier;
}
}
@Override
public PrintWriter getWriter() throws IOException
{
if (outputStream != null)
throw new IOException("print writer already called for this response");
else {
outputStream = getResponse().getOutputStream();
copier = new ServletOutputStreamCopier(outputStream);
writer = new PrintWriter(new OutputStreamWriter(copier, getResponse().getCharacterEncoding()));
return writer;
}
}
@Override
public void flushBuffer() throws IOException
{
if (writer != null)
writer.flush();
else if (copier != null)
copier.flush();
}
public String getContent()
{
String content = "";
try {
content = IOUtils.toString(copier.getCopyBuffer(), getResponse().getCharacterEncoding());
} catch (IOException e) {
e.printStackTrace();
}
return content;
}
}
和我的 ServletOutputStreamCopier 类(将流的内容复制到ByteArrayOutputStream
中的类(:
public class ServletOutputStreamCopier extends ServletOutputStream {
private ServletOutputStream outputStream;
private ByteArrayOutputStream copier;
/**
*
*/
public ServletOutputStreamCopier(ServletOutputStream outputStream) {
super();
this.outputStream = outputStream;
this.copier = new ByteArrayOutputStream();
}
@Override
public boolean isReady()
{
return this.outputStream.isReady();
}
@Override
public void setWriteListener(WriteListener listener)
{
}
@Override
public void write(int b) throws IOException
{
if (this.copier == null)
this.copier = new ByteArrayOutputStream();
if (this.outputStream == null)
throw new IOException("outputStream is null");
this.copier.write(b);
this.outputStream.write(b);
}
public byte[] getCopyBuffer()
{
return this.copier.toByteArray();
}
}
最后注入弹簧引导过滤器:
@Component
public class LoggingFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(
HttpServletRequest request,
HttpServletResponse response,
FilterChain filterChain
) throws ServletException, IOException
{
HttpServletResponseCopier responseWrapper = new HttpServletResponseCopier(response);
filterChain.doFilter(request, responseWrapper);
System.out.println("response body: "+responseWrapper.getContent());
}
}
输出以下内容:
"body": <response body here>