java - 是否可以在 Spring Boot 中读取响应的正文?
问题描述
我有一个PrintWriter
from an HttpServletResponse
,我想知道是否有任何方法可以读取它的缓冲区(考虑到HttpServletResponse.getWriter()
PrintWriter 不是自动刷新的)。
我知道有一些方法可以将 InputStream 转换为 OutputStream,InputStream.transferTo()
但是有没有其他方法可以将我的 PrintWriter 转换为任何类型的 OutputStream?或者有什么方法可以读取一个响应体HttpServletResponse
?
到目前为止,我已经尝试过toString()
没有被覆盖的方法。我试图通过不同的流(如PipedInputStream
和)来传递它ByteArrayOutputStream
。
顺便说一句,我正在使用 Spring Boot 微服务架构。
解决方案
我终于找到了一种通过spring bootFilter
通过覆盖来处理这个问题的方法HttpServletResponseWrapper
。所以这是我的代码(覆盖将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 类(将流的内容复制到 a 中的类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>
推荐阅读
- .net - Trace.CorrelationManager.ActivityId 的 ECS 字段引用中的等价物是什么?
- c# - C# 使用动态键反序列化 JSON
- microservices - 微服务:数据共享与 API 组合
- debugging - 链接独立可执行文件时对“core:fmt::write”的未定义引用
- github - 我可以从 GitHub Dependabot 中排除目录吗?
- c - 从c中的二叉树中获取最小的三个数字
- xml - Xquery 中的嵌套循环会导致不匹配?和成语
- java - LWJGL: Buffer Memory Management
- pthreads - pthread_spin_lock() 和 pthread_spin_unlock() 函数的 glibc 实现是否有内存栅栏指令?
- c++ - 如何在 Gtk 条目中删除插入符号光标