2011-06-20 107 views
0

我現在有存儲一類就是實施Serializable,但因爲是從WSDL產生一定SOAP-系列化和 Web服務的輸入的Java對象。手動XML序列化的Java對象

標準Java序列化實際上會引發異常。我無法控制課程,創建課程的人不願意手動標記Serializable,因爲代理是從WSDL自動生成的(wsdl2java?他們沒有告訴我......)。

所以我需要通過不可能循環遍歷每個字段來將該對象轉換爲其他東西。

.class文件顯示XML序列化屬性,所以我想它們肯定是XML序列化的。

如何執行Java對象的手動XML序列化?我可以在C#中完成,但不能在Java中完成。

謝謝

+0

爲什麼要序列化此對象?要進行WS調用還是有其他原因?在第一種情況下,您不需要手動序列化,否則使用一些序列化庫,如XStream。 – mrembisz

+0

我需要存儲對象供以後使用;) –

+0

更大的問題是,即使所有需要的是臨時存儲在HttpSession中的對象,如果它不實現可序列化,許多Web容器將立即炸燬。 – mezmo

回答

1

你可以做

private byte[] encode(YourObject obj) 
    { 
     byte[] bytes = null; 
     try 
     { 
      YourObject vsNew = new YourObject(obj) 
      ByteArrayOutputStream baos = new ByteArrayOutputStream(); 
       GZIPOutputStream out = new GZIPOutputStream(baos); 
       XMLEncoder encoder = new XMLEncoder(out); 
       encoder.writeObject(vsNew); 
       encoder.close(); 
       bytes = baos.toByteArray(); 
     } 
     catch (Exception e) 
     { 
      _log.error("Exception caught while encoding/zipping ", e); 
     } 
     return bytes; 
    } 


    /* 
    * Decode the report definition blob back to the 
    * ScheduledReport object. 
    */ 
    private YourObject decode(byte[] bytes) 
    { 
     ByteArrayInputStream bais = new ByteArrayInputStream(bytes); 
     YourObject vSNew = null; 
     try 
     { 
      GZIPInputStream in = new GZIPInputStream(bais); 
      XMLDecoder decoder = new XMLDecoder(in); 
      vSNew = (YourObject)decoder.readObject(); 
      decoder.close(); 
     } 
     catch (Exception e) 
     { 
      _log.error("IOException caught while decoding/unzipping ", e); 
     } 
     return vSNew ; 
    } 
+1

在反序列化過程中BigDecimal字段可能丟失*是否可​​能?其他字段已正確序列化! –

+1

找到原因:http://www.nesterovsky-bros.com/weblog/2011/06/16/XMLSerializationOfNumbersInJava.aspx –

0

如果你的對象遵循Java豆類規範,你不在乎他們究竟是如何表示爲XML,XMLEncoder從Java標準API可以做這項工作。

如果您的對象不是「純」的JavaBean,或者您需要更多的控制生成的XML,XStream是一種流行的XML序列化庫。

1

如果您願意(或其他人願意)使用JAXB批註對類進行註釋,那麼JAXB將成爲序列化和從XML反序列化的直接選擇。如果這已經完成(您的問題表明XML序列化屬性在類文件中可用),那麼您需要使用JAXBContext和相關API類(Marshaller和Unmarshaller)來編組和解組對象。

如果你付出了所有的努力,你可以考慮Castor。我應該警告你,如果你沒有映射,那麼你可能不會對輸出滿意。但是,如果您可以將依賴項導入到您的項目*中,這是序列化爲XML的最快捷方式。

我還會提供JiBXXMLBeansXStream的強制性鏈接。它們都可以執行到XML的編組和解組。其中一些不需要像Castor那樣的映射。

*在過去嘗試編寫XML序列化程序時,我建議不要編寫自己的代碼來嘗試執行Castor或類似的編組/解組程序所做的工作。在沒有映射文件的情況下,它涉及大量的反射。

1

這是一種做事方式,另一種方式是......控制java客戶端的人更合理一點。假設JAX-WS用於創建通過wsimport的工具,他們可以指定一個簡單的小綁定文件的客戶端,在-b選項中,看起來像這樣規定的:
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema
                              xmlns:jaxb="http://java.sun.com/xml/ns/jaxb"
                              xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc"
                              elementFormDefault="qualified" attributeFormDefault="unqualified"
                          jaxb:extensionBindingPrefixes="xjc" jaxb:version="2.1">
              <xs:annotation>
    <xs:appinfo>
    <jaxb:globalBindings>
    <xjc:serializable />
        </jaxb:globalBindings>
    </xs:appinfo>
  </xs:annotation>
</xs:schema>

它會自動地把 「序列化」 在所有生成的類。我也通過jaxws-maven-plugin在Maven中工作。我相信其他客戶端生成器也有類似的選項。

HTH

+0

不幸的是,這是不可能的。但提到「合理性」的榮譽。我不知道他們使用什麼工具,他們甚至可以使用自定義工具,因此也無法手動實現Serializable。 –

+0

您是否有權訪問WSDL?這可能是時候禮貌地創建自己的客戶,如果有任何問題被問到,微笑和回覆,「它已被照顧。」 ;) – mezmo

+0

這並不容易。我不允許修改WSDL(儘管我可以非傳統地閱讀它),完全停止:)。儘管如此,後端人員仍然使用他們自己的工具 –