2011-07-25 87 views
7

我想將POJO類中的HashMap轉換爲XML。我嘗試過使用XmlAdapter,但它只導致HashMap的鍵和值對作爲XML元素的屬性。我需要Key作爲元素本身,而HashMap的值是元素的值。舉例來說,我需要以下XML:JAXB HashMap無法映射

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<cart> 
<supervisor_id>555</supervisor_id> 
<payments> 
    <payment sequence="1"> 
     <amount>123.45</amount> 
     <billing_method>12345</billing_method> 
     <form>card</form> 
     <delivery_mode>Q</delivery_mode> 
    </payment> 
<payment sequence="2"> 
     <amount>123.45</amount> 
     <person_id>2333</person_id> 
     <form>cash</form> 
     <delivery_mode>Q</delivery_mode> 
    </payment> 
</payments> 
</cart> 

我創建了以下類:MyMapType持有它有兩個字段,即鍵和值MyMapEntryType類的列表。如何將Key元素更改爲@XmlElement並將值字段分配給Key字段?


這是我的源文件。

MyMapType.java

import java.util.ArrayList; 
import java.util.List; 

public class MyMapType { 

    private List<MyMapEntryType> entry = new ArrayList<MyMapEntryType>(); 

    public List<MyMapEntryType> getEntry() { 
     return entry; 
    } 

    public void setEntry(List<MyMapEntryType> entry) { 
     this.entry = entry; 
    } 

} 

MyMapEntryType.java

import javax.xml.bind.annotation.XmlAccessType; 
import javax.xml.bind.annotation.XmlAccessorType; 
import javax.xml.bind.annotation.XmlAttribute; 
import javax.xml.bind.annotation.XmlValue; 

@XmlAccessorType(XmlAccessType.FIELD) 
public class MyMapEntryType { 

@XmlAttribute 
private String key; 
@XmlValue 
private String value; 
public String getKey() { 
    return key; 
} 
public void setKey(String key) { 
    this.key = key; 
} 
public String getValue() { 
    return value; 
} 
public void setValue(String value) { 
    this.value = value; 
} 
} 

還請找到適配器類:

MyMapAdapter.java

import java.util.HashMap; 
import java.util.Map; 
import java.util.Map.Entry; 
import javax.xml.bind.annotation.adapters.XmlAdapter; 

public class MyMapAdapter extends XmlAdapter<MyMapType, Map<String, String>> { 

    @Override 
    public MyMapType marshal(Map<String, String> map) throws Exception { 

     MyMapType myMapType = new MyMapType(); 

     for(Entry<String, String> entry : map.entrySet()) { 
     MyMapEntryType myMapEntryType = new MyMapEntryType(); 
     myMapEntryType.setKey(entry.getKey()); 
     myMapEntryType.setValue(entry.getValue()); 
     myMapType.getEntry().add(myMapEntryType); 
     } 
     return myMapType; 
    } 

    @Override 
    public Map<String, String> unmarshal(MyMapType map) throws Exception { 
     HashMap<String, String> hashMap = new HashMap<String, String>(); 
     for(MyMapEntryType myEntryType : map.getEntry()) { 
     hashMap.put(myEntryType.getKey(), myEntryType.getValue()); 
     } 
     return hashMap; 
    } 
} 

這是一個有HashMap的領域類:

XmlElementMap.java

@XmlAccessorType(XmlAccessType.FIELD) 
public class XmlElementMap { 

@XmlAttribute(name="sequence") 
private int sequence; 

@XmlJavaTypeAdapter(MyMapAdapter.class) 
private Map<String, String> map = new HashMap<String, String>(); 

public int getSequence() { 
    return sequence; 
} 

public void setSequence(int sequence) { 
    this.sequence = sequence; 
} 

public Map<String, String> getMap() { 
    return map; 
} 

public void setMap(Map<String, String> map) { 
    this.map = map; 
} 


} 


請就如何實現這一目標的建議。

問候,
-Anand

目前,它產生以下輸出:

回答

14

我有同樣的要求,「我需要的關鍵是元素本身和HashMap的是價值的價值元素「。

我沒有使用自定義的適配器,而是通過將HashMap條目動態地轉換爲JAXBElement對象列表來實現它,然後使用@XmlAnyElement對列表進行註釋。

@XmlRootElement(name="root") 
public class MyMapType { 

    @XmlAnyElement 
    public List<JAXBElement> entries = new ArrayList<JAXBElement>(); 

    public MyMapType() { // JAXB required  
    } 

    public MyMapType(Map<String, String> map) { 
     for (Map.Entry<String, String> entry : map.entrySet()) { 
      entries.add(new JAXBElement(new QName(entry.getKey()), 
        String.class, entry.getValue())); 
     } 
    } 

    public static void main(String[] args) throws Exception { 
     JAXBContext context = JAXBContext.newInstance(MyMapType.class); 
     Marshaller marshaller = context.createMarshaller(); 
     marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); 

     Map<String, String> map = new LinkedHashMap<String, String>(); 
     map.put("key1", "value1"); 
     map.put("key2", "value2"); 
     MyMapType mt = new MyMapType(map); 

     marshaller.marshal(mt, System.out); 
    } 
} 

輸出是,

<?xml version="1.0" encoding="UTF-8" standalone="yes"?> 
<root> 
    <key1>value1</key1> 
    <key2>value2</key2> 
</root> 
+0

+1非常有趣和意想不到的工作解決方案。 – informatik01

+0

迄今爲止我所見過的最簡單的解決方案。謝謝! – sinu

+0

這是一個很好的XML解決方案,但不幸的是,在JAX-RS註釋方法中編組爲JSON時,MOXy似乎無法正確處理此問題。以某種方式列表觸發編組到JSON數組,所以結果看起來是這樣的: { 「根」: { 「KEY1」:[ 「VALUE1」], 「KEY2」:[ 「VALUE2」], 「key3」:[「value3」] } } 如果有人有一個想法如何解決這個問題,我將不勝感激。 –