How can i deserialize Json string where object's field's subclass is included in json string, using Java and Jackson library -


i new java. have classes site, instances, cloudinstance. class site has attribute instances , class cloudinstance inherits class instance. follows-

  public class site extends baseentity {       private string sitename;       list<instance> instances = lists.newarraylist();   }    public class instance extends baseentity {     private string instanceid;     private string name;   }    public class cloudinstance extends instance {     private string availabilityzone;     private string instancetype   } 

i deserializing json string follows -

  import com.fasterxml.jackson.databind.objectmapper;    objectmapper mapper = new objectmapper();    baseentity obj = null;   obj = (baseentity) mapper.readvalue(jsonstr, site.class); 

it works fine if jsonstr not contain fields of class 'cloudinstance' , contains field instance instance class's fields.

problem - want deserialize jsonstr includes 'cloudinstance' classe's fiels part of 'instances' field of class 'site'. ex jsonstr follows -

  {         "id": null,         "sitename": "demo",         "instances": [             {                 "instanceid": "i-8c2ee5fc",                 "name": "some-node",                 "availabilityzone": "some-zone",                 "instancetype": "t1.micro"               }]    } 

for above jsonstr following error

  error: unrecognized field \"availabilityzone\" , error: unrecognized field \"instancetype\" 

with lots of if else , dirty code can obj of site including above fields. want implement clean solution this. there library can this? id valuable. please help..!!

thanks in advance.

what trying achieve called polymorphic deserialization. example fails because jackson needs know instance type should constructed json , placed list of instances. please refer this wiki page detailed explanation.

i have modified example demonstrate how work. i've added instance type information in @type field in json representation. i've made classes immutable using constructors annotated the @jsoncreator annotation create instances.

public class jacksonpolymorphism {      public static class baseentity {         private final string id;          protected baseentity(string id) {             this.id = id;         }     }      public static class site extends baseentity {         private final string sitename;         private final list<instance> instances;          @jsoncreator         public site(@jsonproperty("id") string id,                     @jsonproperty("sitename") string sitename,                     @jsonproperty("instances") list<instance> instances) {             super(id);             this.sitename = sitename;             this.instances = instances;         }          @override         public string tostring() {             return "site{" +                     "sitename='" + sitename + '\'' +                     ", instances=" + instances +                     '}';         }     }      @jsontypeinfo(use = jsontypeinfo.id.name,             include = jsontypeinfo.as.property,             property = "@type")     @jsontypename(value = "simple")     public static class instance extends baseentity {         private final string name;          @jsoncreator         public instance(@jsonproperty("instanceid") string id,                         @jsonproperty("name") string name) {             super(id);             this.name = name;         }          @override         public string tostring() {             return "instance{" +                     "name='" + name + '\'' +                     '}';         }     }      @jsontypename("cloud")     public static class cloudinstance extends instance {         private final string availabilityzone;         private final string instancetype;           public cloudinstance(@jsonproperty("instanceid") string id,                              @jsonproperty("name") string name,                              @jsonproperty("availabilityzone") string availabilityzone,                              @jsonproperty("instancetype") string instancetype) {             super(id, name);             this.availabilityzone = availabilityzone;             this.instancetype = instancetype;         }          @override         public string tostring() {             return "cloudinstance{" +                     "availabilityzone='" + availabilityzone + '\'' +                     ", instancetype='" + instancetype + '\'' +                     '}';         }     }      public static final string json = "{\n" +             "        \"id\": null,\n" +             "        \"sitename\": \"demo\",\n" +             "        \"instances\": [\n" +             "            {\n" +             "                \"@type\": \"cloud\",\n" +             "                \"instanceid\": \"i-8c2ee5fc\",\n" +             "                \"name\": \"some-node\",\n" +             "                \"availabilityzone\": \"some-zone\",\n" +             "                \"instancetype\": \"t1.micro\"  \n" +             "            }," +             "            {\n" +             "                \"@type\": \"simple\",\n" +             "                \"instanceid\": \"abc\",\n" +             "                \"name\": \"fgf\"\n" +             "            }]" +             "   }";     public static void main(string[] args) throws ioexception {         objectmapper mapper = new objectmapper();         mapper.registersubtypes(cloudinstance.class);         system.out.println(mapper.readvalue(json, site.class));     }  } 

output:

site{sitename='demo', instances=[cloudinstance{availabilityzone='some-zone', instancetype='t1.micro'}, instance{name='fgf'}]} 

Comments

Popular posts from this blog

database - VFP Grid + SQL server 2008 - grid not showing correctly -

jquery - Set jPicker field to empty value -

.htaccess - htaccess convert request to clean url and add slash at the end of the url -