Как преобразовать строку JSON в список объектов Java?

Это мой массив JSON: -

[ 
    {
        "firstName" : "abc",
        "lastName" : "xyz"
    }, 
    {
        "firstName" : "pqr",
        "lastName" : "str"
    } 
]

У меня есть это в моем объекте String. Теперь я хочу преобразовать его в объект Java и сохранить его в списке объектов Java. например, в объекте Student. Я использую код ниже, чтобы преобразовать его в список объектов Java: -

ObjectMapper mapper = new ObjectMapper();
StudentList studentList = mapper.readValue(jsonString, StudentList.class);

Мой список класса: -

public class StudentList {

    private List<Student> participantList = new ArrayList<Student>();

    //getters and setters
}

Мой Студент объект: -

class Student {

    String firstName;
    String lastName;

    //getters and setters
}

Я что-то здесь упускаю? Я получаю ниже исключения: -

Exception : com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of com.aa.Student out of START_ARRAY token

11 ответов

Решение

Вы просите Джексона разобрать StudentList, Скажите это, чтобы разобрать List (студентов) вместо. поскольку List является общим, вы обычно будете использовать TypeReference

List<Student> participantJsonList = mapper.readValue(jsonString, new TypeReference<List<Student>>(){});

Для тех, кто еще ищет ответ:

1. добавить jackson-databind библиотека для ваших инструментов сборки, таких как Gradle или Maven

2. в ваших кодах:

 add:
               ObjectMapper mapper = new ObjectMapper();
               List<Student> studentList = new ArrayList<>();

               studentList = Arrays.asList(mapper.readValue(jsonStringArray, Student[].class));

Вы также можете использовать Gson для этого сценария.

Gson gson = new Gson();
NameList nameList = gson.fromJson(data, NameList.class);

List<Name> list = nameList.getList();

Ваш класс NameList может выглядеть так:

class NameList{
 List<Name> list;
 //getter and setter
}

Вы можете использовать класс ниже, чтобы прочитать список объектов. Он содержит статический метод для чтения списка с определенным типом объекта. Включены изменения Jdk8Module, которые также обеспечивают поддержку нового класса времени. Это чистый и универсальный класс.

List<Student> students = JsonMapper.readList(jsonString, Student.class);

Общий класс JsonMapper:

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;

import java.io.IOException;
import java.util.*;

import java.util.Collection;

public class JsonMapper {

    public static <T> List<T> readList(String str, Class<T> type) {
        return readList(str, ArrayList.class, type);
    }

    public static <T> List<T> readList(String str, Class<? extends Collection> type, Class<T> elementType) {
        final ObjectMapper mapper = newMapper();
        try {
            return mapper.readValue(str, mapper.getTypeFactory().constructCollectionType(type, elementType));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    private static ObjectMapper newMapper() {
        final ObjectMapper mapper = new ObjectMapper();
        mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        mapper.registerModule(new JavaTimeModule());
        mapper.registerModule(new Jdk8Module());
        return mapper;
    }
}

Используйте простой код ниже, не нужно использовать какую-либо библиотеку

String list = "your_json_string";
Gson gson = new Gson();                         
Type listType = new TypeToken<ArrayList<YourClassObject>>() {}.getType();
ArrayList<YourClassObject> users = new Gson().fromJson(list , listType);

Я сделал способ сделать это ниже, названный jsonArrayToObjectList. Это удобный статический класс, который будет принимать имя файла, а файл содержит массив в форме JSON.

 List<Items> items = jsonArrayToObjectList(
            "domain/ItemsArray.json",  Item.class);

    public static <T> List<T> jsonArrayToObjectList(String jsonFileName, Class<T> tClass) throws IOException {
        ObjectMapper mapper = new ObjectMapper();
        final File file = ResourceUtils.getFile("classpath:" + jsonFileName);
        CollectionType listType = mapper.getTypeFactory()
            .constructCollectionType(ArrayList.class, tClass);
        List<T> ts = mapper.readValue(file, listType);
        return ts;
    }
StudentList studentList = mapper.readValue(jsonString,StudentList.class);

Измени это на это

StudentList studentList = mapper.readValue(jsonString, new TypeReference<List<Student>>(){});
      In your json , top most element name should be matched with the name of variable in your wrapper class. That will Jacson to convert my json into participantJsonList.
{
"participantJsonList" : [ 
    {
        "firstName" : "abc",
        "lastName" : "xyz"
    }, 
    {
        "firstName" : "pqr",
        "lastName" : "str"
    } 
]
}

Я решил эту проблему, создав класс POJO (Student.class) из JSON, а основной класс используется для чтения значений из JSON в задаче.

   **Main Class**

    public static void main(String[] args) throws JsonParseException, 
       JsonMappingException, IOException {

    String jsonStr = "[ \r\n" + "    {\r\n" + "        \"firstName\" : \"abc\",\r\n"
            + "        \"lastName\" : \"xyz\"\r\n" + "    }, \r\n" + "    {\r\n"
            + "        \"firstName\" : \"pqr\",\r\n" + "        \"lastName\" : \"str\"\r\n" + "    } \r\n" + "]";

    ObjectMapper mapper = new ObjectMapper();

    List<Student> details = mapper.readValue(jsonStr, new 
      TypeReference<List<Student>>() {      });

    for (Student itr : details) {

        System.out.println("Value for getFirstName is: " + 
                  itr.getFirstName());
        System.out.println("Value for getLastName  is: " + 
                 itr.getLastName());
    }
}

**RESULT:**
         Value for getFirstName is: abc
         Value for getLastName  is: xyz
         Value for getFirstName is: pqr
         Value for getLastName  is: str


 **Student.class:**

public class Student {
private String lastName;

private String firstName;

public String getLastName() {
    return lastName;
}

public String getFirstName() {
    return firstName;
} }

Только решение Gson

самый безопасный способ - перебрать массив json с помощьюJsonParser.parseString(jsonString).getAsJsonArray()и проанализируйте его элементы один за другим, проверивjsonObject.has("key").

      import com.google.gson.JsonArray;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import lombok.Data;
      @Data
class Foo {
    String bar;
    Double tar;
}
      JsonArray jsonArray = JsonParser.parseString(jsonString).getAsJsonArray();
List<Foo> objects = new ArrayList<>();
jsonArray.forEach(jsonElement -> {
    objectList.add(JsonToObject(jsonElement.getAsJsonObject()));
});
      Foo parseJsonToFoo(JsonObject jsonObject) {
    Foo foo = new Foo();
    if (jsonObject.has("bar")) {
        String data = jsonObject.get("bar").getAsString();
        foo.setBar(data);
    }
    if (jsonObject.has("tar")) {
        Double data = jsonObject.get("tar").getAsDouble();
        foo.setTar(data);
    }
    return foo;
}

Попробуй это. У меня это работает. Надеюсь ты тоже!

List<YOUR_OBJECT> testList = new ArrayList<>();
testList.add(test1);

Gson gson = new Gson();

String json = gson.toJson(testList);

Type type = new TypeToken<ArrayList<YOUR_OBJECT>>(){}.getType();

ArrayList<YOUR_OBJECT> array = gson.fromJson(json, type);

Другие вопросы по тегам