2009-04-08 75 views
3

我正在開發一個RESTful Web服務。部分bean序列化和反序列化+合併

我有一堆實體類(主要是JPA實體,但也包括其他豆)。

有對象映射,序列化,綁定和什麼樣的庫在那裏的gazillions。我在找一個,這將使我:

  • 序列化實體XML和JSON

    ,串行化必須支持使用干將,不僅對象字段。

    它必須支持意見。通過意見我的意思是一種方法來指定實體的屬性的子集,這是要序列化。有關示例,請參閱Yahoo!中的Retrieving Partial Resources。社交平臺API。我也不希望它無限期地遞歸:

    視圖應該定義a)要在實體中公開的屬性和b)它們中的每一個(如果它們本身是實體)的視圖。

    例如,實體Person可能具有視圖fullsimple。當請求Personsimple視圖時,只有屬性idfirstNamelastName會被序列化。當請求full視圖時,屬性motherfather(它們自己也是Persons)也將被序列化,但僅與simple視圖(因此它不會遞歸給祖父母)。

    JSON序列化必須是「自然」,即什麼會在Javascript中有意義。這意味着我想要適當的整數,布爾值和空值,我不想額外的對象包裝或嘗試捕獲整個XML Infoset。

    對於XML,它必須能夠配置序列化使用空元素用於序列化空值,而不是XML Schema的xsi:nil="true"屬性。

    • 未定義friends屬性(不存在於視圖):

      此外,數組必須使用嵌套元素,因此這是可能的空數組和性能,這是不存在於給定的視圖之間進行區分被序列:

      <person> 
      </person> 
      
    • 空數組,人有沒有朋友:

      <person> 
          <friends></friends> 
      </person> 
      
  • 反序列化XML和JSON和數據合併到現有實體

    現在,這是困難的部分。接下來的兩個連接:

    反序列化部分對象必須是可能的(類似於視圖,但哪些屬性存在未預先定義)。

    合併到現有屬性中,而不是創建新屬性。

    這是一個有點棘手的解釋。大多數庫反序列化爲Java對象,但是當時,未定義的屬性和空/空屬性(因爲它存在於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可能意味着「未設置」或「什麼都不做」。

好吧,就是這樣。我一直在說「必須」,現在我意識到了:)圖書館實際上並不需要提供這些功能,但必須有一種方法來以乾淨的方式添加功能(不是以一種可以重寫所有內容的方式更輕鬆)。

回答

1

我不知道你所需要的一切現有庫的,但是,假設你將需要實現的東西:

  • 編寫XML或JSON基於bean的屬性是非常簡單的:

    • 看看使用Apache Commons BeanUtils能夠獲取所有屬性值(http://commons.apache.org/beanutils/)。特別是PropertyUtils類。
    • 使用BeanUtils遞歸地走你的整個對象圖 - 小心循環 - 你需要一個Set或一些東西來跟蹤你已經看到的東西
    • XML:看看XMLEncoder - 它的工作原理使用JavaBean屬性創建XML
  • 對於閱讀:一種方法可能是使用現有的庫(用於JSON或XML)創建對象,然後處理合並對象之間的屬性。 XMLDecoder類可以讀取bean XML(假設您使用XMLEncoder創建它)。這種方法最棘手的部分是知道一個值何時被設置爲null,而不是在XML中設置。這種方法在創建一堆新對象時也有額外的開銷。

  • 否則,閱讀JSON或XML有點麻煩,但不是太糟糕

    • 我假設你已經有了索引對象的一些手段,你要合併到(如地圖某種)
    • 我假設您已經有一些方法可以知道哪個屬性是唯一標識對象的關鍵字(我假設姓氏只是爲了獲得重點,因爲它會造成錯誤的關鍵)
    • XML:爲此使用類型,我建議爲xml使用SAX閱讀器 - 您需要一個堆棧來跟蹤要添加數據的對象 至。 SAX閱讀器告訴你看到了哪些標籤,然後給出這些標籤的值。你也可以在這裏使用XML拉,這往往是更快一點
    • JSON:看看一些開源的JSON庫,並做一些調整。 JSON解析起來很簡單,而且這些工具往往很小,所以這不應該是一個大問題。或者,您可以編寫ANTLR(或其他生成器)解析器來閱讀JSON並按照您的喜好使用它。
1

對於什麼是值得的,Jackson有部分更新外的開箱:

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

,它也可以轉換成兼容的類型(類似序列化到JSON,回讀到不同的類型)。

對於XML部分,您可以使用JAXB,儘管它只能完成綁定,據我所知。