How can I polymorphic deserialization Json String using Java and Jackson Library? -
i've classes a, b, c inherit class baseclass.
i've string json contains json representation of a, b, c or baseclass.
i want have way deserialize string baseclass (polymorphic deserialization). this
baseclass base = objectmapper.readvalue(jsonstring, baseclass.class);
jsonstring
json string representation of of a, b, c, or baseclass.
it's not clear problem original poster having. i'm guessing it's 1 of 2 things:
deserialization problems unbound json elements, because json contains elements there nothing in java bind to; or
want implement polymorphic deserialization.
here's solution first problem.
import static org.codehaus.jackson.map.deserializationconfig.feature.fail_on_unknown_properties; import org.codehaus.jackson.map.objectmapper; public class foo { public static void main(string[] args) throws exception { baseclass base = new baseclass(); a = new a(); b b = new b(); c c = new c(); objectmapper mapper = new objectmapper(); string basejson = mapper.writevalueasstring(base); system.out.println(basejson); // {"basename":"base name"} string ajson = mapper.writevalueasstring(a); system.out.println(ajson); // {"basename":"base name","aname":"a name"} string bjson = mapper.writevalueasstring(b); system.out.println(bjson); // {"basename":"base name","bname":"b name"} string cjson = mapper.writevalueasstring(c); system.out.println(cjson); // {"basename":"base name","cname":"c name"} baseclass basecopy = mapper.readvalue(basejson, baseclass.class); system.out.println(basecopy); // basename: base name // baseclass acopy = mapper.readvalue(ajson, baseclass.class); // throws unrecognizedpropertyexception: // unrecognized field "aname", not marked ignorable // because json contains elements no java field // bind provided. // need let jackson know not json elements must bound. // resolve this, class can annotated // @jsonignoreproperties(ignoreunknown=true) or objectmapper can // directly configured not fail_on_unknown_properties mapper = new objectmapper(); mapper.configure(fail_on_unknown_properties, false); baseclass acopy = mapper.readvalue(ajson, baseclass.class); system.out.println(acopy); // basename: base name baseclass bcopy = mapper.readvalue(bjson, baseclass.class); system.out.println(bcopy); // basename: base name baseclass ccopy = mapper.readvalue(cjson, baseclass.class); system.out.println(ccopy); // basename: base name } } class baseclass { public string basename = "base name"; @override public string tostring() {return "basename: " + basename;} } class extends baseclass { public string aname = "a name"; @override public string tostring() {return super.tostring() + ", aname: " + aname;} } class b extends baseclass { public string bname = "b name"; @override public string tostring() {return super.tostring() + ", bname: " + bname;} } class c extends baseclass { public string cname = "c name"; @override public string tostring() {return super.tostring() + ", cname: " + cname;} }
here's solution second problem.
import org.codehaus.jackson.annotate.jsonsubtypes; import org.codehaus.jackson.annotate.jsonsubtypes.type; import org.codehaus.jackson.annotate.jsontypeinfo; import org.codehaus.jackson.map.objectmapper; public class foo { public static void main(string[] args) throws exception { baseclass base = new baseclass(); a = new a(); b b = new b(); c c = new c(); objectmapper mapper = new objectmapper(); string basejson = mapper.writevalueasstring(base); system.out.println(basejson); // {"type":"baseclass","basename":"base name"} string ajson = mapper.writevalueasstring(a); system.out.println(ajson); // {"type":"a","basename":"base name","aname":"a name"} string bjson = mapper.writevalueasstring(b); system.out.println(bjson); // {"type":"b","basename":"base name","bname":"b name"} string cjson = mapper.writevalueasstring(c); system.out.println(cjson); // {"type":"c","basename":"base name","cname":"c name"} baseclass basecopy = mapper.readvalue(basejson, baseclass.class); system.out.println(basecopy); // basename: base name baseclass acopy = mapper.readvalue(ajson, baseclass.class); system.out.println(acopy); // basename: base name, aname: name baseclass bcopy = mapper.readvalue(bjson, baseclass.class); system.out.println(bcopy); // basename: base name, bname: b name baseclass ccopy = mapper.readvalue(cjson, baseclass.class); system.out.println(ccopy); // basename: base name, cname: c name } } @jsontypeinfo( use = jsontypeinfo.id.name, include = jsontypeinfo.as.property, property = "type") @jsonsubtypes({ @type(value = a.class, name = "a"), @type(value = b.class, name = "b"), @type(value = c.class, name = "c") }) class baseclass { public string basename = "base name"; @override public string tostring() {return "basename: " + basename;} } class extends baseclass { public string aname = "a name"; @override public string tostring() {return super.tostring() + ", aname: " + aname;} } class b extends baseclass { public string bname = "b name"; @override public string tostring() {return super.tostring() + ", bname: " + bname;} } class c extends baseclass { public string cname = "c name"; @override public string tostring() {return super.tostring() + ", cname: " + cname;} }
if instead, goal deserialize subclass type without json element dedicated indicate subclass type is, possible, long in json can used decide subclass type should be. posted example of approach @ http://programmerbruce.blogspot.com/2011/05/deserialize-json-with-jackson-into.html.
Comments
Post a Comment