情境:
Person
实体GET /persons
返回所有人员的列表GET /persons/{id}
返回一个人现在,我希望这些API端点能够返回实体的不同表示形式:
/persons
应仅返回id
,firstName
,lastName
/persons/{id}
应返回所有字段我已经考虑过:
DTO方法:创建仅包含PersonSummary
,id
和firstName
字段的lastName
课程。然后使用Dozer(或其他映射器)从Person -> PersonSummary
复制字段。然后返回PersonSummary
对象列表。
使用javax.json.Json
:手动组合要返回的对象。但是这样我只获得了JSON,没有更多的XML :(
XML架构文件(不知道这实际上是否可行)为每个表示写一个.xsd
文件,让Jaxb处理结果表示。
到目前为止我所看到的:
在Spring中,您只需创建一个包含所有getter的interface
即可。 (比如这里(https://spring.io/blog/2014/05/21/what-s-new-in-spring-data-dijkstra)在底部)。
使用杰克逊,你可以使用@JsonView
(http://wiki.fasterxml.com/JacksonJsonViews)。
使用MOXy有@XmlNamedObjectGraphs
(https://stackoverflow.com/a/19526044/1321564)。
使用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
预期结果:
传递@MyViewAnnotation
时,会生成@XmlElement String s1
和@XmlElement String s2
。 s3
将为@XmlTransient
。
传递@MyOtherViewAnnotation
时,会在@XmlElement
上生成s1
。 s2
和s3
将为@XmlTransient
。
我不知道是否可以在正确的位置拦截JAX-RS处理以创建修改后的类,然后将该类传递给正常的JAX-RS处理。但是这样,它可以轻松完成,JAX-RS可以以相同的方式生成JSON和XML。
有什么想法吗?
答案 0 :(得分:0)
我在JAX-RS中唯一能够考虑支持此行为的是使用具有特殊内容类型的自定义MessageBodyWriter
,例如application/json+list
vs application/json+details
。然后在MessageBodyWriter
仅序列化那些特定字段。
杰克逊观点方法似乎是最适合您需求的方法,假设您使用Jackson JAX-RS提供商。您也可以使用@JsonSerialize(include=NON_NULL)
并在列表视图中将其他字段设置为null,从而获得相同的结果。然而,这仍然是杰克逊特有的解决方案。
我注意到你的其他两个解决方案,你使用了以数据库为中心的方法。我假设这个对象实际上并不在你的数据库中。