2011-04-18 134 views
1

我正在寫一個Java程序,它通過調用某些方法向外部API發出請求。這些方法中的每一個都會返回不同的JSON結構,並且還取決於傳遞的參數。我的問題是,如果有一些方法可以使用Gson反序列化響應字符串,而不必爲每種方法編寫不同的類。將JSON反序列化爲未知類型集合

如果不是Gson,我可以使用哪個其他庫?

謝謝。

回答

4

我的問題是如果有一些方法來反序列化使用Gson的響應字符串,而無需爲每種方法編寫不同的類。

是的,有。如果您不關心反序列化爲特定Java類型的JSON結構只是一個包含鍵值對的對象,其中所有值都是JSON基元,那麼該結構可以簡單地反序列化爲Map<String, String>

請注意,Map<String, Object>將無法​​正常工作,因爲它不會爲Gson反序列化提供足夠的類型信息。 Gson只會爲每個值創建普通的Object實例 - 而不是StringInteger實例,但只是簡單的Object實例。 JSON中的實際值不會被反序列化。從表面上看,可以增強Gson爲JsonPrimitive值創建更多類型特定的實例。例如,由於可以確定JsonPrimitive是否爲Boolean,並調用isBoolean(),那麼人們可能會希望Gson構建一個Boolean,但它不會--Gson只是創建一個空的,可能沒用的Object

下面是一個演示這一點的例子。

input.json內容:

{ 
    "one":"won", 
    "too":22, 
    "3":false 
} 

Foo.java:

import java.io.FileReader; 
import java.lang.reflect.Type; 
import java.util.Map; 

import com.google.gson.Gson; 
import com.google.gson.reflect.TypeToken; 

public class Foo 
{ 
    public static void main(String[] args) throws Exception 
    { 
    Gson gson = new Gson(); 
    Type mapOfStringObjectType = new TypeToken<Map<String, String>>() {}.getType(); 
    Map<String, String> map = gson.fromJson(new FileReader("input.json"), mapOfStringObjectType); 
    System.out.println(map); 
    } 
} 

本實施例的輸出是{3=false, one=won, too=22}

如果示例中的Map類型更改爲HashMap<String, Object>,如其他答案中的建議,則輸出將變爲{[email protected], [email protected], [email protected]},這當然可能是無用的。

如果由於某種原因某種類型的HashMap<String, Object>必須將反序列化爲,則自定義的反序列化處理將是必要的。

如果JSON結構不是一組簡單的鍵值對,其中的值都是JSON基元,但包含類似JSON對象的複雜類型的值,即使將所有值轉換爲Strings ,那麼也需要實現自定義的反序列化處理。

不要猶豫去the Gson Issues List並提交一個改進JSON原語反序列化的改進請求,以適應特定的Java Object類型,或者有一個簡單的機制來轉換任何值 - 包括複雜的JSON類型,如對象和數組 - 在Map中映射到String,這樣上面描述的自定義的反序列化處理將不是必需的。

+0

Gson問題325解決了簡單的反序列化爲Map 。請不要猶豫,通過http://code.google.com/p/google-gson/issues/detail?id=325 – 2011-06-13 06:27:54

+0

投票支持其實施。請注意,傑克遜(http://jackson.codehaus.org)可以將上面的示例JSON反序列化爲沒有自定義處理的Map ,並且JSON-lib(http://json-lib.sourceforge.net)可以類似地反序列化爲Map(Map map = JSONObject.fromObject(json) )。 – 2011-06-13 06:32:12

+0

請注意,我之前對此主題的評論是針對Gson的以前版本的。隨着Gson問題325的實現,它現在可能只是反序列化爲Map 。我不確定,因爲我還沒有嘗試這樣做。 – 2013-01-10 19:53:51

1

如果你想使用gson,你必須編寫不同的類來表示不同方法的響應。如果響應是簡單的鍵值,那麼您可以將響應轉換爲HashMap<String,Object>,它將充當'通用'類來滿足您的用例中的所有類型的響應。

+0

請注意,HashMap 不包含Gson反序列化到的足夠的類型信息。 Gson只會爲Map值創建普通的舊Object對象 - 而不是像String或Integer這樣的Object的子類,而只是Object。我會在回答這個問題時發佈更多細節。 – 2011-06-10 09:05:46

+1

請注意,我之前對此主題的評論是針對Gson的以前版本的。隨着Gson問題325的實現,它現在可能只是反序列化爲Map 。我不確定,因爲我還沒有嘗試這樣做。 – 2013-01-10 19:53:32