解析包含基元和对象的JSONArray [英] Parse JSONArray which contains primitive and objects

查看:123
本文介绍了解析包含基元和对象的JSONArray的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有JSON响应,如下所示:

  {
response:[
一些数字(例如8091),
{
在第一个JSONObject
},
{
中的一群原语在第二个JSONObject

{
第三个JSONObject中的原语
},

...(等等)







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

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



首先,你需要建立一系列模型对象来表示数据。下面是一个可能的样板:

 私有静态类TopLevel {

@SerializedName( 响应)
private final List< ResponseElement>要素;

私人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实现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
}
$ b

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



显然你必须填写 ResponseObject 和其余字段。



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

  private static class ResponseElementDeserializer实现JsonDeserializer< ResponseElement> {

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





要使用这个反序列化器,必须使用 GsonBuilder 对象在Gson上注册它。

 私有静态Gson getGson(){
返回新的GsonBuilder()
.registerTypeAdapter(ResponseElement.class,新的ResponseElementDeserializer())
.create();
}

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

  public void parseJson(){
TopLevel t = getGson()。fromJson(json,TopLevel.class); (ResponseElement元素:t.elements){
System.out.println(element);


}
}




  8061 
[450602:Поздравляем!]
[451700:СреакциейчатаирассуждениямиПапанипослерипа..]
[451578:Помним...Любим...Скорбим ...< br> 2107забираетлучших]
[451371:Землятебепухомбратишка]
[451332:Доигрался,минус900экзов< br>< br> RIP]
[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 +];
}


I have JSON response which looks like that:

{
   "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)

   ]
}

So it's an array with first integer element and other elements are JSONObject. I don't need integer element to be parsed. So how do I handle it using GSON?

解决方案

I would solve this problem by creating a custom JsonDeserializer and registering it to your Gson instance before parsing. This custom deserializer would be set up to handle both ints and real objects.

First you need to build up a series of model objects to represent the data. Here's a template for what that might look like:

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
}

TopLevel and ResponseObject have private constructors because they are going to let Gson set their fields using reflection, while ResponseInteger has a public constructor because we're going to manually invoke it from our custom deserializer.

Obviously you will have to fill out ResponseObject with the rest of its fields.

The deserializer is relatively simple. The json you posted contains only two kinds of elements, and we'll leverage this. Each time the deserializer is invoked, it checks whether the element is a primitive, and returns a ResponseInteger if so (or a ResponseObject if not).

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

To use this deserializer, you'll have to register it with Gson using the GsonBuilder object.

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

And that's it. Now you can use this Gson object to easily parse TopLevel objects!

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: ]

I used these toString() methods, which I omitted above for brevity:

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

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

这篇关于解析包含基元和对象的JSONArray的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆