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