users@jaxb.java.net

Re: Error marshalling JAXB object

From: swtking <rajkal23_at_yahoo.com>
Date: Mon, 10 Aug 2009 08:31:34 -0700 (PDT)

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