Java JSON 转 List 类型转换异常解析

在 Java 开发中,我们经常需要将 JSON 数据转换为 Java 对象来进行处理。然而,有时候我们遇到了将 JSON 转换为 List 类型时出现的类型转换异常。本文将探讨这个异常的产生原因以及解决方法,并提供相应的代码示例。

异常现象

当我们使用 Java 的 JSON 库(如 Jackson、Gson 等)将 JSON 数据转换为 List 类型时,可能会遇到以下异常:

com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of `java.util.ArrayList` out of START_OBJECT token

这个异常告诉我们在将 JSON 数据转换为 List 类型时出现了类型不匹配的问题。那么为什么会出现这个异常呢?

异常原因

要理解这个异常的原因,我们首先需要了解 JSON 数据的结构。在 JSON 中,对象(Object)用花括号 {} 包裹,数组(Array)用方括号 [] 包裹。例如,下面是一个 JSON 对象的示例:

{
  "name": "Alice",
  "age": 25
}

而下面是一个 JSON 数组的示例:

[
  {
    "name": "Alice",
    "age": 25
  },
  {
    "name": "Bob",
    "age": 30
  }
]

当我们将 JSON 数据转换为 List 类型时,实际上是期望将 JSON 数组转换为 List 对象。然而,如果 JSON 数据本身是一个 JSON 对象,而不是数组,那么就会出现类型转换异常。

解决方法

要解决这个类型转换异常,我们需要根据 JSON 数据的结构来选择合适的转换方法。

JSON 数据为数组

如果 JSON 数据是一个数组,我们可以直接将其转换为 List 类型。下面是一个使用 Jackson 库将 JSON 数组转换为 List 的示例代码:

import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.IOException;
import java.util.List;

public class JsonToListExample {
    public static void main(String[] args) throws IOException {
        String json = "[{\"name\":\"Alice\",\"age\":25},{\"name\":\"Bob\",\"age\":30}]";
        ObjectMapper objectMapper = new ObjectMapper();
        List<Person> persons = objectMapper.readValue(json, new TypeReference<List<Person>>() {});
        for (Person person : persons) {
            System.out.println(person.getName() + ", " + person.getAge());
        }
    }
}

class Person {
    private String name;
    private int age;
    
    // Getter and Setter methods
}

在上面的代码中,我们使用了 Jackson 库的 readValue 方法将 JSON 数组转换为 List 对象。通过指定 TypeReference<List<Person>>,我们告诉 Jackson 库将 JSON 数组转换为 List<Person> 类型。

JSON 数据为对象

如果 JSON 数据本身是一个对象,我们可以使用以下两种方法来进行转换:

方法一:手动转换

我们可以先将 JSON 对象转换为一个包含 JSON 对象的数组,然后再将其转换为 List 类型。下面是一个示例代码:

String json = "{\"name\":\"Alice\",\"age\":25}";
ObjectMapper objectMapper = new ObjectMapper();
List<Person> persons = objectMapper.readValue("[" + json + "]", new TypeReference<List<Person>>() {});

在这个示例中,我们首先在 JSON 对象的两端添加了方括号 [],将其转换为一个包含 JSON 对象的数组。然后,我们再使用 readValue 将其转换为 List 类型。

方法二:使用自定义解析器

我们可以自定义一个解析器来处理 JSON 数据为对象的情况。下面是一个示例代码:

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
import java.io.IOException;
import java.util.List;

public class JsonToListExample {
    public static void main(String[] args) throws IOException {
        String json = "{\"name\":\"Alice\",\"age\":25}";
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.addDeserializer(List.class, new ObjectToListDeserializer<>(Person.class));
        List<Person> persons = objectMapper.readValue(json, new TypeReference<List<Person>>() {});
        for (Person person : persons) {
            System.out.println(person.getName() + ", " + person.getAge());
        }
    }
}

class Person {
    private String name;
    private int age;
    
    // Getter and Setter methods