users@jaxb.java.net

Re: Error marshalling JAXB object

From: Wolfgang Laun <wolfgang.laun_at_gmail.com>
Date: Fri, 14 Aug 2009 17:39:02 +0200

On Tue, Aug 11, 2009 at 2:20 PM, swtking <rajkal23_at_yahoo.com> wrote:

>
> I am able to get the example to work after following your steps. Infact
> there
> was a liittle change.
> @XmlElement( name = "adaptedMap" )
> @XmlJavaTypeAdapter(MyHashMapAdapter.class)
> protected Map<String,ArrayList<String>> valueMapList = null;
>
> public Map<String, ArrayList<String>> getValueMapList() {
> if( valueMapList == null ) valueMapList = new HashMap<String,
> ArrayList<String>>();
> return valueMapList;
> }
>
> I had to put in this way, is there any reason?
>

I guess it depends on the setting of @XmlAccessorType( XmlAccessType.NONE )
of the containing class. Check the javadoc for this annotation.



>
> protected Map<String,ArrayList<String>> valueMapList = null;
>
>
> @XmlElement( name = "adaptedMap" )
> @XmlJavaTypeAdapter(MyHashMapAdapter.class)
>
> public Map<String, ArrayList<String>> getValueMapList() {
> if( valueMapList == null ) valueMapList = new HashMap<String,
> ArrayList<String>>();
> return valueMapList;
> }
>
> One more question: xml produced goes with the variables defined in the
> bean.
> Is there any way I can have different name to be displayed in the xml?
>
> <mapEntry>
> <key>key2</key>
> <listEntry>ela</listEntry>
> <listEntry>elb</listEntry>
> </mapEntry>
>
> something like this
>
> <dept>
> <name>English</name>
> <student>John</student>
> <student>Joseph</student>
> </dept>
>

Look at the @XmlElement annotations. It's the name="<string>" field of this
annotation that controls the XML tag name.

-W



>
>
> swtking wrote:
> >
> > Thank you very much for your detailed explanation. It worked like a
> charm.
> >
> >
> > Wolfgang Laun-2 wrote:
> >>
> >> This is the essential part of the class MyBean containing the Map:
> >>
> >> @XmlElement( name = "adaptedMap" )
> >> @XmlJavaTypeAdapter(MyHashMapAdapter.class)
> >> protected Map<String,ArrayList<String>> valueMapList = null;
> >>
> >> public Map<String, ArrayList<String>> getValueMapList() {
> >> if( valueMapList == null ) valueMapList = new HashMap<String,
> >> ArrayList<String>>();
> >> return valueMapList;
> >> }
> >>
> >> To construct a type (ValueType) that JAXB can handle "out of the box",
> >> imagine the Map as a list of Map.Entry elements, which, in turn, has a
> >> String key and a List<String> value. Write a class representing this
> >> structure:
> >>
> >> @XmlAccessorType( XmlAccessType.NONE )
> >> public class ListKeyListType {
> >> private List<KeyListType> listKeyList;
> >> public ListKeyListType(){
> >> }
> >> @XmlElement( name = "mapEntry" )
> >> public List<KeyListType> getListKeyList() {
> >> if( listKeyList == null ) listKeyList = new
> >> ArrayList<KeyListType>();
> >> return listKeyList;
> >> }
> >>
> >> @XmlAccessorType( XmlAccessType.NONE )
> >> public static class KeyListType {
> >> @XmlElement
> >> private String key;
> >> @XmlElement( name = "listEntry" )
> >> private List<String> list;
> >>
> >> public KeyListType(){
> >> }
> >> // getters, setters...
> >> }
> >> }
> >>
> >> Now the XmlAdapter subclass has to convert values between a
> >> ListKeyListType
> >> and a Map<String,List<String>>. Simply iterate over the list (or the
> map)
> >> and create map (or list) entries.
> >>
> >> public class MyHashMapAdapter
> >> extends XmlAdapter<ListKeyListType, Map<String,List<String>>> {
> >>
> >> @Override
> >> public Map<String,List<String>> unmarshal( ListKeyListType value ) {
> >> Map<String,List<String>> res = new
> >> HashMap<String,List<String>>();
> >> for( ListKeyListType.KeyListType lkl: value.getListKeyList() ){
> >> res.put( lkl.getKey(), lkl.getList() );
> >> }
> >> return res;
> >> }
> >>
> >> @Override
> >> public ListKeyListType marshal( Map<String,List<String>> value ) {
> >> ListKeyListType res = new ListKeyListType();
> >> List<ListKeyListType.KeyListType> lkl = res.getListKeyList();
> >>
> >> for( Map.Entry<String,List<String>> e: value.entrySet() ){
> >> ListKeyListType.KeyListType kl = new
> >> ListKeyListType.KeyListType();
> >> kl.setKey( e.getKey() );
> >> kl.setList( e.getValue() );
> >> lkl.add( kl );
> >> }
> >> return res;
> >> }
> >> }
> >>
> >> I have added names to @XmlElement, so as to have better tags in the
> >> resulting XML, e.g.:
> >>
> >> <myBean>
> >> <adaptedMap>
> >> <mapEntry>
> >> <key>key2</key>
> >> <listEntry>ela</listEntry>
> >> <listEntry>elb</listEntry>
> >> </mapEntry>
> >> <mapEntry>
> >> <key>key1</key>
> >> <listEntry>el1</listEntry>
> >> <listEntry>el2</listEntry>
> >> </mapEntry>
> >> </adaptedMap>
> >> <name>BakedBean</name>
> >> </myBean>
> >>
> >> Variations are possible. You might choose to represent the key as an
> >> attribute, simply by using the @XmlAttribute annotation. You might go
> for
> >> a
> >> totally different representation, e.g., a flat list of <key> and
> >> <listEntry>
> >> elements, where the order determines the grouping into map entries,
> which
> >> would require different code for the ValueType and the XmlAdapter
> >> subclass.
> >> And so on.
> >>
> >> -W
> >>
> >>
> >> On Sat, Aug 8, 2009 at 5:54 AM, swtking <rajkal23_at_yahoo.com> wrote:
> >>
> >>>
> >>> My bad gave wrong example...
> >>>
> >>> Yes I am looking similar to this.. Can you tell me what part of my code
> >>> should be changed in order to achieve this?
> >>>
> >>> <myBean>
> >>> <entry>
> >>> <key>flower</key><valueList>rose lily</valueList>
> >>> </entry>
> >>> <entry>
> >>> <key>fruit</key><valueList>apple orange</valueList>
> >>> </entry>
> >>> </myBean>
> >>>
> >>>
> >>>
> >>> Wolfgang Laun-2 wrote:
> >>> >
> >>> > On Fri, Aug 7, 2009 at 9:23 PM, swtking <rajkal23_at_yahoo.com> wrote:
> >>> >
> >>> >>
> >>> >> Thanks for your response. Made changes to MyHashMapAdapter.java the
> >>> >> format
> >>> >> I
> >>> >> needed but still no luck.
> >>> >>
> >>> >> I am trying to get output in this format.
> >>> >>
> >>> >> <xml>
> >>> >> <abc>
> >>> >> <123></123>
> >>> >> <345></345>
> >>> >> </abc>
> >>> >> <def>
> >>> >> <789></789>
> >>> >> </def>
> >>> >> </xml>
> >>> >>
> >>> >
> >>> > You won't be able to get anywhere close to this, for several reasons:
> >>> > - tags can't start with a digit
> >>> > - values can't be tags
> >>> > - unless you override in XmlElement etc., tags will be derived from
> >>> field
> >>> > names
> >>> >
> >>> > Maybe like this:
> >>> >
> >>> > <myBean>
> >>> > <entry>
> >>> > <key>flower</key><valueList>rose lily</valueList>
> >>> > </entry>
> >>> > <entry>
> >>> > <key>fruit</key><valueList>apple orange</valueList>
> >>> > </entry>
> >>> > </myBean>
> >>> >
> >>> > -W
> >>> >
> >>> >
> >>> >>
> >>> >>
> >>> >> MyBean.java
> >>> >>
> >>> >> private Map<String,List<String>> valueMapList=null;
> >>> >>
> >>> >> @XmlJavaTypeAdapter(MyHashMapAdapter.class)
> >>> >> @XmlElement
> >>> >> public Map<String, List<String>> getValueMapList() {
> >>> >> return valueMapList;
> >>> >> }
> >>> >>
> >>> >> public void setValueMapList(Map<String, List<String>>
> >>> valueMapList)
> >>> >> {
> >>> >> this.valueMapList = valueMapList;
> >>> >> }
> >>> >>
> >>> >>
> >>> >> MyHashMapAdapter.java
> >>> >>
> >>> >> public class MyHashMapAdapter extends
> >>> >> XmlAdapter<HashMap<String,List<String>>, Map<String,List<String>>> {
> >>> >>
> >>> >> @Override
> >>> >> public HashMap<String,List<String>> unmarshal( String[]
> value
> >>> )
> >>> {
> >>> >>
> >>> >> HashMap<String,List<String>> m = new
> HashMap<String,List<String>>();
> >>> >> return m;
> >>> >> }
> >>> >>
> >>> >>
> >>> >> @Override
> >>> >> public String[] marshal(List<String> arg0) throws Exception {
> >>> >> String[] s = (String[]) arg0.toArray();
> >>> >> return s;
> >>> >> }
> >>> >>
> >>> >> }
> >>> >>
> >>> >>
> >>> >>
> >>> >> Wolfgang Laun-2 wrote:
> >>> >> >
> >>> >> > The adapter converts between String[] and List<String> but the
> >>> element
> >>> >> to
> >>> >> > which the adapter is attached to is a Map<?,?>.
> >>> >> >
> >>> >> > You could attach an adapter to MyBean, to convert between its
> field
> >>> >> > valueMapList and whatever. You'll have to design a class that's
> >>> capable
> >>> >> of
> >>> >> > storing the same information as MyBean but can be handled by JAXB
> >>> and
> >>> >> is
> >>> >> > structured according to the XML structure you want.
> >>> >> >
> >>> >> > -W
> >>> >> >
> >>> >> >
> >>> >> > On Thu, Aug 6, 2009 at 9:16 PM, swtking <rajkal23_at_yahoo.com>
> wrote:
> >>> >> >
> >>> >> >>
> >>> >> >> Could anyone tell me what I am doing wrong.
> >>> >> >>
> >>> >> >> Trying to marshall a complex map (Map<String,List<String>>)
> >>> >> >>
> >>> >> >> MyBean.java
> >>> >> >>
> >>> >> >> private Map<String,List<String>> valueMapList=null;
> >>> >> >>
> >>> >> >> @XmlJavaTypeAdapter(MyHashMapAdapter.class)
> >>> >> >> @XmlElement
> >>> >> >> public Map<String, List<String>> getValueMapList() {
> >>> >> >> return valueMapList;
> >>> >> >> }
> >>> >> >>
> >>> >> >> public void setValueMapList(Map<String, List<String>>
> >>> >> >> valueMapList)
> >>> >> >> {
> >>> >> >> this.valueMapList = valueMapList;
> >>> >> >> }
> >>> >> >>
> >>> >> >>
> >>> >> >> MyHashMapAdapter.java
> >>> >> >>
> >>> >> >> public class MyHashMapAdapter extends XmlAdapter<String[],
> >>> >> List<String>>
> >>> >> >> {
> >>> >> >>
> >>> >> >> public List<String> unmarshal( String[] value ) {
> >>> >> >> List<String> r = new ArrayList<String>();
> >>> >> >> for( String s : value )
> >>> >> >> r.add(s);
> >>> >> >> return r;
> >>> >> >> }
> >>> >> >>
> >>> >> >> public String[] unmarshal( List<String> value ) {
> >>> >> >> return value.toArray(new
> String[value.size()]);
> >>> >> >> }
> >>> >> >>
> >>> >> >> @Override
> >>> >> >> public String[] marshal(List<String> arg0) throws
> Exception
> >>> {
> >>> >> >> String[] s = (String[]) arg0.toArray();
> >>> >> >> return s;
> >>> >> >> }
> >>> >> >>
> >>> >> >> }
> >>> >> >>
> >>> >> >>
> >>> >> >> This is my error
> >>> >> >>
> >>> >> >> java.io.IOException: Error marshalling JAXB object of type "class
> >>> >> >> com.MyBean".
> >>> >> >> at
> >>> >> >>
> >>> >> >>
> >>> >>
> >>>
> com.sun.jersey.core.provider.jaxb.AbstractRootElementProvider.writeTo(AbstractRootElementProvider.java:145)
> >>> >> >> at
> >>> >> >>
> >>> >> >>
> >>> >>
> >>>
> com.sun.jersey.spi.container.ContainerResponse.write(ContainerResponse.java:254)
> >>> >> >> at
> >>> >> >>
> >>> >> >>
> >>> >>
> >>>
> com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:578)
> >>> >> >> at
> >>> >> >>
> >>> >> >>
> >>> >>
> >>>
> com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:502)
> >>> >> >> at
> >>> >> >>
> >>> >> >>
> >>> >>
> >>>
> com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:493)
> >>> >> >> Truncated. see log file for complete stacktrace
> >>> >> >> com.sun.xml.bind.v2.runtime.IllegalAnnotationsException: 3 counts
> >>> of
> >>> >> >> IllegalAnnotationExceptions
> >>> >> >> Adapter com.MyHashMapAdapter is not applicable to the field type
> >>> >> >> java.util.Map<java.lang.String,
> java.util.List<java.lang.String>>.
> >>> >> >> this problem is related to the following location:
> >>> >> >> at
> >>> >> >> @javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter(type=class
> >>> >> >> javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter$DEFAULT,
> >>> >> >> value=class
> >>> >> >> com.MyHashMapAdapter)
> >>> >> >> at public java.util.Map
> >>> com.MyBean.getValueMapList()
> >>> >> >> at com.MyBean
> >>> >> >> java.util.Map is an interface, and JAXB can't handle interfaces.
> >>> >> >> this problem is related to the following location:
> >>> >> >> at java.util.Map
> >>> >> >> at public java.util.Map
> >>> com.MyBean.getValueMapList()
> >>> >> >> at com.MyBean
> >>> >> >> java.util.Map does not have a no-arg default constructor.
> >>> >> >> this problem is related to the following location:
> >>> >> >> at java.util.Map
> >>> >> >> at public java.util.Map
> >>> com.MyBean.getValueMapList()
> >>> >> >> at com.MyBean
> >>> >> >>
> >>> >> >> at
> >>> >> >>
> >>> >> >>
> >>> >>
> >>>
> com.sun.xml.bind.v2.runtime.IllegalAnnotationsException$Builder.check(IllegalAnnotationsException.java:102)
> >>> >> >> at
> >>> >> >>
> >>> >> >>
> >>> >>
> >>>
> com.sun.xml.bind.v2.runtime.JAXBContextImpl.getTypeInfoSet(JAXBContextImpl.java:447)
> >>> >> >> at
> >>> >> >>
> >>> >> >>
> >>> >>
> >>>
> com.sun.xml.bind.v2.runtime.JAXBContextImpl.<init>(JAXBContextImpl.java:288)
> >>> >> >> at
> >>> >> >>
> >>> >> >>
> >>> >>
> >>>
> com.sun.xml.bind.v2.runtime.JAXBContextImpl$JAXBContextBuilder.build(JAXBContextImpl.java:1111)
> >>> >> >> at
> >>> >> >>
> >>> >>
> >>>
> com.sun.xml.bind.v2.ContextFactory.createContext(ContextFactory.java:154)
> >>> >> >> Truncated. see log file for complete stacktrace
> >>> >> >>
> >>> >> >>
> >>> >> >> --
> >>> >> >> View this message in context:
> >>> >> >>
> >>> >>
> >>>
> http://www.nabble.com/Error-marshalling-JAXB-object-tp24852727p24852727.html
> >>> >> >> Sent from the java.net - jaxb users mailing list archive at
> >>> >> Nabble.com.
> >>> >> >>
> >>> >> >>
> >>> >> >>
> >>> ---------------------------------------------------------------------
> >>> >> >> To unsubscribe, e-mail: users-unsubscribe_at_jaxb.dev.java.net
> >>> >> >> For additional commands, e-mail: users-help_at_jaxb.dev.java.net
> >>> >> >>
> >>> >> >>
> >>> >> >
> >>> >> >
> >>> >>
> >>> >> --
> >>> >> View this message in context:
> >>> >>
> >>>
> http://www.nabble.com/Error-marshalling-JAXB-object-tp24852727p24870320.html
> >>> >> Sent from the java.net - jaxb users mailing list archive at
> >>> Nabble.com.
> >>> >>
> >>> >>
> >>> >>
> ---------------------------------------------------------------------
> >>> >> To unsubscribe, e-mail: users-unsubscribe_at_jaxb.dev.java.net
> >>> >> For additional commands, e-mail: users-help_at_jaxb.dev.java.net
> >>> >>
> >>> >>
> >>> >
> >>> >
> >>>
> >>> --
> >>> View this message in context:
> >>>
> http://www.nabble.com/Error-marshalling-JAXB-object-tp24852727p24874694.html
> >>> Sent from the java.net - jaxb users mailing list archive at
> Nabble.com.
> >>>
> >>>
> >>> ---------------------------------------------------------------------
> >>> To unsubscribe, e-mail: users-unsubscribe_at_jaxb.dev.java.net
> >>> For additional commands, e-mail: users-help_at_jaxb.dev.java.net
> >>>
> >>>
> >>
> >>
> >
> >
>
> --
> View this message in context:
> http://www.nabble.com/Error-marshalling-JAXB-object-tp24852727p24916543.html
> Sent from the java.net - jaxb users mailing list archive at Nabble.com.
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe_at_jaxb.dev.java.net
> For additional commands, e-mail: users-help_at_jaxb.dev.java.net
>
>