50

I am having a question with Jackson that I think should be simple to solve, but it is killing me.

Let's say I have a java POJO class that looks like this (assume Getters and Setters for me):

class User {
    private String name;
    private Integer age;
}

And I want to deserialize JSON that looks like this into a User object:

{
  "user":
    {
      "name":"Sam Smith",
      "age":1
  }
}

Jackson is giving me issues because the User is not the first-level object in the JSON. I could obviously make a UserWrapper class that has a single User object and then deserialize using that but I know there must be a more elegant solution.

How should I do this?

Sam Stern
  • 24,624
  • 13
  • 93
  • 124

1 Answers1

75

edit: this solution only works for jackson < 2.0

For your case there is a simple solution:

  • You need to annotate your model class with @JsonRootName(value = "user");
  • You need to configure your mapper with om.configure(Feature.UNWRAP_ROOT_VALUE, true); (as for 1.9) and om.configure(DeserializationFeature.UNWRAP_ROOT_VALUE, true); (for version 2).

That's it!


@JsonRootName(value = "user")
public static class User {
    private String name;
    private Integer age;

    public String getName() {
        return name;
    }

    public void setName(final String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(final Integer age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "User [name=" + name + ", age=" + age + "]";
    }

}

ObjectMapper om = new ObjectMapper();
om.configure(Feature.UNWRAP_ROOT_VALUE, true);
System.out.println(om.readValue("{  \"user\":    {      \"name\":\"Sam Smith\",      \"age\":1  }}", User.class));

this will print:

User [name=Sam Smith, age=1]
Chase
  • 2,748
  • 2
  • 23
  • 32
Francisco Spaeth
  • 23,493
  • 7
  • 67
  • 106
  • 5
    For anyone who comes to this page in the future, I'd like to note that this only works with Jackson < 2.0 (when it was Codehaus, before it was migrated to FasterXML). I can't find UNWRAP_ROOT_VALUE in the FasterXML Package. – Sam Stern Jul 29 '12 at 21:54
  • 25
    I think it's now DeserializationFeature.UNWRAP_ROOT_VALUE – jsh Aug 06 '12 at 19:37
  • 1
    But what you supposed to do in case API exposes both User and List ? – keiw Feb 05 '14 at 13:45
  • Also for jackson 2.2 the feature is SerializationFeature.WRAP_ROOT_VALUE – Koitoer Feb 10 '14 at 19:40
  • 2
    So I know this thread is old, but ist there a solution for when your JSON looks like this? { "user”: [ { "name":"Sam Smith", "age":1 }] } Assuming you can be sure that “user” always is an array with one entry – florian Sep 26 '14 at 09:04
  • @FranciscoSpaeth I'm curious about the significance of `@JsonRootName(value = "user");` because even without it, the class name "User" is used as the root element and it works just fine – pedram bashiri Apr 16 '18 at 16:38
  • @pedrambashiri right, from my understanding it will use "user" then and not "User" – Francisco Spaeth Apr 16 '18 at 17:05