解析包含基元和对象的JSONArray

时间:2017-08-15 16:05:00

标签: java android arrays json gson

我有JSON响应,看起来像这样:

{
   "response":[
      "Some number (for example 8091)",
      {
         "Bunch of primitives inside the first JSONObject"
      },
      {
         "Bunch of primitives inside the second JSONObject"
      },
      {
         "Bunch of primitives inside the third JSONObject"
      },

      ... (and so on)

   ]
}

所以它是一个带有第一个整数元素的数组,其他元素是JSONObject。 我不需要解析整数元素。那么如何使用GSON处理它?<​​/ p>

4 个答案:

答案 0 :(得分:1)

我会通过创建自定义JsonDeserializer并在解析之前将其注册到Gson实例来解决此问题。此自定义反序列化器将设置为处理int和真实对象。

首先,您需要构建一系列模型对象来表示数据。这是一个可能看起来像什么的模板:

private static class TopLevel {

    @SerializedName("response")
    private final List<ResponseElement> elements;

    private TopLevel() {
        this.elements = null;
    }
}

private static class ResponseInteger implements ResponseElement {

    private final int value;

    public ResponseInteger(int value) {
        this.value = value;
    }
}

private static class ResponseObject implements ResponseElement {

    @SerializedName("id")
    private final String id;

    @SerializedName("text")
    private final String text;

    private ResponseObject() {
        this.id = null;
        this.text = null;
    }
}

private interface ResponseElement {
    // marker interface
}

TopLevelResponseObject有私有构造函数,因为它们会让Gson使用反射设置字段,而ResponseInteger有一个公共构造函数,因为我们要手动调用它来自我们的自定义解串器。

显然,您必须在其余字段中填写ResponseObject

解串器相对简单。您发布的json只包含两种元素,我们将利用它。每次调用反序列化器时,它都会检查元素是否为基元,如果是,则返回ResponseInteger(如果不是,则返回ResponseObject。)

private static class ResponseElementDeserializer implements JsonDeserializer<ResponseElement> {

    @Override
    public ResponseElement deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
        if (json.isJsonPrimitive()) {
            return new ResponseInteger(json.getAsInt());
        }
        else {
            return context.deserialize(json, ResponseObject.class);
        }
    }
}

要使用此反序列化器,您必须使用GsonBuilder对象向Gson注册它。

private static Gson getGson() {
    return new GsonBuilder()
            .registerTypeAdapter(ResponseElement.class, new ResponseElementDeserializer())
            .create();
}

就是这样。现在,您可以使用此Gson对象轻松解析TopLevel个对象!

public void parseJson() {
    TopLevel t = getGson().fromJson(json, TopLevel.class);

    for (ResponseElement element : t.elements) {
        System.out.println(element);
    }
}
8061
[450602: Поздравляем!]
[451700: С реакцией чата и рассуждениями Папани после рипа..]
[451578: Помним...Любим...Скорбим...<br>2107 забирает лучших]
[451371: Земля тебе пухом братишка]
[451332: Доигрался, минус 900 экзов<br><br>R I P]
[451269: ]
[451242: https://www.twitch.tv/arthas подрубка<br><br>evilpapech.ru - скидка 30% на футболки!]
[451217: ]
[451181: или так це жерстко?]
[451108: ]

我使用了这些toString()方法,为简洁起见,我在上面省略了这些方法:

    @Override
    public String toString() {
        return Integer.toString(value);
    }

    @Override
    public String toString() {
        return "[" + id + ": " + text + "]";
    }

答案 1 :(得分:0)

基本上,这种结构是JSON数据的错误格式。 您需要删除该数字,或将此数字作为一个字段放在同一个对象中,如下所示(调用ObjectA)并考虑这是一个ObjectA数组。 一切都应该运作良好。请尝试以下代码:

public class Response {
    @SerializedName("response")
    @Expose
    public List<ObjectA> objectA = null;
}

public class ObjectA {
    @SerializedName("value")
    @Expose
    public Integer value;
    @SerializedName("description")
    @Expose
    public String description;
}

Response response = new Gson().fromJson(responseString, Response.class);

答案 2 :(得分:0)

试试这个

Gson gson = new Gson();

// Reading from a file.
Example example = gson.fromJson(new FileReader("D:\\content.json"), Example.class);

<强> POJO

package com.example;

public class Example {

private List<Integer> response = null;

public List<Integer> getResponse() {
return response;
}

public void setResponse(List<Integer> response) {
this.response = response;
}

}

答案 3 :(得分:0)

请使用下面的ValueObject格式,它不解析第一个整数元素

public class ResponseVO {
    public List<Response> response = new ArrayList();
    public class Response {
        public final long id;
        public final long from_id;
        ...
    }
}