Hola usuario de nuestro sitio, tenemos la solución a tu interrogante, continúa leyendo y la hallarás más abajo.
Solución:
Necesitas crear un Filter
donde envuelves el ServletResponse
argumento con una costumbre HttpServletResponseWrapper
implementación en la que anula el getOutputStream()
y getWriter()
para devolver una costumbre ServletOutputStream
implementación en la que copia los bytes escritos en el resumen base OutputStream#write(int b)
método. Luego, pasas la costumbre envuelta HttpServletResponseWrapper
al FilterChain#doFilter()
llamar en su lugar y finalmente debería poder obtener la respuesta copiada después el la llamada.
En otras palabras, el 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.
La costumbre 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];
La costumbre 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();
La solución BalusC está bien, pero un poco desactualizada. Spring ahora tiene una función para ello. Todo lo que necesitas hacer es usar [ContentCachingResponseWrapper]
, que tiene método public byte[] getContentAsByteArray()
.
Sugiero hacer WrapperFactory que permitirá que sea configurable, ya sea para usar ResponseWrapper predeterminado o ContentCachingResponseWrapper.
En lugar de crear HttpServletResponseWrapper personalizado, puede usar ContentCachingResponseWrapper ya que proporciona el método getContentAsByteArray ().
public void doFilterInternal(HttpServletRequest servletRequest, HttpServletResponse servletResponse,
FilterChain filterChain) throws IOException, ServletException
HttpServletRequest request = servletRequest;
HttpServletResponse response = servletResponse;
ContentCachingRequestWrapper requestWrapper = new ContentCachingRequestWrapper(request);
ContentCachingResponseWrapper responseWrapper =new ContentCachingResponseWrapper(response);
try
super.doFilterInternal(requestWrapper, responseWrapper, filterChain);
finally
byte[] responseArray=responseWrapper.getContentAsByteArray();
String responseStr=new String(responseArray,responseWrapper.getCharacterEncoding());
System.out.println("string"+responseStr);
/*It is important to copy cached reponse body back to response stream
to see response */
responseWrapper.copyBodyToResponse();
Aquí tienes las reseñas y valoraciones
Si para ti ha resultado útil nuestro post, nos gustaría que lo compartas con más seniors y nos ayudes a extender nuestro contenido.