JAXB和java.util.Map
具有諷刺意味的是,可能很難在JAXB(JSR-222)中映射java.util.Map類? 在這篇文章中,我將介紹一些使其變得更容易的項目。
Java模型
以下是我們將用于此示例的Java模型。
顧客
Customer類具有Map類型的屬性。 我之所以選擇此Map,是因為鍵是一個域對象,而值是一個域對象。
package blog.map;import java.util.*; import javax.xml.bind.annotation.*;@XmlRootElement public class Customer {private Map<String, Address> addressMap = new HashMap<String, Address>();public Map<String, Address> getAddressMap() {return addressMap;}public void setAddressMap(Map<String, Address> addressMap) {this.addressMap = addressMap;}}地址
Address類只是典型的POJO。
package blog.map;public class Address {private String street;public String getStreet() {return street;}public void setStreet(String street) {this.street = street;}}示范代碼
在下面的演示代碼中,我們將創建一個Customer實例并填充其Map屬性。 然后,將其封送為XML。
package blog.map;import javax.xml.bind.*;public class Demo {public static void main(String[] args) throws Exception {JAXBContext jc = JAXBContext.newInstance(Customer.class);Address billingAddress = new Address();billingAddress.setStreet('1 A Street');Address shippingAddress = new Address();shippingAddress.setStreet('2 B Road');Customer customer = new Customer();customer.getAddressMap().put('billing', billingAddress);customer.getAddressMap().put('shipping', shippingAddress);Marshaller marshaller = jc.createMarshaller();marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);marshaller.marshal(customer, System.out);}}用例#1 –默認表示
以下是與我們的域模型相對應的XML示例。 我們看到Map中的每個項目都有包裹在entry元素中的key和value元素。
<?xml version='1.0' encoding='UTF-8'?> <customer><addressMap><entry><key>shipping</key><value><street>2 B Road</street></value></entry><entry><key>billing</key><value><street>1 A Street</street></value></entry></addressMap> </customer>用例2 –重命名元素
JAXB參考實現使用@XmlElementWrapper批注來重命名與Map屬性相對應的元素(我們已在EclipseLink 2.4.2和2.5.0中向MOXy添加了此支持)。 在MOXy的早期版本中,應使用@XmlElement批注。
顧客
我們將使用@XmlElementWrapper批注將與addressMap屬性對應的元素重命名為address 。
package blog.map;import java.util.*; import javax.xml.bind.annotation.*;@XmlRootElement public class Customer {private Map<String, Address> addressMap = new HashMap<String, Address>();@XmlElementWrapper(name='addresses')public Map<String, Address> getAddressMap() {return addressMap;}public void setAddressMap(Map<String, Address> addressMap) {this.addressMap = addressMap;}}輸出量
現在我們看到的是,addressMap元素已被重新命名為地址 。
<?xml version='1.0' encoding='UTF-8'?> <customer><addresses><entry><key>shipping</key><value><street>2 B Road</street></value></entry><entry><key>billing</key><value><street>1 A Street</street></value></entry></addresses> </customer>用例#3 –添加命名空間資格
在此用例中,我們將研究將名稱空間限定應用于屬性類型為java.util.Map的類的影響。 有一個與Map屬性的名稱空間限定有關的MOXy錯誤,已在EclipseLink 2.4.2和2.5.0中修復(請參見: http : //bugs.eclipse.org/399297 )。
包裝信息
我們將使用包級別@XmlSchema批注來指定屬于該包中的類的所有字段/屬性都應使用http://www.example.com命名空間進行限定(請參閱: JAXB&Namespaces )。
@XmlSchema(namespace='http://www.example.com',elementFormDefault=XmlNsForm.QUALIFIED) package blog.map;import javax.xml.bind.annotation.*;輸出量
我們看到與Customer和Address類相對應的元素是名稱空間限定的,但與Map類相對應的元素則不是。 這是因為Map類來自java.util包,因此我們在包級別@XmlSchema注釋中指定的信息不適用。
<?xml version='1.0' encoding='UTF-8'?> <ns2:customer xmlns:ns2='http://www.example.com'><ns2:addresses><entry><key>shipping</key><value><ns2:street>2 B Road</ns2:street></value></entry><entry><key>billing</key><value><ns2:street>1 A Street</ns2:street></value></entry></ns2:addresses> </ns2:customer>用例#4 –使用XmlAdapter修復命名空間資格
我們可以使用XmlAdapter來調整前一個用例的名稱空間限定。
XmlAdapter(MapAdapter)
XmlAdapter機制允許您將一個類轉換為另一個類,以影響映射(請參閱: XmlAdapter – JAXB的Secret Weapon )。 為了獲得適當的名稱空間限定,我們將使用XmlAdapter將Map轉換為域模型包中的對象。
package blog.map;import java.util.*; import javax.xml.bind.annotation.adapters.XmlAdapter;public class MapAdapter extends XmlAdapter<MapAdapter.AdaptedMap, Map<String, Address>> {public static class AdaptedMap {public List<Entry> entry = new ArrayList<Entry>();}public static class Entry {public String key;public Address value;}@Overridepublic Map<String, Address> unmarshal(AdaptedMap adaptedMap) throws Exception {Map<String, Address> map = new HashMap<String, Address>();for(Entry entry : adaptedMap.entry) {map.put(entry.key, entry.value);}return map;}@Overridepublic AdaptedMap marshal(Map<String, Address> map) throws Exception {AdaptedMap adaptedMap = new AdaptedMap();for(Map.Entry<String, Address> mapEntry : map.entrySet()) {Entry entry = new Entry();entry.key = mapEntry.getKey();entry.value = mapEntry.getValue();adaptedMap.entry.add(entry);}return adaptedMap;}}顧客
@XmlJavaTypeAdapter批注用于在Map屬性上指定XmlAdapter 。 請注意,在應用XmlAdaper的情況下,我們需要將@XmlElementWrapper批注更改為@XmlElement (證明應該使用@XmlElement來注釋Map屬性的元素)。
package blog.map;import java.util.*; import javax.xml.bind.annotation.*; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;@XmlRootElement public class Customer {private Map<String, Address> addressMap = new HashMap<String, Address>();@XmlJavaTypeAdapter(MapAdapter.class)@XmlElement(name='addresses')public Map<String, Address> getAddressMap() {return addressMap;}public void setAddressMap(Map<String, Address> addressMap) {this.addressMap = addressMap;}}輸出量
現在,XML輸出中的所有元素都已使用http://www.example.com命名空間進行了限定。
<?xml version='1.0' encoding='UTF-8'?> <customer xmlns='http://www.example.com'><addresses><entry><key>shipping</key><value><street>2 B Road</street></value></entry><entry><key>billing</key><value><street>1 A Street</street></value></entry></addresses> </customer>參考: Java XML和JSON綁定博客中我們的JCG合作伙伴 Blaise Doughan的JAXB和java.util.Map 。
翻譯自: https://www.javacodegeeks.com/2013/03/jaxb-and-java-util-map.html
總結
以上是生活随笔為你收集整理的JAXB和java.util.Map的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 台式电脑怎么设置路由器密码(台式电脑怎么
- 下一篇: 天正cad旋转快捷键(天正cad快捷键大