users@jaxb.java.net

Re: Error marshalling JAXB object

From: swtking <rajkal23_at_yahoo.com>
Date: Tue, 11 Aug 2009 08:34:29 -0700 (PDT)

In order to get different names in the xml used @XmlType on the bean class,
but it did not work.


swtking 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?
>
> 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>
>
>
> 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-tp24852727p24919998.html
Sent from the java.net - jaxb users mailing list archive at Nabble.com.