使用JAX-RS和Jackson映射额外参数

时间:2013-04-30 06:39:57

标签: java java-ee jpa jackson jax-rs

我正在开发一个使用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获取额外值:似乎使资源的界面复杂化,从客户角度来看似乎是任意的。
  4. 有什么想法吗?如果可以装配JAX-RS MessageBodyReader或某种上下文提供程序来传递额外参数的Map作为方法的附加参数,那将是很好的,但我不知道这将是多少工作。

1 个答案:

答案 0 :(得分:2)

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

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

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