Search code examples
javajacksonjackson-databindjackson2

Jackson serialize nested attribute with same name


Currently, I have a JSON response of the following type.

{
   "user":{
      "user":{
         "name":"Demo",
         "age":25,
         "eail":"[email protected]"
      },
      "address":{
         "country":"NZ"
      }
   }
}

I want to map my custom class to nested user attributes.

@Data
public class Demo{
      @JsonProperty("user")
      private User user;
      private Address address;
}

But when I am trying to get the attribute, it is always sending null value. I think it is maping to first occurance of "user" in line no 2.

How can I map it to correct user attribute in line no 3.


Solution

  • Mapping starts from the root of JSON so the correct class definition for this JSON will be this

    public class Demo {
        @JsonProperty("user")
        private DemoUser user;
    }
    
    public class DemoUser {
        @JsonProperty("user")
        private User user;
    
        @JsonProperty("address")
        private Address address;
    }
    

    If you want to keep the class as it is and only want to use the inner 'user', you can do it using JsonNode like this

    ObjectMapper mapper = new ObjectMapper();
    JsonNode node = mapper.readValue(jsonString, JsonNode.class);
    Demo demo = mapper.readValue(node.at("/user").toString(), Demo.class);
    

    The at() method accepts the JSON path expression which is the path to a particular node in the JSON.

    Here, "/user" means it will find the node user from the root of JSON and will return it.

    Similarly,

    node.at("/user/user").toString();
    

    will give you

    {
      "name":"Demo",
      "age":25,
      "eail":"[email protected]"
    }