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 object
s. next thing don't want map<string, object>
- deserializing , serialization it's totally fine - working cloth
s - 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 cloth
es - 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