Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java JAX-RS:如何在发送响应之前拦截json消息体?_Java_Json_Jakarta Ee_Jax Rs - Fatal编程技术网

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

Java JAX-RS:如何在发送响应之前拦截json消息体?,java,json,jakarta-ee,jax-rs,Java,Json,Jakarta Ee,Jax Rs,我正在创建一个只处理json的JAX-RSWeb服务。我们正在使用JAX-RS2.0和NetBeans8。所有JPA 2.1实体都有一个用于审计目的的唯一id。它不是主键。实体可能有其他关联实体的列表。我们需要确保实体和关联列表中的实体都具有相同的唯一id。如果存在差异,则审核失败 我正在试图找出处理此验证的最佳方法 我可以尝试使用反射,但这是缓慢和繁琐的 我可以创建一个写拦截器,确定实体的类型,从中获取唯一id,并扫描任何对象列表以确定是否存在差异。我不喜欢这个想法,因为我必须编写代码来验证模

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

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

我可以尝试使用反射,但这是缓慢和繁琐的

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

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

我真的很感激你对实现我的目标的最佳选择的建议

感谢您的关注、建议和时间


Mike

A
WriterInterceptor
是一个不错的选择。如果调用
context.continue()
,它将序列化实体。之后,可以在
上下文中找到结果。getOutputStream()
。由于从这个输出流中读取数据并不容易,因此您可以使用
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);
        }
    }

}

嗨,勒弗洛,非常感谢您的回复。:)我在航班之间运行,所以我没有时间深入思考代码,所以如果下面的问题是多余的,请原谅我。为了澄清,此备选方案将要求将实体序列化两次。。。首先是扫描,然后离开写作拦截器。这是正确的吗?如果是这样,有没有办法避免进行两次序列化?再次感谢您的帮助!MikeThe实体将至少写入两次
输出流
。首先在
ByteArrayOutputStream上,然后在原始流上。这是必要的,因为原始流不提供读取其内容的方法。我不认为有很大的影响,但这取决于你的实体的大小。我建议只记录需要多长时间。通常,实体并不大,实体中的任何列表都很短,所以我认为性能不会成为问题。今天下午我将快速编写代码并进行一些测试。谢谢你的帮助!