2013-06-04 83 views
3

我在使用GSON序列化和反序列化我的對象結構時遇到了問題。爲了描述這個問題,我將不得不描述我的類結構:使用GSON將複雜對象(de)序列化爲JSON

我有一個java抽象類,讓我們將其命名爲「A」。還有類「BA」,「CA」,「DA」也是抽象的,它們擴展了類「A」。它們中的每一個都有自己的構造函數,其中沒有非構造函數。最後有幾個(許多!)類擴展「BC」或「CA」或「DA」。這些「底部」類的實例保存在「ArrayList」列表中。

現在,我試圖「jsonize」該數組列表。爲了創建JSON字符串我用這個代碼:

Gson gs = new Gson(); 
Type listOfTestObject = new TypeToken<List<A>>(){}.getType(); 
String rez = gs.toJson(getListOfAs(), listOfTestObject); 

我試圖反序列化利用這一點,JSON(在其他類):

Type listOfTestObject = new TypeToken<ArrayList<A>>(){}.getType(); 
ArrayList<A> listOfAs = gs.fromJson(jsonREZString, listOfTestObject); 

但上面的代碼中拋出這個:

Unable to invoke no-args constructor for class packagename.A. Register an InstanceCreator with Gson for this type may fix this problem. 

現在,我已經在類「A」中創建了非參數構造函數,但沒有運氣。我已閱讀「InstanceCreator」,但看起來我必須爲每個擴展「A」的具體類創建一個「InstanceCreator」!對?我不能這樣做,因爲我有許多(許多!)類,通過「BA」,「CA」或「DA」擴展「A」。

你能幫我解決這個問題嗎,我錯過了什麼嗎?我怎樣才能簡單地反序列化(序列化看起來很好)這個複雜的結構,而不添加每個類型的自定義反序列化代碼?

回答

3

其實你可能在這裏有兩個不同的問題。

1)您有多態類型,因此您可能想將對象序列化爲它們的具體類型而不是A。 2)您想要反序列化爲不提供參數ctrs的具體類型。

Gson不支持1 & 2,有一個擴展名爲1,但我從來沒有使用它。

也許Genson解決您的問題,它同時支持1 & 2.

Genson genson = new Genson.Builder() 
          // enables polymorphic types support 
          .setWithClassMetadata(true) 
          // enables no arg support 
          .setWithDebugInfoPropertyNameResolver(true) 
          .create(); 

// will look like: [{"@class": "com.xxx.SomeConcreteClass", ...}, {"@class": "com.XXX.OtherClass"}] 
String json = genson.serialize(getListOfAs()); 
List<A> listOfA = genson.deserialize(json, new GenericType<List<A>>() {}); 

你不需要序列化過程中指定的類型,如果你想,只有父域出現在輸出時除外。例如:genson.serialize(getListOfAs(),GenericType>(){})只會序列化來自A的屬性,您還可以通過在構建器上設置setUseRuntimeTypeForSerialization(true)來強制genson始終使用運行時類型。

此外,如果您不希望在json表示中泄漏impl細節,則可以爲您的類型定義別名(builder.addAlias(「someAlias」,SomeClass.class)),它們將用於代替完整包+ classname。

相關問題