I have a PrintWriter
from an HttpServletResponse
and I would like to know if there is any way to read its buffer (considering the HttpServletResponse.getWriter()
PrintWriter isn't auto-flushed).
I know there are some ways to transform an InputStream to an OutputStream through InputStream.transferTo()
but is there any way to do it in the other way and to convert my PrintWriter to any type of OutputStream? Or is there any way just to read the response body of an HttpServletResponse
?
So far I've tried the toString()
method which is not overwritten. I tried to pipe it through different streams like PipedInputStream
and ByteArrayOutputStream
.
I'm using spring boot microservices architecture btw.
I finally found a way to handle this through spring boot Filter
by overriding HttpServletResponseWrapper
. so here's my code (the class that overrides the HttpServletResponseWrapper
to change the response default output stream to my custom 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;
}
}
and my ServletOutputStreamCopier class (the class that copies the content of the stream into 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();
}
}
and finally inject it into the spring boot filter:
@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());
}
}
which outputs this:
"body": <response body here>
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.