AXB是很强大的XML <—> Java Class映射工具。很可惜它默认不支持对Hashmap的映射。但我们可以通过使用XmlJavaTypeAdapter来扩展实现,本文介绍详细方法。
首先创建一个带有 HashMap
的 Class
:
01 | package org.bluedash.demo; |
02 |
03 | import java.util.HashMap; |
04 |
05 | import javax.xml.bind.annotation.XmlAccessType; |
06 | import javax.xml.bind.annotation.XmlAccessorType; |
07 | import javax.xml.bind.annotation.XmlRootElement; |
08 | import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; |
09 |
10 | @XmlRootElement |
11 | @XmlAccessorType (XmlAccessType.FIELD) |
12 | public class Foo { |
13 |
14 | @XmlJavaTypeAdapter (MyHashMapAdapter. class ) |
15 | HashMap hashmap; |
16 |
17 | public Foo() { |
18 | hashmap = new HashMap(); |
19 | } |
20 |
21 | public HashMap getHashmap() { |
22 | return hashmap; |
23 | } |
24 |
25 | public void setHashmap(HashMap hashmap) { |
26 | this .hashmap = hashmap; |
27 | } |
28 |
29 | } |
我们使用自己的 MyHashMapAdapter.class
来映射 HashMap
:
01 | package org.bluedash.demo; |
02 |
03 | import java.util.HashMap; |
04 | import java.util.List; |
05 | import java.util.Set; |
06 | import java.util.Map.Entry; |
07 |
08 | import javax.xml.bind.annotation.adapters.XmlAdapter; |
09 |
10 | public final class MyHashMapAdapter extends XmlAdapter<MyHashMapType, HashMap> { |
11 |
12 | @Override |
13 | public MyHashMapType marshal(HashMap arg0) throws Exception { |
14 | MyHashMapType myHashMapType = new MyHashMapType(); |
15 | for (Entry entry : (Set<Entry>) arg0.entrySet()) { |
16 | MyHashEntryType myHashEntryType = new MyHashEntryType(); |
17 | myHashEntryType.key = (Integer) entry.getKey(); |
18 | myHashEntryType.value = (String) entry.getValue(); |
19 | myHashMapType.entries.add(myHashEntryType); |
20 | // myHashMapType = myHashEntryType; |
21 | } |
22 | return myHashMapType; |
23 | } |
24 |
25 | @Override |
26 | public HashMap unmarshal(MyHashMapType arg0) throws Exception { |
27 | HashMap hashMap = new HashMap(); |
28 | for (MyHashEntryType myHashEntryType : (List<MyHashEntryType>) arg0.entries) { |
29 | hashMap.put(myHashEntryType.key, myHashEntryType.value); |
30 | } |
31 | return hashMap; |
32 | } |
33 |
34 | } |
里面使用了自定义的 MyHashMapType
:
01 | package org.bluedash.demo; |
02 |
03 | import java.util.ArrayList; |
04 | import java.util.List; |
05 |
06 | import javax.xml.bind.annotation.XmlElement; |
07 | import javax.xml.bind.annotation.XmlRootElement; |
08 |
09 | @XmlRootElement |
10 | public class MyHashMapType { |
11 |
12 | @XmlElement (required = true ) |
13 | public List<MyHashEntryType> entries = new ArrayList<MyHashEntryType>(); |
14 | } |
使用 MyHashEntryType
来实现对 HashMap
每一条数据的映射:
01 | package org.bluedash.demo; |
02 |
03 | import javax.xml.bind.annotation.XmlAccessType; |
04 | import javax.xml.bind.annotation.XmlAccessorType; |
05 | import javax.xml.bind.annotation.XmlAttribute; |
06 | import javax.xml.bind.annotation.XmlType; |
07 | import javax.xml.bind.annotation.XmlValue; |
08 |
09 | @XmlAccessorType (XmlAccessType.FIELD) |
10 | @XmlType |
11 | public class MyHashEntryType { |
12 |
13 | @XmlAttribute |
14 | public Integer key; |
15 |
16 | @XmlValue |
17 | public String value; |
18 |
19 | } |
下面做一个 Demo
来使用一下我们的 Adapter
:
01 | package org.bluedash.demo; |
02 |
03 | import java.io.File; |
04 |
05 | import javax.xml.bind.JAXBContext; |
06 | import javax.xml.bind.JAXBException; |
07 | import javax.xml.bind.Marshaller; |
08 | import javax.xml.bind.Unmarshaller; |
09 |
10 | public class Demo { |
11 |
12 | public static void main(String[] args) throws JAXBException { |
13 | JAXBContext jaxbContext = JAXBContext.newInstance(Foo. class ); |
14 |
15 | Foo foo = new Foo(); |
16 | foo.getHashmap().put( 1 , "One" ); |
17 | foo.getHashmap().put( 2 , "Two" ); |
18 | foo.getHashmap().put( 3 , "Three" ); |
19 |
20 | Marshaller marshaller = jaxbContext.createMarshaller(); |
21 | marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true ); |
22 |
23 | // Output the generated XML: |
24 | marshaller.marshal(foo, System.out); |
25 |
26 | // Save the output to a foo.xml |
27 | File xmlFile = new File( "foo.xml" ); |
28 | marshaller.marshal(foo, xmlFile); |
29 |
30 | // Restore the Foo class from xml file |
31 | Unmarshaller unmarshaller = jaxbContext.createUnmarshaller(); |
32 | Foo createdFoo = (Foo) unmarshaller.unmarshal(xmlFile); |
33 |
34 | // See the result |
35 | System.out.println(createdFoo.hashmap); |
36 | } |
37 | } |
代码运行结果如下:
1 | <? xml version = "1.0" encoding = "UTF-8" standalone = "yes" ?> |
2 | < foo > |
3 | < hashmap > |
4 | < entries key = "1" >One</ entries > |
5 | < entries key = "2" >Two</ entries > |
6 | < entries key = "3" >Three</ entries > |
7 | </ hashmap > |
8 | </ foo > |
9 | {1=One, 2=Two, 3=Three} |