Search code examples
javajsonjacksonpojo

How to write Java class to fetch the object from Json which doesn't have fixed fields?


I need to have Java class to accommodate below requirement and it should be compatible for Jackson's parsing using Object Mapper.

The Json is in below format :

[
 { 
   "name" : "Snehal",
   "property1" : "value11",
   "property2" : "value12",
   "property3" : "value13",

 },
 {
   "name" : "Masne",
   "property1" : "value21",
   "property2" : "value22",
   "property3" : "value23",

},
]

In above Json, the no. of properties are not fixed, meaning there can be, say, property4, 5, 6, etc

The corresponding Java class could be thought of as below :

Class MyClass
{

  String name;

  List<String> properties;

 // getters, setters, etc

}

But this wont solve the purpose since, in this case, Json will generated something like of below format:

[ 
 {
   "name" : "Snehal",
   [
      {"property" : "value1" },
      {"property" : "value1" },
      {"property" : "value1" }
   ]
 },

 {
   .... []
 }

]

How do I implement the Java class to achieve the data in specifeid Json format ?


Solution

  • You can use @JsonAnyGetter/@JsonAnySetter annotations to mark that your class has 'extra' properties in addition to the declared fields.

    Here is an example:

    public class JacksonAnyGetter {
    
        static final String JSON = " { \n" +
                "   \"name\" : \"Snehal\",\n" +
                "   \"property1\" : \"value11\",\n" +
                "   \"property2\" : \"value12\",\n" +
                "   \"property3\" : \"value13\"\n" +
                "\n" +
                " }";
    
        static class Bean {
            public String name; // we always have name
            private Map<String, Object> properties = new HashMap<>();
    
            @JsonAnySetter
            public void add(String key, String value) {
                properties.put(key, value);
            }
    
            @JsonAnyGetter
            public Map<String, Object> getProperties() {
                return properties;
            }
    
            @Override
            public String toString() {
                return "Bean{" +
                        "name='" + name + '\'' +
                        ", properties=" + properties +
                        '}';
            }
        }
    
        public static void main(String[] args) throws IOException {
            final ObjectMapper mapper = new ObjectMapper();
            final Bean bean = mapper.readValue(JSON, Bean.class);
            System.out.println(bean);
            final String json = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(bean);
            System.out.println(json);
        }
    }
    

    Output:

    Bean{name='Snehal', properties={property3=value13, property2=value12, property1=value11}}
    {
      "name" : "Snehal",
      "property3" : "value13",
      "property2" : "value12",
      "property1" : "value11"
    }