2014-02-23 32 views
1

我想將一些JSON轉換爲android中的java對象,但它似乎不工作。Android中的Java對象的JSON不與GSON一起工作

Gson gson = new Gson(); 
Person person = gson.fromJson(s, Person.class); 
Toast toast = Toast.makeText(getApplicationContext(), "Welcome back " + person.getDisplayName(), duration); 
toast.show(); 

哪裏Person.class是

com.google.api.services.plus.model.Person 

我收到的類型轉換錯誤,如:

wrong object type: Ljava/lang/Double; Ljava/lang/Integer; 
java.lang.IllegalArgumentException: invalid value for field 

但我想重新使用API​​庫這個模型對象,所以是無論如何要解決這個問題?

編輯:

爲了證明在一個更簡單的形式這個問題,請參考本示例。

com.google.api.services.plus.model.Person; 

Gson g = new Gson(); 

    Person p1 = new Person(); 
    p1.setDisplayName("Test"); 
    p1.setCircledByCount(10); 

    String json = g.toJson(p1); 
    Person fromJson = g.fromJson(json, Person.class); 
    System.out.println(fromJson.getDisplayName()); 

引發相同的異常。

Exception in thread "main" java.lang.IllegalArgumentException: Can not set java.lang.Integer field com.google.api.services.plus.model.Person.circledByCount to java.lang.Double 
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(Unknown Source) 
at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(Unknown Source) 

我做錯了什麼? 感謝

+1

發佈你的模型類和json – user2450263

+1

坦率地說,你不應該使用該類的GSON。它不適用於GSON。它有自己的內置邏輯,用於將自身序列化爲JSON,並且它是處理反序列化的一部分的庫。 –

回答

6

問題是你使用的類不是用於/設計用於Gson。

的核心問題是,Person延伸GenericJson延伸GenericData延伸AbstractMap<String, Object> ......和的問題。

當Gson嘗試反序列化JSON時,它使用其MapTypeAdapterFactory,這不幸地導致在Java中將"circledByCount"的JSON數字類型讀爲Double

然後在此Person類踢的複雜性。如果你去看看源代碼,它實際上使用的註釋和覆蓋put方法來填充在Person領域。如果你看一下堆棧跟蹤你可以看到發生了什麼:

Exception in thread "main" java.lang.IllegalArgumentException: Can not set java.lang.Integer field com.google.api.services.plus.model.Person.circledByCount to java.lang.Double 
    at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:164) 
    at sun.reflect.UnsafeFieldAccessorImpl.throwSetIllegalArgumentException(UnsafeFieldAccessorImpl.java:168) 
    at sun.reflect.UnsafeObjectFieldAccessorImpl.set(UnsafeObjectFieldAccessorImpl.java:81) 
    at java.lang.reflect.Field.set(Field.java:680) 
    at com.google.api.client.util.FieldInfo.setFieldValue(FieldInfo.java:245) 
    at com.google.api.client.util.FieldInfo.setValue(FieldInfo.java:206) 
    at com.google.api.client.util.GenericData.put(GenericData.java:103) 
    at com.google.api.client.util.GenericData.put(GenericData.java:47) 
    at com.google.gson.internal.bind.MapTypeAdapterFactory$Adapter.read(MapTypeAdapterFactory.java:188) 
    at com.google.gson.internal.bind.MapTypeAdapterFactory$Adapter.read(MapTypeAdapterFactory.java:145) 
    at com.google.gson.Gson.fromJson(Gson.java:803) 
    at com.google.gson.Gson.fromJson(Gson.java:768) 
    at com.google.gson.Gson.fromJson(Gson.java:717) 
    at com.google.gson.Gson.fromJson(Gson.java:689) 

GSON呼籲GenericDataput()方法(因爲,它知道這是一個Map)。該方法實際上通過反射填充註釋的circledByCount字段。而...這是錯誤的類型。

因此,基本上...這不會與Gson合作。至少不是沒有寫一個自定義的JsonDeserializer,但看着課堂,這將是相當複雜的。

+0

感謝您的詳細解釋。當在客戶端庫中的許多其他位置使用模型類並使用與GSON不同的json序列化器時,似乎很奇怪。然而,我確信這有一個合理的原因! – user1089599

0

你的JSON StringDouble價值和Person對象,你關心鑄有Integer值。

請檢查雙方的對象Person。如果您在Android應用程序端複製並粘貼相同的Person對象,則更好。

+0

它們與帖子中列出的Google API相同。 json由一個彈簧mvc控制器返回一個person對象生成。服務器端Jackson序列化程序可能導致此問題? – user1089599

+0

如果從服務器返回的JSON字符串是oky,它不能成爲Jackson序列化程序的問題。請仔細檢查您的人員類別..如果您可以在服務器和客戶端雙方提供JSON字符串和Person類別.. – Charitha

0

您的人員類必須具有與您解析的JSON完全相同的文件和名稱。