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

A B*_*elp 4 java json jax-rs java-ee

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

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

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

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

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

我非常感谢您提出的关于实现我的目标的最佳选择的建议。

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

麦克风

lef*_*loh 6

A WriterInterceptor是一个不错的选择。如果您调用,它将序列化实体context.proceed()之后,可以在中找到结果context.getOutputStream()。由于不容易从此OutputStream中读取内容,因此可以使用a 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);
        }
    }

}
Run Code Online (Sandbox Code Playgroud)