Akshay
Akshay

Reputation: 1817

Not able to wrap JSON properties in a Custom Java Class in Jackson

I have a JSON string that needs to be converted to JAVA Object. I need to wrap some fields into a different JAVA class. The problem I am facing I am not able to wrap it and I get the Java fields as null. Please see below JSON

{
    "first_name": "John",
    "last_name": "DCosta",
    "age": "29",
    "phone": "+173341238",
    "address_line_1": "43 Park Street",
    "address_line_2": "Behind C21 Mall",
    "city": "Cario",
    "country": "UK",
    "child1": {
        "name": "Peter",
        "age": "5"
    },
    "child2": {
        "name": "Paddy",
        "age": "2"
    },
    "child3": {
        "name": "Premus",
        "age": "1"
    }
}

Please see my JAVA Classes Below -

Details.java

public class Details {
    
    private Person person;
    private Address address;
    private Child[] children;
    
    public Person getPerson() {
        return person;
    }
    public void setPerson(Person person) {
        this.person = person;
    }
    public Address getAddress() {
        return address;
    }
    public void setAddress(Address address) {
        this.address = address;
    }
    public Child[] getChildren() {
        return children;
    }
    public void setChildren(Child[] children) {
        this.children = children;
    }

}

Person.java

import com.fasterxml.jackson.annotation.JsonProperty;

    public class Person {
        
        @JsonProperty("first_name") 
        private String firstName;
        
        @JsonProperty("last_name")
        private String lastName;
        
        @JsonProperty("age")
        private Integer age;
    
    
        public String getFirstName() {
            return firstName;
        }
    
        public void setFirstName(String firstName) {
            this.firstName = firstName;
        }
    
        public String getLastName() {
            return lastName;
        }
    
        public void setLastName(String lastName) {
            this.lastName = lastName;
        }
    
        public Integer getAge() {
            return age;
        }
    
        public void setAge(Integer age) {
            this.age = age;
        }
        
        
    
    }

Address.java

import com.fasterxml.jackson.annotation.JsonProperty;

public class Address {
    
    @JsonProperty("phone")
    private String phone;
    
    @JsonProperty("address_line_1")
    private String addressLine1;
    
    @JsonProperty("address_line_2")
    private String addressLine2;
    
    @JsonProperty("city")
    private String city;
    
    @JsonProperty("country")
    private String country;

    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }

    public String getAddressLine1() {
        return addressLine1;
    }

    public void setAddressLine1(String addressLine1) {
        this.addressLine1 = addressLine1;
    }

    public String getAddressLine2() {
        return addressLine2;
    }

    public void setAddressLine2(String addressLine2) {
        this.addressLine2 = addressLine2;
    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

    public String getCountry() {
        return country;
    }

    public void setCountry(String country) {
        this.country = country;
    }

}

Child.java

public class Child {
    
    private String name;
    private Integer age;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Integer getAge() {
        return age;
    }
    public void setAge(Integer age) {
        this.age = age;
    }

}

My Code to convert JSON to JAVA Object -

    String filePath = "test.json";
    File file = new File(filePath);
    ObjectMapper mapper = new ObjectMapper();
    mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    Details details = mapper.readValue(file, Details.class);
    
    System.out.println(details.getPerson());

The problem I am facing is I am getting all the values in the details object are null. If I remove the mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); then I get the below exception

Exception in thread "main" com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "first_name" (class learn.springboot.model.Details), not marked as ignorable (3 known properties: "address", "person", "children"])
 at [Source: (File); line: 2, column: 17] (through reference chain: learn.springboot.model.Details["first_name"])
    at com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException.from(UnrecognizedPropertyException.ja

Upvotes: 0

Views: 413

Answers (1)

Reza Ebrahimpour
Reza Ebrahimpour

Reputation: 914

I don't think that it is possible to have some wrapper classes and expect Jackson to flatten and extract all of those fields from wrapper classes and map the flat JSON fields to them.

Based on the Details class, Jackson expects having a JSON object like the below one (inner fields are omitted):

{
  "person": {},
  "address": {},
  "children": []
}

So, you have to change the Details class to something like below:

public class Details {
    @JsonProperty("first_name") 
    private String firstName;
        
    @JsonProperty("last_name")
    private String lastName;
        
    @JsonProperty("age")
    private Integer age;

    ...
}

Upvotes: 1

Related Questions