Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/xml/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 部分bean序列化和反序列化+;合并_Java_Xml_Json_Serialization - Fatal编程技术网

Java 部分bean序列化和反序列化+;合并

Java 部分bean序列化和反序列化+;合并,java,xml,json,serialization,Java,Xml,Json,Serialization,我正在开发一个RESTful web服务 我有一堆实体类(主要是JPA实体,但也有其他bean) 有无数的对象映射、序列化、绑定等等库。我正在寻找一个能让我: 将实体序列化为XML和JSON 序列化必须支持使用getter,而不仅仅是对象字段 它必须支持视图。我所说的视图是指指定要序列化的实体属性子集的方法。例如,请参见雅虎!社交平台API。我也不希望它无限期地反复出现: 视图应该定义a)要在实体中公开的属性,b)每个属性的视图(如果它们本身是实体) 例如,实体Person可能具有视图full

我正在开发一个RESTful web服务

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

有无数的对象映射、序列化、绑定等等库。我正在寻找一个能让我:

  • 将实体序列化为XML和JSON

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

    它必须支持视图。我所说的视图是指指定要序列化的实体属性子集的方法。例如,请参见雅虎!社交平台API。我也不希望它无限期地反复出现:

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

    例如,实体
    Person
    可能具有视图
    full
    simple
    。当请求
    人员的
    简单视图时,只有属性
    id
    firstName
    lastName
    会被序列化。当请求
    完整视图时,属性
    母亲
    父亲
    (即
    本身)也将被序列化,但仅使用
    简单视图(这样它就不会递归到祖父母)

    JSON序列化必须是“自然的”,即在Javascript中有意义的内容。这意味着我需要正确的整数、布尔值和空值,我不需要额外的对象包装器或试图捕获整个XML信息集的东西

    对于XML,必须能够将序列化配置为使用空元素序列化空值,而不是XML模式的
    xsi:nil=“true”
    属性

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

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

      例如,它不应该触碰实体
      firstName
      和/或清除它是
      父对象

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

      这些更新/补丁是库不能只返回DTO的原因:因为在那个时候,
      null
      可能意味着“未设置”或“什么都不做”


    好了,就这样。我已经说了很多“必须”,现在我意识到:)库实际上不需要提供这些功能,但必须有一种方法以干净的方式添加功能(=不是以一种可以使重写更容易的方式)。

    我不知道现有的库可以做你需要的一切,但是,假设您需要实现一些东西:

    • 基于bean属性编写XML或JSON非常简单:

      • 看看如何使用ApacheCommonsBeanutils来获取所有属性值()。特别是PropertyUtils类
      • 递归地使用BeanUtils遍历整个对象图-注意循环-您需要一个集合或旁边的东西来跟踪您已经看到的内容
      • XML:看看XMLEncoder——它使用JavaBean属性来创建XML
    • 阅读:一种方法可能是使用现有的libs(用于JSON或XML)创建对象,然后处理对象之间的属性合并。XMLDecoder类可以读取bean XML(假设您使用XMLEncoder创建它)。这种方法最棘手的部分是知道什么时候值被“设置”为null,而不是在XML中被设置。这种方法还需要额外的开销来创建一组新对象

    • 否则,读取JSON或XML会有点麻烦,但也不是太糟糕

      • 我假设您已经有了一些方法来索引要合并到的对象(比如某种类型的地图)
      • 我假设您已经有了一些方法来知道哪个属性是唯一标识对象的键(我假设姓氏只是为了说明问题,因为它会生成一个坏键)
      • XML:对于这种类型的使用,我建议为XML使用SAX读取器——您需要一个堆栈来跟踪要向其中添加数据的对象。SAX阅读器告诉您看到了哪些标记,然后给出这些标记的值。您也可以在这里使用XML拉,这往往会更快一些
      • JSON:看看一些开源JSON库并做一些调整。JSON解析起来非常简单,而且这些工具往往非常小,所以这应该不是什么大问题。或者,您可以编写一个ANTLR(或其他生成器)解析器来读取JSON,并根据需要使用它
    对于它的价值,有部分现成的更新:

    ObjectMapper mapper = new ObjectMapper();
    Bean existing = ...;
    mapper.updatingReader(existing).readValue(jsonSource);
    
    它还可以转换兼容的类型(类似于序列化为JSON,读回不同的类型)

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

    <person>
        <friends></friends>
    </person>
    
    <person>
        <lastName>Bon Jovi</lastName>
        <friends></friends>
    </person>
    
    person.setLastName("Bon Jovi");
    person.setFriends(new ArrayList());
    
    ObjectMapper mapper = new ObjectMapper();
    Bean existing = ...;
    mapper.updatingReader(existing).readValue(jsonSource);