Java JAX-RS:如何在发送响应之前拦截json消息体?
我正在创建一个只处理json的JAX-RSWeb服务。我们正在使用JAX-RS2.0和NetBeans8。所有JPA 2.1实体都有一个用于审计目的的唯一id。它不是主键。实体可能有其他关联实体的列表。我们需要确保实体和关联列表中的实体都具有相同的唯一id。如果存在差异,则审核失败 我正在试图找出处理此验证的最佳方法 我可以尝试使用反射,但这是缓慢和繁琐的 我可以创建一个写拦截器,确定实体的类型,从中获取唯一id,并扫描任何对象列表以确定是否存在差异。我不喜欢这个想法,因为我必须编写代码来验证模型中的每个特定实体,并在模型更改时维护这些代码 我最喜欢的选择是截取在返回给请求者之前生成的json。我可以简单地标记字符串并找到唯一的id值。如果有不同,我会抛出一个异常。这假设正在使用渴望加载,这是我能想到的唯一缺点,因为这意味着我们必须始终返回完整的负载,而不仅仅是实体。对于这个项目,我尝试使用一个写拦截器,但是我发现实体还没有被序列化为json。因此,我不知道如何在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,并扫描任何对象列表以确定是否存在差异。我不喜欢这个想法,因为我必须编写代码来验证模
MikeA
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上,然后在原始流上。这是必要的,因为原始流不提供读取其内容的方法。我不认为有很大的影响,但这取决于你的实体的大小。我建议只记录需要多长时间。通常,实体并不大,实体中的任何列表都很短,所以我认为性能不会成为问题。今天下午我将快速编写代码并进行一些测试。谢谢你的帮助!