使用动态密钥通过gson解析对象

时间:2016-09-14 10:09:48

标签: java json api parsing gson

就像标题所说,我试图解析一个对象,哪个键是动态字符串。我已经看了很长时间才找到答案,发现1. this,2。this和3. this

为了您的信息,我不熟悉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;

Episode.class

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

但是在最后两种情况下,我的Serie对象都是NULL或者我得到一个带有NULL值的LinkedTreeMap。

有人能指出我正确的方向吗?自从2天以来我一直坚持这个问题,老实说,如何解决这个问题并不是真的。

1 个答案:

答案 0 :(得分:0)

也许你可以试试这个: 剧集类

unsigned int TestArray[3] = {0x0604, 0x0605, 0x0606};

void TestRoutine(unsigned char Number)
{
    unsigned char Data = TestArray[Number];
    unsigned char UpperByte = (Data/256); //upper byte
    unsigned char LowerByte = (Data%256 & 0x07); //lower byte
}

然后是Serial class:

    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的动态密钥生成JAVA对象,只需运行:

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

 }

要获得Narcos序列信息,您需要写下这个:

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