I'm trying to marshal this class:
package otherTest;
import java.util.Collection;
import java.util.List;
import java.util.Map;
public class SearchResult {
private List<Map<String,String>> listOfMap;
private Map<String,Collection<String>> mapWithList;
public List<Map<String, String>> getListOfMap() {
return listOfMap;
}
public void setListOfMap(List<Map<String, String>> listOfMap) {
this.listOfMap = listOfMap;
}
public Map<String, Collection<String>> getMapWithList() {
return mapWithList;
}
public void setMapWithList(Map<String, Collection<String>> mapWithList) {
this.mapWithList = mapWithList;
}
public SearchResult(){}
}
oxm.xml
<?xml version="1.0"?>
<xml-bindings
xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/oxm"
package-name="otherTest"
xml-mapping-metadata-complete="true">
<java-types>
<java-type name="SearchResult">
<xml-root-element/>
<java-attributes>
<xml-element java-attribute="listOfMap"/>
<xml-element java-attribute="mapWithList"/>
</java-attributes>
</java-type>
</java-types>
</xml-bindings>
Demo.java
package otherTest;
import java.io.InputStream;
import java.util.*;
import javax.xml.bind.*;
import org.eclipse.persistence.jaxb.JAXBContextProperties;
public class Demo {
public static void main(String[] args) throws Exception {
Map<String, Object> properties = new HashMap<String , Object>();
ClassLoader classLoader = Demo.class.getClassLoader();
InputStream modelStream = classLoader.getResourceAsStream("otherTest/oxm.xml");
properties.put(JAXBContextProperties.OXM_METADATA_SOURCE, modelStream);
JAXBContext jc = JAXBContext.newInstance(new Class[] {SearchResult.class}, properties);
List<Map<String,String>> results = new ArrayList<Map<String,String>>();
Map<String,String> test = new HashMap<String,String>();
Map<String,Collection<String>> daMashalare = new HashMap<String,Collection<String>>();
test.put("id","10");
test.put("publicationTitle","20");
test.put("paginazione","boh");
test.put("pageSize", "10");
results.add(test);
Collection<String> listaString = new ArrayList<String>();
listaString.add("testlist");
daMashalare.put("nothing",listaString);
SearchResult result = new SearchResult();
result.setListOfMap(results);
result.setMapWithList(daMashalare);
Marshaller marshaller = jc.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
marshaller.marshal(result, System.out);
}
}
Unluckly the output that I get is:
<?xml version="1.0" encoding="UTF-8"?>
<searchResult>
<listOfMap>{id=10, paginazione=boh, pageSize=10, publicationTitle=20}</listOfMap>
<mapWithList>
<entry>
<key>nothing</key>
<value>testlist</value>
</entry>
</mapWithList>
</searchResult>
So As you can see the listOfMap attribute is not how I would like to see it
<?xml version="1.0" encoding="UTF-8"?>
<searchResult>
<listOfMap>
<id>10</id>
<paginazione>boh</paginazione>
<pageSize>10</pageSize>
<publicationTitle>20</publicationTitle>
</listOfMap>
<mapWithList>
<entry>
<key>nothing</key>
<value>testlist</value>
</entry>
</mapWithList>
</searchResult>
How Can I set an adapter to solve this problem? I have also included this test package: that you can download and test it http://bit.ly/14aWIu1
Thank you
This is a generic solution for Map:
MapAdapter<K,V>
package otherTest;
import java.util.HashMap;
import java.util.Map;
import javax.xml.bind.annotation.adapters.XmlAdapter;
public class MapAdapter<K, V> extends XmlAdapter<MapType<K, V>, Map<K, V>> {
@Override
public Map<K, V> unmarshal(MapType<K, V> v) throws Exception {
HashMap<K, V> map = new HashMap<K, V>();
for (MapEntryType<K, V> mapEntryType : v.getEntry()) {
map.put(mapEntryType.getKey(), mapEntryType.getValue());
}
return map;
}
@Override
public MapType marshal(Map<K, V> v) throws Exception {
MapType<K, V> mapType = new MapType<K, V>();
for (Map.Entry<K, V> entry : v.entrySet()) {
MapEntryType<K, V> mapEntryType = new MapEntryType<K, V>();
mapEntryType.setKey(entry.getKey());
mapEntryType.setValue(entry.getValue());
mapType.getEntry().add(mapEntryType);
}
return mapType;
}
}
MapEntryType<K,V>
package otherTest;
import java.util.Map;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
@XmlAccessorType(XmlAccessType.PROPERTY)
public class MapEntryType<K, V> {
private K key;
private V value;
public MapEntryType() {
}
public MapEntryType(Map.Entry<K, V> e) {
key = e.getKey();
value = e.getValue();
}
@XmlElement
public K getKey() {
return key;
}
public void setKey(K key) {
this.key = key;
}
@XmlElement
public V getValue() {
return value;
}
public void setValue(V value) {
this.value = value;
}
}
MapType<K,V>
package otherTest;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public class MapType<K, V> {
private List<MapEntryType<K, V>> entry = new ArrayList<MapEntryType<K, V>>();
public MapType() {
}
public MapType(Map<K, V> map) {
for (Map.Entry<K, V> e : map.entrySet()) {
entry.add(new MapEntryType<K, V>(e));
}
}
public List<MapEntryType<K, V>> getEntry() {
return entry;
}
public void setEntry(List<MapEntryType<K, V>> entry) {
this.entry = entry;
}
}
SearchResult
package otherTest;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
public class SearchResult {
private List<Map<String,String>> listOfMap;
private Map<String,Collection<String>> mapWithList;
@XmlJavaTypeAdapter(MapAdapter.class)
public List<Map<String, String>> getListOfMap() {
return listOfMap;
}
public void setListOfMap(List<Map<String, String>> listOfMap) {
this.listOfMap = listOfMap;
}
public Map<String, Collection<String>> getMapWithList() {
return mapWithList;
}
public void setMapWithList(Map<String, Collection<String>> mapWithList) {
this.mapWithList = mapWithList;
}
public SearchResult(){}
}
Test
package otherTest;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.xml.transform.TransformerException;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import org.eclipse.persistence.jaxb.JAXBContextProperties;
public class Test {
public static void main(String[] args) throws TransformerException, Exception {
Map<String, Object> properties = new HashMap<String, Object>();
Marshaller marshaller = null;
ClassLoader classLoader = Test.class.getClassLoader();
List<Map<String,String>> results = new ArrayList<Map<String,String>>();
Map<String,String> test = new HashMap<String,String>();
test.put("id","10");
test.put("publicationTitle","20");
test.put("paginazione","boh");
test.put("pageSize", "10");
results.add(test);
InputStream modelStream = classLoader.getResourceAsStream("test/oxm.xml");
JAXBContext ctx = null;
properties.put(JAXBContextProperties.OXM_METADATA_SOURCE, modelStream );
try {
ctx = JAXBContext.newInstance(new Class[] {SearchResult.class}, properties);
} catch (JAXBException e) {
e.printStackTrace();
}
marshaller = ctx.createMarshaller();
marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
SearchResult result = new SearchResult();
result.setListOfMap(results);
marshaller.marshal(result, System.out);
}
}
Output
<?xml version="1.0" encoding="UTF-8"?>
<listOfMap>
<entry>
<key xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xsd:string">id</key>
<value xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xsd:string">10</value>
</entry>
<entry>
<key xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xsd:string">paginazione</key>
<value xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xsd:string">boh</value>
</entry>
<entry>
<key xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xsd:string">pageSize</key>
<value xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xsd:string">10</value>
</entry>
<entry>
<key xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xsd:string">publicationTitle</key>
<value xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:type="xsd:string">20</value>
</entry>
</listOfMap>