我正在开发一个RESTful Web服务。
我有一堆实体类(主要是JPA实体,还有其他bean)。
有很多对象映射,序列化,绑定和诸如此类的库。我正在寻找一个能让我:
的人将实体序列化为XML和JSON
序列化必须支持使用 getters ,而不仅仅是对象字段。
必须支持观看次数。通过视图,我指的是指定要序列化的实体属性的子集的方法。有关示例,请参阅Yahoo!中的Retrieving Partial Resources。社交平台API。我也不希望它无限期地递归:
视图应该定义a)要在实体中公开的属性,以及b)每个属性的视图(如果它们本身就是实体)。
例如,实体Person
可能包含观看次数full
和simple
。在请求simple
的{{1}}视图时,只会对属性Person
,id
和firstName
进行序列化。在请求lastName
视图时,属性full
和mother
(father
自己)也会被序列化,但只能使用Persons
视图(所以它不会归咎于祖父母。)
JSON序列化必须“自然”,即在Javascript中有意义的东西。这意味着我想要正确的整数,布尔值和空值,我不想要额外的对象包装器或试图捕获整个XML Infoset的东西。
对于XML,必须配置序列化以使用空元素来序列化空值,而不是XML Schema的simple
属性。
此外,必须使用嵌套元素序列化数组,以便可以区分空数组和给定视图中不存在的属性:
未定义的xsi:nil="true"
属性(视图中不存在):
friends
空数组,人没有朋友:
<person>
</person>
反序列化XML和JSON并将数据合并到现有实体
现在这是困难的部分。接下来的两个是相连的:
部分对象的反序列化必须是可能的(类似于视图,但不存在预先定义的属性)。
合并到现有属性中,而不是创建新属性。
这有点难以解释。大多数库反序列化为Java对象,但在那时,未定义属性和null / empty属性(如Javascript / JSON中存在,如上所述的XML,PHP,......)之间的区别将丢失。
获得此XML时:
<person>
<friends></friends>
</person>
并传递<person>
<lastName>Bon Jovi</lastName>
<friends></friends>
</person>
对象,库应该:
Person
例如,它不应触及实体person.setLastName("Bon Jovi");
person.setFriends(new ArrayList());
和/或清除它firstName
。
当然,对于列表,这应该更复杂。我希望配置一个id属性,通过它可以决定是更新嵌套实体还是创建一个新实体。
这些更新/补丁是图书馆不得仅返回DTO的原因:因为那时father
可能意味着“未设置”或“什么也不做”。
嗯,就是这样。我一直在说“必须”很多,我现在意识到:)图书馆不需要实际提供,但必须有一种方式以干净的方式添加功能(=不会以重写一切的方式更容易)。
答案 0 :(得分:1)
我不知道现有的库可以满足您的所有需求,但是,假设您需要实现某些功能:
基于bean属性编写XML或JSON非常简单:
阅读:一种方法可能是使用现有的库(用于JSON或XML)来创建对象,然后处理合并对象之间的属性。 XMLDecoder类可以读取bean XML(假设您使用XMLEncoder创建它)。这种方法的棘手部分是知道何时将值“设置”为null而不是在XML中设置。这种方法还有额外的开销,即创建一堆新对象。
否则,阅读JSON或XML有点棘手,但不是太糟糕
答案 1 :(得分:1)
对于它的价值,Jackson具有开箱即用的部分更新:
ObjectMapper mapper = new ObjectMapper();
Bean existing = ...;
mapper.updatingReader(existing).readValue(jsonSource);
它还可以转换兼容类型(类似于序列化为JSON,读回不同类型)。
对于XML部分,您可以使用JAXB,但据我所知它只能完成绑定。