JAX-RS:如何在发送响应之前拦截json消息体?

时间:2014-08-26 04:57:22

标签: java json java-ee jax-rs

我正在创建一个仅处理json的JAX-RS Web服务。我们使用的是JAX-RS 2.0和Netbeans 8.所有JPA 2.1实体都有一个用于审计目的的唯一ID。它不是主键。实体可以具有其他关联实体的列表。我们需要确保关联列表中的实体和实体都具有相同的唯一ID。如果存在差异,则审核失败。

我正在试图找出处理此验证的最佳方法......

我可以尝试使用反射,但这很慢而且很麻烦......

我可以创建一个写拦截器,确定实体的类型,从中获取唯一的id,并扫描任何对象列表以确​​定是否存在差异。我不喜欢这个想法,因为我必须编写代码来验证模型中的每个特定实体,并在模型发生变化时维护此代码。

我最喜欢的选择是拦截在返回请求者之前生成的json。我可以简单地将字符串标记化并找到唯一的id值。如果有任何不同,我会抛出异常。这假设正在使用急切加载,这是我能想到的唯一缺点,因为这意味着我们必须始终返回完整的有效负载而不仅仅是实体。对于这个项目,我尝试使用写拦截器,但我发现该实体尚未序列化为json。所以,我不知道如何在json返回给调用者之前拦截json。

我非常感谢您对实现目标的最佳选择的建议。

感谢您的关注,建议和时间。

麦克

1 个答案:

答案 0 :(得分:4)

WriterInterceptor是个不错的选择。如果您致电context.proceed(),它会对该实体进行序列化。 之后,可以在context.getOutputStream()中找到结果。由于从这个OutputStream中读取起来并不容易,您可以使用ByteArrayOutputStream来序列化并恢复原始流:

@Provider
public class ResponseInterceptor implements WriterInterceptor {

    @Override
    public void aroundWriteTo(WriterInterceptorContext context) throws IOException, WebApplicationException {
        OutputStream originalStream = context.getOutputStream();
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        context.setOutputStream(baos);
        try {
            context.proceed();
        } finally {
            // search in the response, e.g.
            JsonNode response = new ObjectMapper().readTree(baos.toByteArray());
            // ...
            // write to and restore the original Stream
            baos.writeTo(originalStream);
            baos.close();
            context.setOutputStream(originalStream);
        }
    }

}
相关问题