Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Map JSON string array to List<String> using Jackson

Tags:

json

jackson

I have following JSON returned from server.

 String json = {
    "values": ["name","city","dob","zip"]
 };

I want to use ObjectMapper to return the List<String> values. Something like:

List<String> response = mapper.readValue(json, List.class)

I have tried several ways but none of them worked. Any help is appreciated.


Edit: I don't want additional wrapper objects. I want to straight away get the List<String> out.

like image 756
Srinivas Avatar asked May 12 '16 12:05

Srinivas


People also ask

How do you Map a JSON array to a list of Java objects?

We can convert a JSON array to a list using the ObjectMapper class. It has a useful method readValue() which takes a JSON string and converts it to the object class specified in the second argument.

How does Jackson read JSON array?

Reading JSON from a File Thankfully, Jackson makes this task as easy as the last one, we just provide the File to the readValue() method: final ObjectMapper objectMapper = new ObjectMapper(); List<Language> langList = objectMapper. readValue( new File("langs. json"), new TypeReference<List<Language>>(){}); langList.

How do I convert JSON Map to Jackson?

Converting Map to JSONHashMap<String, String> hashmap = new HashMap<String, String>(); hashmap. put("id", "1"); hashmap. put("firstName", "Lokesh"); hashmap. put("lastName", "Gupta"); ObjectMapper mapper = new ObjectMapper(); String json = mapper.

How does Jackson read nested JSON?

A JsonNode is Jackson's tree model for JSON and it can read JSON into a JsonNode instance and write a JsonNode out to JSON. To read JSON into a JsonNode with Jackson by creating ObjectMapper instance and call the readValue() method. We can access a field, array or nested object using the get() method of JsonNode class.


3 Answers

The TypeFactory in Jackson allows to map directly to collections and other complex types:

String json = "[ \"abc\", \"def\" ]";
ObjectMapper mapper = new ObjectMapper();

List<String> list = mapper.readValue(json, TypeFactory.defaultInstance().constructCollectionType(List.class, String.class));
like image 168
Gyorgy Szekely Avatar answered Oct 10 '22 01:10

Gyorgy Szekely


You could define a wrapper class as following:

public class Wrapper {

    private List<String> values;

    // Default constructor, getters and setters omitted
}

Then use:

Wrapper wrapper = mapper.readValue(json, Wrapper.class);
List<String> values = wrapper.getValues();

If you want to avoid a wrapper class, try the following:

JsonNode valuesNode = mapper.readTree(json).get("values");

List<String> values = new ArrayList<>();
for (JsonNode node : valuesNode) {
    values.add(node.asText());
}
like image 36
cassiomolin Avatar answered Oct 10 '22 01:10

cassiomolin


There is another way you might be interested in, partly similar to accepted answer but can be written as one-liner (line breaks should help with understanding).

Input JSON:

{
    "values": ["name", "city", "dob", "zip"]
}

Code snippet:

String json = "{\"values\":[\"name\",\"city\",\"dob\",\"zip\"]}";
ObjectMapper mapper = new ObjectMapper();

List<String> list = Arrays.asList(
    mapper.convertValue(
        mapper.readTree(json).get("values"),
        String[].class
    )
);

list.forEach(System.out::println);

This code snippet outputs the following:

name
city
dob
zip

Please note that Arrays.asList() returns a list of fixed size because it is backed by a given array. To get a resizable list just wrap it like that:

List<String> resizableList = new ArrayList<>(
    Arrays.asList(new String[] {"a", "b", "c"})
);

Of course this solution can be adapted to more complex cases, not just Strings.

For example, for a given POJO User:

class User {
    private int id;
    private String name;

    public int getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    @Override
    public String toString() {
        return String.format(
            "[User = {id: %d, name: \"%s\"}]",
            id,
            name
        );
    }
}

and input JSON:

{
    "values": [{
            "id": 1,
            "name": "Alice"
        }, {
            "id": 2,
            "name": "Bob"
        }
    ]
}

following code snippet:

ObjectMapper mapper = new ObjectMapper();
String json = "{\"values\":[{\"id\":1,\"name\":\"Alice\"},{\"id\":2,\"name\":\"Bob\"}]}";

List<User> list = Arrays.asList(
    mapper.convertValue(
        mapper.readTree(json).get("values"),
        User[].class
    )
);

list.forEach(System.out::println);

yelds the following output:

[User = {id: 1, name: "Alice"}]
[User = {id: 2, name: "Bob"}]
like image 2
Ksandr Kerr Avatar answered Oct 10 '22 00:10

Ksandr Kerr