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
了解更多信息