JAXB封送由XmlAdapter创建的ArrayList

我想使用XmlAdapter调整HashMap字段的XML表示。 我使用ArrayList来做到这一点。 但是,当编组ArrayList根本没有编组。 这是为什么?

代码

 @XmlRootElement public class Foo { private HashMap hashMap; public Foo() { this.hashMap = new HashMap(); } @XmlJavaTypeAdapter(HashMapAdapter.class) public HashMap getHashmap() { return hashMap; } public void setHashmap(HashMap hashMap) { this.hashMap = hashMap; } } 
 public final class HashMapAdapter extends XmlAdapter<ArrayList, HashMap> { @Override public ArrayList marshal(HashMap arg0) throws Exception { ArrayList result = new ArrayList(); for(Entry entry : arg0.entrySet()) result.add(new HashMapEntry(entry.getKey(), entry.getValue())); return result; } @Override public HashMap unmarshal(ArrayList arg0) throws Exception { HashMap result = new HashMap(); for(HashMapEntry entry : arg0) result.put(entry.key, entry.value); return result; } } 
 public class HashMapEntry { @XmlElement public String key; @XmlValue public String value; public HashMapEntry() { } public HashMapEntry(String key, String value) { this.key = key; this.value = value; } } 

结果

  

XmlAdapter您需要将HashMap转换为具有List属性的对象实例,而不是直接转换为ArrayList

HashMapAdapter

 package forum13163430; import java.util.*; import java.util.Map.Entry; import javax.xml.bind.annotation.*; import javax.xml.bind.annotation.adapters.XmlAdapter; public final class HashMapAdapter extends XmlAdapter> { @Override public AdaptedHashMap marshal(HashMap hashMap) throws Exception { AdaptedHashMap adaptedHashMap = new AdaptedHashMap(); for(Entry entry : hashMap.entrySet()) { adaptedHashMap.item.add(new HashMapEntry(entry.getKey(), entry.getValue())); } return adaptedHashMap; } @Override public HashMap unmarshal(AdaptedHashMap adaptedHashMap) throws Exception { HashMap result = new HashMap(); for(HashMapEntry entry : adaptedHashMap.item) result.put(entry.key, entry.value); return result; } public static class AdaptedHashMap { public List item = new ArrayList(); } public static class HashMapEntry { @XmlAttribute public String key; @XmlValue public String value; public HashMapEntry() { } public HashMapEntry(String key, String value) { this.key = key; this.value = value; } } } 

了解更多信息


UPDATE

谢谢,这个工作。 然而,我在生成的XML中获得了额外级别的注释。 有什么办法可以避免吗?

如果您使用EclipseLink MOXy作为JAXB(JSR-222)提供程序,那么您可以在此用例中使用@XmlPath扩展。 我将在下面举例说明。

@XmlJavaTypeAdapter之外的hashmap属性上,我添加了MOXy的@XmlPath注释。 XML路径"." 表示应将子项编组到父XML元素中。

 package forum13163430; import java.util.HashMap; import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; import org.eclipse.persistence.oxm.annotations.XmlPath; @XmlRootElement public class Foo { private HashMap hashMap; public Foo() { this.hashMap = new HashMap(); } @XmlPath(".") @XmlJavaTypeAdapter(HashMapAdapter.class) public HashMap getHashmap() { return hashMap; } public void setHashmap(HashMap hashMap) { this.hashMap = hashMap; } } 

jaxb.properties

要将MOXy指定为JAXB提供程序,您需要在与域模型相同的包中包含一个名为jaxb.properties的文件,并带有以下条目(请参阅: http : //blog.bdoughan.com/2011/05/specifying-eclipselink- moxy-as-your.html )。

 javax.xml.bind.context.factory=org.eclipse.persistence.jaxb.JAXBContextFactory 

演示

由于MOXy是符合JAXB(JSR-222)的实现,因此标准API可用于将对象从/转换为XML。

 package forum13163430; import java.io.File; import javax.xml.bind.*; public class Demo { public static void main(String[] args) throws Exception { JAXBContext jc = JAXBContext.newInstance(Foo.class); Unmarshaller unmarshaller = jc.createUnmarshaller(); File xml = new File("src/forum13163430/input.xml"); Foo foo = (Foo) unmarshaller.unmarshal(xml); Marshaller marshaller = jc.createMarshaller(); marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); marshaller.marshal(foo, System.out); } } 

input.xml中/输出

下面是运行演示代码的输入和输出。

   B C A  

了解更多信息