【问题标题】:Gson- Parsing a JSON array of JSON objects to ArrayList<org.json.JSONObject>Gson- 将 JSON 对象的 JSON 数组解析为 ArrayList<org.json.JSONObject>
【发布时间】:2017-02-10 10:31:33
【问题描述】:

我有一个这样的 JSON 字符串:

{
  "r": [
    {
      "pic": "1.jpg",
      "name": "Name1"
    },
    {
      "pic": "2.jpg",
      "name": "Name2"
    },
    {
      "pic": "3.jpg",
      "name": "Name3"
    }
  ]
}

我要解析成这个 POJO 模型:

public class Catalog {
    @SerializedName("r")
    @Expose
    private List<JSONObject> r = new ArrayList<JSONObject>();

    public List<JSONObject> getR() {
        return r;
    }

    public void setR(List<JSONObject> r) {
        this.r = r;
    }
}

我是这样解析的:

Catalog cat = new Gson().fromJson(jsonString,Catalog.class);

但终于得到了这个 json

{
  "r": [
    {
      "nameValuePairs": {}
    },
    {
      "nameValuePairs": {}
    },
    {
      "nameValuePairs": {}
    }
  ]
}

请注意,我不想使用com.google.gson.JsonObject我想使用org.json.JSONObject。由于我的几乎所有代码都使用它,如何实现这一点?

【问题讨论】:

  • 实现您的JsonDeseriailzer&lt;org.json.JSONObject&gt; 并将其注册到GsonBuilder.registerTypeAdapter(JSONObject.class, jsonObjectJsonDeserializerInstance)。但是,为什么需要使用JSONObject 而不是带有picname 字段的Java 映射?
  • 你为什么要org.json.JSONObject??
  • JSONObjectsJSONArray 转换为JSONObjectsList 的原因是什么?您可以在 JSONArrayList 中迭代 JSONObjects

标签: java android json arraylist gson


【解决方案1】:

正如在其他答案和 cmets 中已经提到的那样,出于多种原因,您可能真的不想使用 org.json.JSONObject。但是如果这对你来说是必须的,你只需要创建你的 org.json.JSONObject-aware Gson 实例。

final class JSONObjectJsonDeserializer
        implements JsonDeserializer<JSONObject> {

    // The implementation is fully thread-safe and can be instantiated once
    private static final JsonDeserializer<JSONObject> jsonObjectJsonDeserializer = new JSONObjectJsonDeserializer();

    // Type tokens are immutable values and therefore can be considered constants (and final) and thread-safe as well
    private static final TypeToken<Map<String, Object>> mapStringToObjectTypeToken = new TypeToken<Map<String, Object>>() {
    };

    private JSONObjectJsonDeserializer() {
    }

    static JsonDeserializer<JSONObject> getJsonObjectJsonDeserializer() {
        return jsonObjectJsonDeserializer;
    }

    @Override
    public JSONObject deserialize(final JsonElement jsonElement, final Type type, final JsonDeserializationContext context) {
        // Convert the input jsonElement as if it were a Map<String, Object> (a generic representation for JSON objectS)
        final Map<String, Object> map = context.deserialize(jsonElement, mapStringToObjectTypeToken.getType());
        // And forward the map to the JSONObject constructor - it seems to accept it nice
        return new JSONObject(map);
    }

}

Gson 被设计为线程安全的,不需要在每次需要序列化或反序列化时都实例化:

private static final Gson gson = new GsonBuilder()
        .registerTypeAdapter(JSONObject.class, getJsonObjectJsonDeserializer())
        .create();

最后:

final Catalog catalog = gson.fromJson(jsonString, Catalog.class);
out.println(catalog.getR());

结果如下:

[{"name":"Name1","pic":"1.jpg"}, {"name":"Name2","pic":"2.jpg"}, {"name":" Name3","pic":"3.jpg"}]

无论如何,我建议您重新设计映射模型。

【讨论】:

  • 太棒了。谢谢你。它按预期工作。但是我创建了一个 pojo 来替换 JSONObject。最好立即进行映射,而不是使用 Deserializer 解析它的开销。
【解决方案2】:

我认为你不需要JSONObject

试试这个

// is wrapped class for serialized json. 
public class JsonExample
{
    List<Catalog> r;
}

public class Catalog {
    private String pic;
    private String name;

    public String getPic() {
        return pic;
    }

    public String getName() {
        return name;
    }
}

JsonExample example = new Gson().fromJson(json, JsonExample.class);

附加 - 使用JSONObject

JSONObject obj = new JSONObject(json);
JSONArray arr = obj.getJSONArray("r");

List<Catalog> cataList = new ArrayList<>();

for(int i = 0 ; i < arr.length() ; ++i)
{
    cataList.add(new Catalog(arr.getJSONObject(i)));
}

public class Catalog {
    private String pic;
    private String name;

    public Catalog(JSONObject obj) throws JSONException
    {
        pic = obj.getString("pic");
        name = obj.getString("name");
    }

    public String getPic() {
        return pic;
    }

    public String getName() {
        return name;
    }
}

【讨论】:

    【解决方案3】:

    我认为在您的情况下,根本不需要使用 gson 库。 只有org.json才能解决整个问题。

    例如:

    JSONObject json = new JSONObject(jsonString);
    
    JSONArray jsonArray = json.getJSONArray("r");
    
    List<JSONObject> jsonList = new ArrayList<>();
    for (int i = 0; i < jsonArray.length(); i++) {
      jsonList.add(jsonArray.getJSONObject(i));
    }
    
    Catalog catalog = new Catalog();        
    catalog.setR(jsonList);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-09-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多