部分bean序列化和反序列化+合并 [英] Partial bean serialization and deserialization+merging

查看:96
本文介绍了部分bean序列化和反序列化+合并的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发RESTful Web服务.

我有一堆实体类(主要是JPA实体,还有其他bean).

那里有无数的对象映射,序列化,绑定和其他库.我正在寻找一种能让我:

  • 将实体序列化为XML和JSON

    序列化必须支持使用 getters ,而不仅仅是对象字段.

    它必须支持视图.通过视图,我指的是一种指定要序列化的实体属性子集的方法.有关示例,请参见Yahoo!中的获取部分资源.社交平台API.我也不希望它无限递归:

    该视图应定义a)要在实体中公开的属性,以及b)每个属性(如果它们是实体本身)的视图.

    例如,实体Person可能具有视图fullsimple.当请求Personsimple视图时,仅属性idfirstNamelastName会被序列化.当请求full视图时,属性motherfather(本身是Persons)也将被序列化,但只能使用simple视图进行序列化(因此不会递归给祖父母). /p>

    JSON序列化必须为自然" ,即在Javascript中有意义的内容.这意味着我想要适当的整数,布尔值和null,并且我不需要多余的对象包装器或试图捕获整个XML Infoset的东西.

    对于XML,必须可以将序列化配置为使用空元素来对空值(而不是XML Schema的xsi:nil="true"属性)进行序列化.

    此外,必须使用嵌套元素对数组进行序列化,以便可以区分空数组和给定视图中不存在的属性:

    • 未定义的friends属性(视图中不存在):

      <person>
      </person>
      

    • 空数组,人没有朋友:

      <person>
          <friends></friends>
      </person>
      

  • 反序列化XML和JSON并将数据合并到现有实体中

    现在这是困难的部分.接下来的两个连接:

    必须对部分对象进行反序列化(类似于视图,但是没有预先定义存在的属性).

    合并到现有属性中,而不创建新属性.

    这有点棘手.大多数库反序列化为Java对象,但是那时,未定义属性和null/empty属性(因为它存在于Javascript/JSON,如上所述的XML,PHP,...)之间的区别就消失了.

    获得此XML时:

    <person>
        <lastName>Bon Jovi</lastName>
        <friends></friends>
    </person>
    

    并通过一个Person对象,该库应:

    person.setLastName("Bon Jovi");
    person.setFriends(new ArrayList());
    

    例如,它不应触摸实体firstName和/或将其清除为father.

    当然,对于列表,这应该更复杂.我希望配置一个id属性,该属性将决定是更新嵌套实体还是创建一个新实体.

    这些更新/补丁是库不得仅返回DTO的原因:因为那时null可能意味着未设置"或什么都不做".

是的,就是这样.我一直在说很多必须",我现在意识到:)该库实际上不需要提供它,但是必须有一种以简洁的方式添加功能的方法(=不能以重写所有内容的方式)更容易).

解决方案

对于它的价值,杰克逊具有开箱即用的部分更新:

ObjectMapper mapper = new ObjectMapper();
Bean existing = ...;
mapper.updatingReader(existing).readValue(jsonSource);

,它还可以转换兼容的类型(类似于序列化为JSON,读回不同的类型).

对于XML部分,您可以使用JAXB,尽管据我所知它只能完成绑定.

I am developing a RESTful web service.

I have a bunch of entity classes (mostly JPA entities, but also other beans).

There are gazillions of object mapping, serialization, binding and whatnot libraries out there. I'm looking for a one that will enable me to:

  • Serialize the entities to XML and JSON

    Serialization MUST support using getters, not only object fields.

    It MUST support views. By views I mean a way to specify a subset of the properties of the entity, which are to be serialized. For an example, see Retrieving Partial Resources in the Yahoo! Social Platform API. I also don't want it to recurse indefinitely deep:

    The view should define a) properties to be exposed in the entity and b) a view for each of them (if they're entities themselves).

    For example, the entity Person might have views full and simple. When requesting a simple view of a Person, only properties id, firstName and lastName would be serialized. When requesting a full view, the properties mother and father (which are Persons themselves) would also be serialized, but only with the simple view (so it wouldn't recurse to grandparents).

    The JSON serialization MUST be "natural", i.e. what would make sense in Javascript. That means I want proper integers, booleans and nulls and I don't want extra object wrappers or something that tries to capture the entire XML Infoset.

    For XML, it MUST be possible to configure the serialization to use empty elements for serializing nulls, not XML Schema's xsi:nil="true" attributes.

    Additionally, arrays must be serialized using nested elements so it's possible to differentiate between empty arrays and properties which aren't present in a given view:

    • Undefined friends property (not present in view):

      <person>
      </person>
      

    • Empty array, person has no friends:

      <person>
          <friends></friends>
      </person>
      

  • Deserialize XML and JSON and merge the data into existing entities

    Now this is the difficult part. The next two are connected:

    Deserialization of partial objects MUST be possible (analogous to views, but which properties are present is not defined in advance).

    Merging into existing properties, not creating new ones.

    This is a bit tricky to explain. Most libraries deserialize into Java objects, but at that time, the distinction between an undefined property and a null/empty property (as it exists in Javascript/JSON, XML as described above, PHP, ...) is lost.

    When being given this XML:

    <person>
        <lastName>Bon Jovi</lastName>
        <friends></friends>
    </person>
    

    and being passed a Person object, the library should:

    person.setLastName("Bon Jovi");
    person.setFriends(new ArrayList());
    

    It shouldn't touch the entities firstName and/or clear it's father, for example.

    Of course with lists this should be more complex. I would expect to configure an id property, by which it would decide whether to update the nested entity or create a new one.

    These updates/patches are a reason why the library MUST NOT just return a DTO: because at that time a null might either mean "unset" or "do nothing".

Well, that's it. I've been saying "MUST" a lot, I realize now :) The library needn't actually provide that, but there must be a way to add the functionality in a clean fashion (= not in a way that would make rewriting everything easier).

解决方案

For what it is worth, Jackson has partial update out-of-the-box:

ObjectMapper mapper = new ObjectMapper();
Bean existing = ...;
mapper.updatingReader(existing).readValue(jsonSource);

and it can also convert compatible types (similar to serializing to JSON, reading back to different type).

For XML part you can use JAXB, although it can only complete binding as far as I know.

这篇关于部分bean序列化和反序列化+合并的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆