java - Determine subclass when unmarshalling with JAXB -
i try provide sscce of problem.
i have hierarchy of classes:
class base:
@xmlrootelement @xmlseealso({ a.class, b.class }) @xmlaccessortype(xmlaccesstype.field) public class base { @xmlattribute private string basedata; public string getbasedata() { return basedata; } public void setbasedata(string basedata) { this.basedata = basedata; } } class extends base
@xmlaccessortype(xmlaccesstype.field) @xmltype(name="a", proporder = { "dataa1", "dataa2" }) @xmlrootelement(name = "base", namespace = "") public class extends base { private string dataa1; private string dataa2; public string getdataa1() { return dataa1; } public void setdataa1(string dataa1) { this.dataa1 = dataa1; } public string getdataa2() { return dataa2; } public void setdataa2(string dataa2) { this.dataa2 = dataa2; } } class b extends base
@xmlaccessortype(xmlaccesstype.field) @xmltype(name="b", proporder = { "datab1", "datab2" }) @xmlrootelement(name = "base", namespace = "") public class b extends base { private string datab1; private string datab2; public string getdatab1() { return datab1; } public void setdatab1(string datab1) { this.datab1 = datab1; } public string getdatab2() { return datab2; } public void setdatab2(string datab2) { this.datab2 = datab2; } } but when try test it:
public class test { public static void main(string[] args) throws exception { base base = new a(); base.setbasedata("basedataa"); ((a) base).setdataa1("dataa1"); ((a) base).setdataa2("dataa2"); jaxbcontext jc = jaxbcontext.newinstance(base.class, a.class, b.class); // marshal object marshaller marshaller = jc.createmarshaller(); marshaller.setproperty(marshaller.jaxb_formatted_output, true); stringwriter sw = new stringwriter(); marshaller.marshal(base, sw); // unmarshal object unmarshaller unmarshaller = jc.createunmarshaller(); string generatedxml = sw.tostring(); system.out.println(generatedxml); base objectfromunmarshall = (base) unmarshaller.unmarshal(new stringreader(generatedxml)); system.out.println(objectfromunmarshall); // re-marshal object system.out.println(""); sw = new stringwriter(); marshaller.marshal(objectfromunmarshall, sw); system.out.println(sw.tostring()); } } this output:
<?xml version="1.0" encoding="utf-8" standalone="yes"?> <base basedata="basedataa"> <dataa1>dataa1</dataa1> <dataa2>dataa2</dataa2> </base> jaxb.b@5c0369c4 <?xml version="1.0" encoding="utf-8" standalone="yes"?> <base basedata="basedataa"/> i marchal object a, when unmarshalling creates instance of b!
why? how can tell him unmarshalh instance?
note: using sun jaxb implementation , cannot change it.
well, way have found handle use xmladapter (based in this great article).
public class baseadapter extends xmladapter<baseadapter.basehandler,base>{ @override public base unmarshal(basehandler basehandler) throws exception { if (null == basehandler) { return null; } if (null != basehandler.dataa1) { a = new a(); a.setdataa1(basehandler.dataa1); a.setdataa2(basehandler.dataa2); return a; } else { b b = new b(); b.setdatab1(basehandler.datab1); b.setdatab2(basehandler.datab2); return b; } } @override public basehandler marshal(base base) throws exception { if (null == base) { return null; } basehandler basehandler = new basehandler(); if (base instanceof a) { a = (a) base; basehandler.dataa1 = a.getdataa1(); basehandler.dataa2 = a.getdataa2(); } else { b b = (b) base; basehandler.datab1 = b.getdatab1(); basehandler.datab2 = b.getdatab2(); } return basehandler; } public static class basehandler { public string dataa1; public string dataa2; public string datab1; public string datab2; } } here complete sscce code if interested.
Comments
Post a Comment