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

Popular posts from this blog

java - Run spring boot application error: Cannot instantiate interface org.springframework.context.ApplicationListener -

python - pip wont install .WHL files -

Excel VBA "Microsoft Windows Common Controls 6.0 (SP6)" Location Changes -