How to convert JSON string into List of Java object?
Asked Answered
N

11

89

This is my JSON Array :-

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

I have this in my String object. Now I want to convert it into Java object and store it in List of java object. e.g. In Student object. I am using below code to convert it into List of Java object : -

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

My List class is:-

public class StudentList {

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

    //getters and setters
}

My Student object is: -

class Student {

    String firstName;
    String lastName;

    //getters and setters
}

Am I missing something here? I am getting below exception: -

Exception : com.fasterxml.jackson.databind.JsonMappingException: Can not deserialize instance of com.aa.Student out of START_ARRAY token
Nonresistance answered 16/6, 2017 at 12:34 Comment(6)
You are trying deserialize List into StudentLively
Specifically: mapper.readValue(jsonString, Student.class) serializes a Student, not "a Student, or List of Students if the json looks like a List." You should use a TypeReference.Kraemer
@yshavit: -I have updated the question. Sorry for that. Please look into it once again.Nonresistance
Your JSON doesn't look like {"participantList" : []}. That's what the error is trying to tell youSerialize
here is working solution extract data from JSON string arrayArcheozoic
Here is working solution. Extract data form JSON string array and convert into ListArcheozoic
W
172

You are asking Jackson to parse a StudentList. Tell it to parse a List (of students) instead. Since List is generic you will typically use a TypeReference

List<Student> participantJsonList = mapper.readValue(jsonString, new TypeReference<List<Student>>(){});
Wampumpeag answered 16/6, 2017 at 12:37 Comment(3)
perfect answer. Always works. But I have a follow-up question. What if Student POJO has a nested hashmap structure and jsonString has a piece which should be mapped to this nested hashmap. Can someone tell how can I achieve that?Crampton
Well, I understood what I was trying to achieve. I had to change the JSON structure (which I had the liberty to). [ { "id": "1", "name": "XYZ", "thisHasToBeHashMap" : { "key1" : "value1" , "key2" :"value2" } }] Having this structure is implicitly converted using TypeReference<List<Student>>Crampton
It can be simplified to List<Student> participantJsonList = mapper.readValue(jsonString, new TypeReference<>(){});Conversational
M
17

For any one who looks for answer yet:

1.Add jackson-databind library to your build tools like Gradle or Maven

2.in your Code:

ObjectMapper mapper = new ObjectMapper();

List<Student> studentList = new ArrayList<>();

studentList = Arrays.asList(mapper.readValue(jsonStringArray, Student[].class));
Monarchal answered 1/3, 2020 at 12:10 Comment(0)
T
6

You can also use Gson for this scenario.

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

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

Your NameList class could look like:

class NameList{
 List<Name> list;
 //getter and setter
}
Tribrach answered 18/6, 2018 at 6:28 Comment(1)
This solution is more simple StackOverflow. It use TypeToken classe.Cockcrow
H
4

You can use below class to read list of objects. It contains static method to read a list with some specific object type. It is included Jdk8Module changes which provide new time class supports too. It is a clean and generic class.

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

Generic JsonMapper class:

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;
    }
}
Helmut answered 20/11, 2019 at 17:14 Comment(0)
K
4

use below simple code, no need to use any other library, besides GSON

String list = "your_json_string";
Gson gson = new Gson();                         
Type listType = new TypeToken<ArrayList<YourClassObject>>() {}.getType();
ArrayList<YourClassObject> users = new Gson().fromJson(list , listType);
Kirschner answered 3/3, 2020 at 10:25 Comment(1)
"No need to use any library"... but you're very clearly using GSON (which already has an answer provided above)?!Volcanology
E
2

I made a method to do this below called jsonArrayToObjectList. Its a handy static class that will take a filename and the file contains an array in JSON form.

 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;
    }
Experientialism answered 22/8, 2019 at 23:20 Comment(1)
This is really a good option among others because this is a simple generic function for any POJO ClassCecil
J
1
StudentList studentList = mapper.readValue(jsonString,StudentList.class);

Change this to this one

StudentList studentList = mapper.readValue(jsonString, new TypeReference<List<Student>>(){});
Jecho answered 10/12, 2018 at 10:57 Comment(0)
T
0

I have resolved this one by creating the POJO class (Student.class) of the JSON and Main Class is used for read the values from the JSON in the problem.

   **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;
} }
Teth answered 28/12, 2018 at 6:24 Comment(2)
While this code may answer the question, it would be better to include some context, explaining how it works and when to use it. Code-only answers are not useful in the long run.Tellus
@AlexRiabov have added the context to it.Teth
V
0

Gson only Solution

the safest way is to iterate over json array by JsonParser.parseString(jsonString).getAsJsonArray() and parase it's elements one by one by checking 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;
}
Veats answered 20/7, 2022 at 2:13 Comment(0)
W
0
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"
    } 
]
}
Windom answered 25/10, 2023 at 4:48 Comment(0)
L
-1

Try this. It works with me. Hope you too!

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);
Lianna answered 15/11, 2019 at 6:21 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.