在JAX-RS过滤器中捕获响应有效负载 [英] Capture Response Payload in JAX-RS filter

查看:74
本文介绍了在JAX-RS过滤器中捕获响应有效负载的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想捕获响应日志并将其记录在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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆