2016-09-14 48 views
0

タイトルと同様、動的なStringであるオブジェクトを解析しようとしています。私はいくつかの答えをかなり長い間を見て、あなたの情報、Javaへの私はちょっと新しい1. this、2 thisと3 thisgsonを使用して動的キーでオブジェクトを解析する

を発見し、これは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}} 

ダイナミックキー、この例では「ナルコス」です。その基本的にあなたがエピソードを望むショーの名前。

私はさまざまなアプローチを試みました。最初のリンクについては は、構文解析のためのコードは次のようになります。

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であるか、NULL値でLinkedTreeMapを取得します。

誰かが正しい方向に向けるでしょうか?私は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; 
    } 

} 

次にシリアルクラス:JSONから、動的キーで

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; 
    } 

} 
その後

生成する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

ありがとうございます。私はナルコスがダイナミックキーであると付け加えておきます。 APIへのリクエストに応じて変更されます。それはいつもあなたが要求するショーの名前です。 これが役立つ場合は、これがAPIのURLです。 質問を編集して少し明確にします。 – Tagman

+0

@Tagman私は自分の答えを編集しました。どうぞご覧ください – user3662708

+0

ありがとうございました。これはまさに私が探していたものです。なぜ私はこれらの2つのクラスだけが必要なのか理解しようとしています。しかし、コードは私が望んでいたように動作します。 – Tagman

関連する問題