19

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.

3 Answers 3

47

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));
Sign up to request clarification or add additional context in comments.

2 Comments

This is the most straightforward way, without using unnecessary wrappers or resorting to the low-level tree API. Of course, it also works with complex classes, not just strings.
This isn't what OP wants. Won't work with JSON array field, only with top-level ones.
13

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());
}

3 Comments

Correct, I can do that and in fact, I have that solution already in place. But, I didn't want to have that Wrapper. Is it possible, Thanks for your time.
@ Cássio Mazzochi Molin - Thank you
the second one worked in my case. I initially tried using wrapper class. But jackson was throwing issues with constructor not finding and similar ones, which didn't go away when I tried to resolve them. the second option worked flawlessly though.
5

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"}]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.