java - Custom deserialization with Gson -
i've been trying improve code on don't know how, json this:
{ "name": "jhon", "lastname": "smith", "clothes": { "gender":"male", "shirt": { "id": 113608, "name": "green shirt", "size": "large" }, "pants": { "id": 115801, "name": "black leather pants", "size": "large" } } } the way works far having both shirt , pants classes identical im trying use 1 class both of them.i have no in how json generated have work comes.
this classes:
class person
public class person{ private string lastname; private string name; private clothes clothes; } class clothes
public class clothes{ private shirt shirt; private pants pants; private string gender; } class shirt
public class shirt{ private string id; private string name; private string size; } pants same shirt, thing don't want code break if/when decide add piece of clothing i'm trying this
class clothes
public class clothes{ private list<something> clothlist; private string gender; }
instead of using 2 separate classes (shirt , pants) use 1 class - let's cloth. tried , worked fine:
person class:
package com.dominikangerer.q29550820; public class person { private string name; private string lastname; private clothes clothes; } clothes class:
package com.dominikangerer.q29550820; public class clothes { private string gender; private cloth shirt; private cloth pants; } cloth class:
package com.dominikangerer.q29550820; public class cloth { private integer id; private string name; private string size; } after building these classes tried directly in little main class results in fine deserialized.
gson g = new gson(); person person = g.fromjson("{\"name\":\"jhon\",\"lastname\":\"smith\",\"clothes\":{\"gender\":\"male\",\"shirt\":{\"id\":113608,\"name\":\"green shirt\",\"size\":\"large\"},\"pants\":{\"id\":115801,\"name\":\"black leather pants\",\"size\":\"large\"}}}", person.class); didn't use @expose here or @serializedname("something") because wasn't needed.
hope helps out - otherwise please explain problem in more detail , try you.
----------- update ------------
okay it's quite easy cast json have there in normal object - thing inside map (clothes) have normal string value. purpose suggest enable gson functionality @expose tell why idea later.
let's start: removed clothes class map<string, object> gson can deserialize - problem here have gender inside map. modified person class works this:
person v2:
package com.dominikangerer.q29550820; public class person { private string name; private string lastname; @serializedname("clothes") private map<string, object> clotheswrapper; public string getgender() { return clotheswrapper.get("gender").tostring(); } public void setgender(string gender) { this.clotheswrapper.put("gender", gender); } } now can map gender string , modify getter , setter - still have map there contains objects. next thing don't want map<string, object> - deserializing , serialization it's totally fine - working cloths - it's stupid let's rid of easiest way:
we modify our person class this:
person v3:
package com.dominikangerer.q29550820; public class person { @expose private string name; @expose private string lastname; @expose @serializedname("clothes") private map<string, object> clotheswrapper; private map<string, cloth> clothes; public string getgender() { return clotheswrapper.get("gender").tostring(); } public void setgender(string gender) { this.clotheswrapper.put("gender", gender); } public map<string, cloth> getclothes() { if (clothes == null) { gson g = new gson(); clothes = new hashmap<string, cloth>(); (entry<string, object> entry : clotheswrapper.entryset()) { if (entry.getkey().equals("gender")) { continue; } string helper = g.tojson(entry.getvalue()); cloth cloth = g.fromjson(helper, cloth.class); clothes.put(entry.getkey(), cloth); } } return clothes; } } as can see indirectly cast clothes - have because it's easiest way linkedtreemap cloth-object without running classcastexception. can see have map<string,object> clotheswrapper let gson parse object (can't find better name - sorry) , map<string, cloth> clothes map without expose. need setup gson enableexpose option works this:
(using person v3 class here - debug - works charm)
public class main { public static void main(string[] args) { gson g = new gsonbuilder().excludefieldswithoutexposeannotation().create(); person person = g.fromjson("{\"name\":\"jhon\",\"lastname\":\"smith\",\"clothes\":{\"gender\":\"male\",\"shirt\":{\"id\":113608,\"name\":\"green shirt\",\"size\":\"large\"},\"pants\":{\"id\":115801,\"name\":\"black leather pants\",\"size\":\"large\"}}}", person.class); system.out.println(person.getclothes()); system.out.println(person.getgender()); } } you can find classes in github repository