在JAX-RS过滤器中捕获响应有效负载 [英] Capture Response Payload in JAX-RS filter
问题描述
我想捕获响应日志并将其记录在JAX-RS过滤器中.这是我用来拦截响应的filter方法的代码片段. (仅供参考-我正在使用RestEasy进行实施)
I want to capture and log the response payload in JAX-RS filter. Here is the code snippet of the filter method that I'm using to intercept the response. (FYI - I'm using RestEasy for implementation)
@Override
public void filter(final ContainerRequestContext requestContext, final ContainerResponseContext responseContext) throws IOException {
...
final OutputStream out = responseContext.getEntityStream();
try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
out.write(baos.toByteArray());
....
}
}
但是,ByteArrayOutputStream却是空的.查看RestEasy代码,它使用DeferredOutputStream,但不确定在这里拉响应有效负载的重要性.我曾尝试直接写入byte [],但这也无济于事.我在这里想念什么吗?谢谢.
However, the ByteArrayOutputStream turns out be empty. Looking at the RestEasy code, it's using DeferredOutputStream, but not sure how it would matter here in pulling the response payload. I have tried writing to byte[] directly, but that doesn't help either. Am I missing anything here ? Thanks.
推荐答案
如果您不想向响应中写入更多数据,则不需要处理OutputStream.只需使用响应实体即可:
If you don't want to write more data to the response you don't need to deal with the OutputStream. Just use the response entity:
@Provider
public class SomeFilter implements ContainerResponseFilter {
private Logger LOG = LoggerFactory.getLogger(SomeFilter.class);
@Override
public void filter(ContainerRequestContext requestContext,
ContainerResponseContext responseContext) throws IOException {
LOG.info("response entity: " + responseContext.getEntity());
}
}
在调用Filter时,OutputStream为空,因为JAX-RS运行时尚未对其进行写入.过滤后,运行时将选择正确的 MessageBodyWriter 会将实体序列化到OutputStream.
The OutputStream is empty at the time the Filter is called because the JAX-RS runtime has not written to it. After your Filter the runtime will choose the correct MessageBodyWriter which will serialize the entity to the OutputStream.
您还可以使用 WriterInterceptor拦截所有MessageBodyWriters .下面的示例将ByteArrayOutputStream传递给MessageBodyWriter并随后还原原始的OutputStream:
You could also intercept all MessageBodyWriters with a WriterInterceptor. Following example passes a ByteArrayOutputStream to the MessageBodyWriter and restores the original OutputStream afterwards:
@Provider
public class ResponseInterceptor implements WriterInterceptor {
private Logger LOG = LoggerFactory.getLogger(ResponseInterceptor.class);
@Override
public void aroundWriteTo(WriterInterceptorContext context) throws IOException, WebApplicationException {
OutputStream originalStream = context.getOutputStream();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
context.setOutputStream(baos);
try {
context.proceed();
} finally {
LOG.info("response body: " + baos.toString("UTF-8"));
baos.writeTo(originalStream);
baos.close();
context.setOutputStream(originalStream);
}
}
}
这篇关于在JAX-RS过滤器中捕获响应有效负载的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!