2011-06-19 59 views
3

我在使用GSon進行json反序列化時遇到了一些困難,我希望有人能幫助我。使用Gson反序列化泛型集合

我想反序列化下面的JSON片段:

{ 
    "fieldA": "valueA", 
    "myCollection": { 
     "AnotherClass": [ 
      { 
       "objectAfieldA": "valueB", 
       "objectAfieldB": "valueC" 
      }, 
      { 
       "objectAfieldA": "valueD", 
       "objectAfieldB": "valueE" 
      } 
     ] 
    } 
} 

相應的整體水平具有以下字段:

... 
String fieldA; 
List<AnotherClass> = new ArrayList<AnotherClass>(); 
.... 

現在,我的問題是,當我反序列化,使用fromJson(jsonSample, resultContainer.class),而不List<T>元素,一切都很好,但是當我包含包含的列表時,我得到了一個NullPointerException。我讀過有關如何處理泛型類型的集合和使用TypeToken,但是當我的收藏是另一個階級的一部分,我不能應用這些知識...

我真的希望得到任何幫助解決這個問題。

+0

如果你的工作把你的代碼示例,那麼它將無法正常編譯列表字段沒有名字。如果這不是問題,請查看[http://stackoverflow.com/questions/5554217/google-gson-deserialize-listclass-object-generic-type](http://stackoverflow.com/questions/5554217/google-gson-deserialize-listclass-object-generic-type),和[http://stackoverflow.com/questions/2496494/library-to-encode-decode-from-json-to-java-util-圖](http://stackoverflow.com/questions/2496494/library-to-encode-decode-from-json-to-java-util-map)。 – oberger

+0

你是對的,我錯過了一個名字領域。問題在隨後的答案中得到解決。 –

回答

1

反序列化時,如果要反序列化的最外層結構是泛型集合,則只需要使用TypeToken。原始問題中的例子不是這種情況。因此,使用TypeToken是不必要的。

問題似乎是JSON結構與試圖綁定的Java結構不匹配。

的JSON結構定義

an object with two elements 
    element 1 is a string named "fieldA", 
    element 2 is an object named "myCollection", which has one element 
     the one element is an array named "AnotherClass", composed of objects with two elements 
      element 1 is a string named "objectAfieldA", 
      element 2 is a string named "objectAfieldB" 

所以,定義Java數據結構來匹配,和反序列化將工作很乾脆,沒有任何必要的加工定做。如果沒有提供這種匹配的Java結構,則自定義的反序列化是必要的。

這是一個使用原始問題的名稱和類型的工作示例。

import java.io.FileReader; 

import com.google.gson.Gson; 

public class Foo 
{ 
    public static void main(String[] args) throws Exception 
    { 
    Gson gson = new Gson(); 
    resultContainer result = gson.fromJson(new FileReader("input.json"), resultContainer.class); 
    System.out.println(gson.toJson(result)); 
    } 
} 

class resultContainer 
{ 
    String fieldA; 
    MyCollectionContainer myCollection; 
} 

class MyCollectionContainer 
{ 
    SomeOtherClass[] AnotherClass; 
} 

class SomeOtherClass 
{ 
    String objectAfieldA; 
    String objectAfieldB; 
} 
+0

很好的答案,現貨!我調整了我的Java結構,我很高興。 Thanx,布魯斯。 –

+0

現在又出現了另一個問題......我使用的服務有時只會在'AnotherClass'元素中攜帶一個項目,在這種情況下,它不會被編碼爲json數組(完美地轉換爲SomeOtherClass []),而只是一個簡單的SomeOtherClass鍵入 - 留下數組括號。這打破了我的反序列化。如果我手動添加括號,它會再次解析。這是JSON標準,你們有解決方法嗎? –

+0

你所描述的是一個經常發生的問題。也許有些人認爲,如果他們生成的JSON是有效的,那就足夠好了,即使它的結構不一致。不幸的是,Gson還沒有一個簡單的配置來處理這個經常發生的問題。自定義的反序列化處理是必要的。我在http://stackoverflow.com/questions/6223023上發佈了這樣一個例子來回答這個問題。 –

4

爲deserealizing無名JSON陣列的解決方案很簡單:

List<resultContainer> lres = gson.fromJson(new FileReader("input.json"), new TypeToken<List<resultContainer>>(){}.getType());