2016-09-14 65 views
0

就像標題所說的,我試圖解析一個對象,該對象的關鍵是一個動態的String。我看了很長一段時間了一些答案,發現1 this,2 this和3 this通過gson解析具有動態密鑰的對象

爲了您的信息,我還挺新到Java,這是我第一次用JSON數據工作,並解析

JSON響應看起來像這樣:

{"Narcos": {"episodes": [{"season": 2, "name": "Episode #2.1", "number": 1}, {"season": 2, "name": "Episode #2.10", "number": 10}, {"season": 2, "name": "Episode #2.2", "number": 2}, {"season": 2, "name": "Episode #2.3", "number": 3}, {"season": 2, "name": "Episode #2.4", "number": 4}, {"season": 2, "name": "Episode #2.5", "number": 5}, {"season": 2, "name": "Episode #2.6", "number": 6}, {"season": 2, "name": "Episode #2.7", "number": 7}, {"season": 2, "name": "Episode #2.8", "number": 8}, {"season": 2, "name": "Episode #2.9", "number": 9}, {"season": 1, "name": "Descenso", "number": 1}, {"season": 1, "name": "Despegue", "number": 10}, {"season": 1, "name": "Explosivos", "number": 6}, {"season": 1, "name": "La Catedral", "number": 9}, {"season": 1, "name": "La Gran Mentira", "number": 8}, {"season": 1, "name": "The Men of Always", "number": 3}, {"season": 1, "name": "The Palace in Flames", "number": 4}, {"season": 1, "name": "The Sword of Sim\u00f3n Bolivar", "number": 2}, {"season": 1, "name": "There Will Be a Future", "number": 5}, {"season": 1, "name": "You Will Cry Tears of Blood", "number": 7}], "year": 2015}} 

動態鍵,在該示例中 「Narcos」。它基本上是你想要的劇集名稱。

我嘗試了不同的方法。 對於第一個鏈接,用於解析的代碼如下所示:

ApiTest.class

Type mapType = new TypeToken<Map<String, Serie> >() {}.getType(); // define generic type 

    Map<String, Serie> serie = gson.fromJson(jsonString, mapType); 

Serie.class

public class Serie { 

    private Episodes episodes; 

Episodes.class

public class Episodes { 

    private Episode[] episode; 
    private int year; 

插曲。類

public class Episode { 

    private int season; 
    private String name; 
    private int number; 

當我用第一種方法去,我得到這個錯誤

Exception in thread "main" com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 1 column 41 path $..episodes 
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:224) 
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.read(ReflectiveTypeAdapterFactory.java:129) 
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:220) 
    at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.read(TypeAdapterRuntimeTypeWrapper.java:41) 
    at com.google.gson.internal.bind.MapTypeAdapterFactory$Adapter.read(MapTypeAdapterFactory.java:187) 
    at com.google.gson.internal.bind.MapTypeAdapterFactory$Adapter.read(MapTypeAdapterFactory.java:145) 
    at com.google.gson.Gson.fromJson(Gson.java:887) 
    at com.google.gson.Gson.fromJson(Gson.java:852) 
    at com.google.gson.Gson.fromJson(Gson.java:801) 
    at testing.ApiTest.main(ApiTest.java:114) 
Caused by: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 1 column 41 path $..episodes 
    at com.google.gson.stream.JsonReader.beginObject(JsonReader.java:385) 
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:213) 
    ... 9 more 

當我試圖根據其他兩個線程來解析數據,我創建了一個響應類是這樣的:

PoroResponse.class

public class PoroResponse { 

    private Map<String, Serie> serie; 

,並改變了代碼ApiTest.class到:

PoroResponse poro = gson.fromJson(jsonString, PoroResponse.class); 

,並試圖獲得一個數組通過這個一起工作:

Episode[] episodes = poro.get(poro).getSerie().getEpisodes().getEpisode(); 

我也試圖解析它是這樣的:

Object o = new Gson().fromJson(json, Object.class); 

但在雙方的最後情況下,不是我的意甲對象是NULL或我得到一個LinkedTreeMap與NULL值。

難道有人指着我正確的方向嗎?自2天以來,我一直被困在這個問題上,誠實地沒有真正的想法如何解決它。

回答

0

也許你可以試試這個: 集類

public class Episode { 

    @SerializedName("season") 
    @Expose 
    private Integer season; 
    @SerializedName("name") 
    @Expose 
    private String name; 
    @SerializedName("number") 
    @Expose 
    private Integer number; 


    public Integer getSeason() { 
     return season; 
    } 


    public void setSeason(Integer season) { 
     this.season = season; 
    } 


    public String getName() { 
     return name; 
    } 


    public void setName(String name) { 
     this.name = name; 
    } 


    public Integer getNumber() { 
     return number; 
    } 


    public void setNumber(Integer number) { 
     this.number = number; 
    } 

} 

然後串行類:

public class Serial { 

    @SerializedName("episodes") 
    @Expose 
    private List<Episode> episodes = new ArrayList<Episode>(); 
    @SerializedName("year") 
    @Expose 
    private Integer year; 

    public List<Episode> getEpisodes() { 
     return episodes; 
    } 


    public void setEpisodes(List<Episode> episodes) { 
     this.episodes = episodes; 
    } 


    public Integer getYear() { 
     return year; 
    } 


    public void setYear(Integer year) { 
     this.year = year; 
    } 

} 

然後生成一個與JSON動態密鑰Java對象只要運行這個:

Type type = new TypeToken<Map<String, Serial>>() { 
     }.getType(); 
Map<String, Serial> result = new Gson() 
       .fromJson(new InputStreamReader(new ByteArrayInputStream(jsonString.getBytes())), type); 

要獲得Narcos的系列信息,您需要編寫這個信息:

Serial narcosSerial = result.get("Narcos"); 
+0

感謝您的意見。我應該補充說Narcos是動態的關鍵。它根據對API的請求而改變。所以它總是你要求的節目的名字。 這是API的URL,如果它可能有幫助。 我將編輯我的問題,使其更清楚一點。 – Tagman

+0

@Tagman我編輯了我的答案。請看看 – user3662708

+0

非常感謝。這正是我所期待的。我仍然在試圖弄清爲什麼我只需要這兩個班。但代碼就像我想要的那樣工作。 – Tagman