java - How to make JAXB call the setter AFTER adding Elements to an List? -
i have data in xml-file want unmarshal jaxb myhashmap. myobject has string name, key in hashmap.
to prevent writing key/name information twice xml-file (once name of myobject , once key of myhashmap), added setter , getter arraylist, add/read data into/out of myhashmap.
@xmlrootelement public class myhashmap extends hashmap<string, myobject> implements serializable { public myhashmap() { super(); } @xmlelement(name = "myobject") public void setmyobjectsarraylist(arraylist<myobject> myobjectlist) { (myobject myobject : myobjectlist) { this.put(myobject.getname(), myobject); } } public arraylist<myobject> getmyobjectsarraylist() { if (this.isempty()) { // added setter called return null; } arraylist<myobject> myobjectlist = new arraylist<myobject>(); myobjectlist.addall(this.values()); return myobjectlist; } }
it worked fine in java 7 (according andswer of this because of bug ), doesnt in java 8. in java 8 jaxb gets listobject , adds elemts instead of using setter.
so added "return null" if list empty. apparently jaxb sets empty list , adds elements afterwards not work code. there possibility tell jaxb add elements list , call setter then?
you can use map jaxb marshal , unmarshal it. (cf. https://jaxb.java.net/tutorial/section_6_2_1-a-survey-of-jaxb-annotations.html) avoid repetition of name, annotate @xmltransient
in myobject.
another approach use adapter; you'd have wrap map parent element. see https://jaxb.java.net/tutorial/section_6_2_9-type-adapters-xmljavatypeadapter.html
yet possibility use simpler approach different implementation of root element class. let use myhashmap map , avoids dirty tricks, although accessors little more inconvenient call. of course, may implement map , clean and convenient, that's more code write.
@xmlrootelement public class myhashmap { private boolean dirty = false; private map<string,myobject> str2obj; private list<myobject> myobjects = new arraylist<>(); @xmlelement(name = "myobject") list<myobject> getmyobjects(){ dirty = true; return myobjects(); } // variant 1: expose str2obj @xmltransient public map<string,myobject> getstr2obj(){ if( dirty ) rebuild(); return str2obj; } private void rebuild(){ str2obj.clear(); for( myobject myobject: myobjects ){ str2obj.put(mmyobject.getname(), myobject ); } dirty = false; } // variant 2: delegate put, get, , other methods // use same approach }
Comments
Post a Comment