使用Gson将JSON数组解析为java.util.List

问题描述 投票:0回答:7

我有一个名为

JsonObject
"mapping"
,其中包含以下内容:

{
    "client": "127.0.0.1",
    "servers": [
        "8.8.8.8",
        "8.8.4.4",
        "156.154.70.1",
        "156.154.71.1"
    ]
}

我知道我可以通过以下方式获取数组

"servers"

mapping.get("servers").getAsJsonArray()

现在我想将

JsonArray
解析为
java.util.List
...

最简单的方法是什么?

java json parsing gson
7个回答
319
投票

最简单的方法绝对是使用 Gson 的默认解析函数

fromJson()

当您需要反序列化为任何

ParameterizedType
(例如任何
List
)时,该函数有一个适合的实现,即
fromJson(JsonElement json, Type typeOfT)

在你的例子中,你只需要获取 Type

List<String>
,然后将 JSON 数组解析为 
Type
,如下所示:

import java.lang.reflect.Type;
import com.google.gson.reflect.TypeToken;

JsonElement yourJson = mapping.get("servers");
Type listType = new TypeToken<List<String>>() {}.getType();

List<String> yourList = new Gson().fromJson(yourJson, listType);

在您的情况下,

yourJson
是一个
JsonElement
,但它也可能是一个
String
,任何
Reader
JsonReader

您可能想查看 Gson API 文档


19
投票

下面的代码使用了

com.google.gson.JsonArray
。 我已经打印了列表中元素的数量以及列表中的元素

import java.util.ArrayList;

import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;


public class Test {

    static String str = "{ "+ 
            "\"client\":\"127.0.0.1\"," + 
            "\"servers\":[" + 
            "    \"8.8.8.8\"," + 
            "    \"8.8.4.4\"," + 
            "    \"156.154.70.1\"," + 
            "    \"156.154.71.1\" " + 
            "    ]" + 
            "}";

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        try {

            JsonParser jsonParser = new JsonParser();
            JsonObject jo = (JsonObject)jsonParser.parse(str);
            JsonArray jsonArr = jo.getAsJsonArray("servers");
            //jsonArr.
            Gson googleJson = new Gson();
            ArrayList jsonObjList = googleJson.fromJson(jsonArr, ArrayList.class);
            System.out.println("List size is : "+jsonObjList.size());
                    System.out.println("List Elements are  : "+jsonObjList.toString());


        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

}

输出

List size is : 4

List Elements are  : [8.8.8.8, 8.8.4.4, 156.154.70.1, 156.154.71.1]

11
投票

我在Gson官方网站这里

阅读了解决方案

这个代码给你:

    String json = "{"client":"127.0.0.1","servers":["8.8.8.8","8.8.4.4","156.154.70.1","156.154.71.1"]}";

    JsonObject jsonObject = new Gson().fromJson(json, JsonObject.class);
    JsonArray jsonArray = jsonObject.getAsJsonArray("servers");

    String[] arrName = new Gson().fromJson(jsonArray, String[].class);

    List<String> lstName = new ArrayList<>();
    lstName = Arrays.asList(arrName);

    for (String str : lstName) {
        System.out.println(str);
    }    

结果显示在显示器上:

8.8.8.8
8.8.4.4
156.154.70.1
156.154.71.1

4
投票

Kotlin 扩展

对于 Kotlin 开发者,您可以使用此扩展

inline fun <reified T> String.convertToListObject(): List<T>? {
    val listType: Type = object : TypeToken<List<T?>?>() {}.type
    return Gson().fromJson<List<T>>(this, listType)
}

2
投票

我能够让列表映射仅使用

@SerializedName
来处理所有字段..不需要围绕
Type
的逻辑。

运行代码 - 在下面的步骤 #4 - 通过调试器,我可以观察到

List<ContentImage> mGalleryImages
对象填充了 JSON 数据

这是一个例子:

1。 JSON

   {
    "name": "Some House",
    "gallery": [
      {
        "description": "Nice 300sqft. den.jpg",
        "photo_url": "image/den.jpg"
      },
      {
        "description": "Floor Plan",
        "photo_url": "image/floor_plan.jpg"
      }
    ]
  }

2。带有 List 的 Java 类

public class FocusArea {

    @SerializedName("name")
    private String mName;

    @SerializedName("gallery")
    private List<ContentImage> mGalleryImages;
}

3.列表项的 Java 类

public class ContentImage {

    @SerializedName("description")
    private String mDescription;

    @SerializedName("photo_url")
    private String mPhotoUrl;

    // getters/setters ..
}

4。处理 JSON 的 Java 代码

    for (String key : focusAreaKeys) {

        JsonElement sectionElement = sectionsJsonObject.get(key);
        FocusArea focusArea = gson.fromJson(sectionElement, FocusArea.class);
    }

0
投票

鉴于您从

mapping.get("servers").getAsJsonArray()
开始,如果您可以访问 Guava
Streams
,您可以执行以下一行操作:

List<String> servers = Streams.stream(jsonArray.iterator())
                              .map(je -> je.getAsString())
                              .collect(Collectors.toList());

注意

StreamSupport
无法在
JsonElement
类型上工作,所以它是不够的。


0
投票

这是读取 json 文件并将其解析为对象列表的一种方法

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


private List<Student> readFromJsonFile(String fileName) throws IOException {
    Resource resource = resourceLoader.getResource("classpath:" + fileName);

    try (BufferedReader reader = new BufferedReader(
            new InputStreamReader(resource.getInputStream(), StandardCharsets.UTF_8))) {
        
        Type listType = new TypeToken<List<Student>>() {
        }.getType();
        return new Gson().fromJson(reader, listType);
    }
}

“classpath:”表示Spring Boot项目中的资源文件夹。根据您的情况可以修改。

© www.soinside.com 2019 - 2024. All rights reserved.