如何使用 Gson 解析 JSON 包含数组的文件

How to use Gson to parse JSON file that contains arrays

我正在尝试从 this URL using ion、Android 和 Gson 的库中读取 JSON 文件。

JSON 文件的当前状态:

{
    "Excited":["https://github.com/vedantroy/image-test/raw/master/Happy/excited1.gif",
                "https://github.com/vedantroy/image-test/raw/master/Happy/excited2.gif",
                "https://github.com/vedantroy/image-test/raw/master/Happy/excited3.gif"],

    "Sad":["https://github.com/vedantroy/image-test/raw/master/Sad/sad1.gif",
            "https://github.com/vedantroy/image-test/raw/master/Sad/sad2.gif",
            "https://github.com/vedantroy/image-test/raw/master/Sad/sad3.gif",
            "https://github.com/vedantroy/image-test/raw/master/Sad/sad4.gif"]

}

重要说明:虽然现在 JSON 文件有两个数组,"Excited" 和 "Sad",但它可能有更多数组未来。但是,文件的基本结构始终是一系列 JSON 数组。

我的objective是将这个包含两个(但可以更多)数组的JSON对象转换成列表的列表。

到目前为止,这是我的代码,它解析了 URL 和 returns 一个名为 "result":

的 Gson JsonObject
Ion.with(applicationContext)
                .load("https://raw.githubusercontent.com/vedantroy/image-test/master/index.json")
                .asJsonObject()
                .setCallback { e, result ->
                    //Do something...
                }

这段代码也可以写成:

Ion.with(applicationContext)
                .load("https://raw.githubusercontent.com/vedantroy/image-test/master/index.json")
                .asJsonObject()
                .setCallback(object : FutureCallback<JsonObject> {
                    override fun onCompleted(e: Exception?, result: JsonObject?) {
                        TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
                    }

                })

遍历 JsonObject entrySet 并将每个 JsonArray 添加到列表中,我使用我的 Java 代码,如果需要,您可以将其转换为 Kotlin:

ArrayList<JsonArray> result = new ArrayList<>();
for (Map.Entry<String, JsonElement> entry : resultJson.entrySet()) {
    if (entry.getValue().isJsonArray()) {
        result.add(entry.getValue().getAsJsonArray());
    }
}

如果你能重构这个 JSON,我会使用这样的东西,对我来说这更容易 serialize/deserialize 并且看起来更语义化(并且是一个 JSON 数组, JSON 你发送的只是一个 JSON 对象)

[{
    "mood": "Excited",
    "gifs": ["https://github.com/vedantroy/image-test/raw/master/Happy/excited1.gif",
        "https://github.com/vedantroy/image-test/raw/master/Happy/excited2.gif",
        "https://github.com/vedantroy/image-test/raw/master/Happy/excited3.gif"
    ]
},

{
    "mood": "Sad",
    "gifs": ["https://github.com/vedantroy/image-test/raw/master/Sad/sad1.gif",
        "https://github.com/vedantroy/image-test/raw/master/Sad/sad2.gif",
        "https://github.com/vedantroy/image-test/raw/master/Sad/sad3.gif",
        "https://github.com/vedantroy/image-test/raw/master/Sad/sad4.gif"
    ]
}
]

使用这个 JSON,你可以在 Java 中像这样反序列化,所以你将不得不使用 Ion 库来适应 Kotlin

import java.util.ArrayList;
import java.util.List;

import org.json.JSONArray;

import com.google.common.reflect.TypeToken;
import com.google.gson.Gson;

public class Deserializer {

    public static void main(String[] args) {
       JSONArray json = new JSONArray(
            "[{\"mood\": \"Excited\",\"gifs\": [\"https://github.com/vedantroy/image-test/raw/master/Happy/excited1.gif\",\"https://github.com/vedantroy/image-test/raw/master/Happy/excited2.gif\",\"https://github.com/vedantroy/image-test/raw/master/Happy/excited3.gif\"]},{\"mood\": \"Sad\",\"gifs\": [\"https://github.com/vedantroy/image-test/raw/master/Sad/sad1.gif\",\"https://github.com/vedantroy/image-test/raw/master/Sad/sad2.gif\",\"https://github.com/vedantroy/image-test/raw/master/Sad/sad3.gif\",\"https://github.com/vedantroy/image-test/raw/master/Sad/sad4.gif\"]}]");
       Gson gson = new Gson();
       List<YourObject> test = gson.fromJson(json.toString(), new TypeToken<ArrayList<YourObject>>() {}.getType());
       test.forEach(System.out::println);
    }

    public static class YourObject {

        private String mood;
        private List<String> gifs;

        @Override
        public String toString() {
            return this.mood.toString() + " " + this.gifs.toString();
       }
    }
}