是否可以在春季启动中读取响应的正文?



我有一个来自HttpServletResponsePrintWriter,我想知道是否有任何方法可以读取它的缓冲区(考虑到HttpServletResponse.getWriter()PrintWriter不是自动刷新的(。

我知道有一些方法可以通过InputStream.transferTo()将输入流转换为输出流,但是有没有办法以另一种方式将我的PrintWriter转换为任何类型的输出流?或者有什么方法可以读取HttpServletResponse的响应正文?

到目前为止,我已经尝试了未覆盖的toString()方法。我试图通过不同的流(如PipedInputStreamByteArrayOutputStream(通过管道传输它。

顺便说一句,我正在使用弹簧启动微服务架构。

我终于找到了一种方法,通过覆盖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>

相关内容

最新更新