2

我正在开发一个使用 JAX-RS、Jackson 和 JPA 的项目。JAX-RS 资源将传入的 JSON 直接映射到最终要持久化的 POJO (JPA)。

@POST
@Consumes(MediaType.APPLICATION_JSON)
public Response createEntity(Entity entity) {
   ...
}

但是,我偶尔会发现资源需要从客户端获得的信息并没有将 1:1 清晰地映射到 POJO。还有一些额外的字段提供了一些关于如何处理请求的元数据。例如,回调 URL 或未持久化的明文密码。

是否有一种优雅的方式来保存这些信息,同时仍然直接映射到 JPA 实体?

我有一些想法,但我对其中任何一个都不感兴趣:

  1. 首先映射到Map<String, Object>:然后使用 ObjectMapper 映射到配置为忽略某些属性的实体。这会导致某些资源的一些额外样板代码(为了一致性起见,可能所有使用 JSON 的资源)
  2. 使用 @Transient 字段获取额外值:这允许 Jackson 干净地映射到 POJO,但往往会使数据模型与业务逻辑混淆,而不仅仅是关注实体的状态和行为。
  3. 使用@QueryParam 获取额外值:似乎使资源接口复杂化,从客户端的角度来看似乎有点随意。

有任何想法吗?如果可以装配 JAX-RS MessageBodyReader 或某种上下文提供程序以将额外参数的 Map 作为附加参数传递给该方法,那就太好了,但我不知道这需要做多少工作。

4

1 回答 1

2

此用例通常通过在资源级别使用专用数据传输对象来处理,这些对象将由Dozer等框架映射到 JPA 实体。除了明显的样板代码外,这种方法还有一些优点:

  • 如果资源遵循HATEOAS原则,则必须使用更多的 REST 特定信息来丰富实体,例如它们自己的链接、指向其他资源的链接和分页信息。
  • 通常 REST 客户端可以选择指定实体扩展属性(出于带宽原因,实体或引用实体的哪些属性应包含在响应中),您必须至少对实体应用过滤器。

但是回到您的问题,如果您想重新使用 JPA 实体进行 JSON 映射,我认为您的想法都是有效的。您的第二个想法的另一个变体可能是将所有这些额外信息作为实体的一部分存储在映射中(将单个属性作为业务逻辑混乱而不是许多),如果您的 JPA 实体具有公共基类,则此映射可以是在那里完成。您可以使用@JsonAnySetter注释来实现这一点。

于 2013-04-30T21:15:41.593 回答