JAX-RS - 如何获得资源的多个表示/投影?

时间:2014-08-10 19:24:50

标签: java-ee jaxb jax-rs projection jaxb2

情境:

  • 它是使用普通JavaEE 7的REST API
  • 有一个Person实体
  • GET /persons返回所有人员的列表
  • GET /persons/{id}返回一个人

现在,我希望这些API端点能够返回实体的不同表示形式:

  • /persons应仅返回idfirstNamelastName
  • /persons/{id}应返回所有字段

我已经考虑过:

  • DTO方法:创建仅包含PersonSummaryidfirstName字段的lastName课程。然后使用Dozer(或其他映射器)从Person -> PersonSummary复制字段。然后返回PersonSummary对象列表。

  • 使用javax.json.Json手动组合要返回的对象。但是这样我只获得了JSON,没有更多的XML :(

  • XML架构文件(不知道这实际上是否可行)为每个表示写一个.xsd文件,让Jaxb处理结果表示。

到目前为止我所看到的:


使用JavaEE有一种(简单)方法吗?或者是否有一些不错的外部库?


编辑:运行时注释操作

您如何看待这个想法(这基本上就像杰克逊的@JsonView一样):

@XmlRootElement
public class MyClass {
  @MyViewAnnotation @MyOtherViewAnnotation
  String s1;

  String s2;

  @MyViewAnnotation
  String s3;
}

该怎么办? (伪代码)

// resource object comes from some JAX-RS interceptor along
// with the preferred view annotation (in this case @MyViewAnnotation)

Annotation viewAnnotation = @MyViewAnnotation;

for(Field f : resource) {
  if(f.hasAnnotation(viewAnnotation)) {
    f.addAnnotation(@XmlElement);
  } else {
    f.addAnnotation(@XmlTransient);
  }
}

// return manipulated resource object back to JAX-RS

预期结果:

  1. 传递@MyViewAnnotation时,会生成@XmlElement String s1@XmlElement String s2s3将为@XmlTransient

  2. 传递@MyOtherViewAnnotation时,会在@XmlElement上生成s1s2s3将为@XmlTransient

  3. 我不知道是否可以在正确的位置拦截JAX-RS处理以创建修改后的类,然后将该类传递给正常的JAX-RS处理。但是这样,它可以轻松完成,JAX-RS可以以相同的方式生成JSON和XML。

    有什么想法吗?

1 个答案:

答案 0 :(得分:0)

我在JAX-RS中唯一能够考虑支持此行为的是使用具有特殊内容类型的自定义MessageBodyWriter,例如application/json+list vs application/json+details。然后在MessageBodyWriter仅序列化那些特定字段。

杰克逊观点方法似乎是最适合您需求的方法,假设您使用Jackson JAX-RS提供商。您也可以使用@JsonSerialize(include=NON_NULL)并在列表视图中将其他字段设置为null,从而获得相同的结果。然而,这仍然是杰克逊特有的解决方案。

我注意到你的其他两个解决方案,你使用了以数据库为中心的方法。我假设这个对象实际上并不在你的数据库中。