2011-07-25 30 views
7

Tôi muốn chuyển đổi HashMap trong một lớp POJO thành XML. Tôi đã thử bằng cách sử dụng XmlAdapter nhưng nó chỉ kết quả trong các cặp khóa và giá trị của HashMap là các thuộc tính của các phần tử XML. Tôi cần Key là Element và giá trị của HashMap là giá trị của phần tử. Ví dụ: tôi cần XML sau:JAXB HashMap unmappable

<?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> 

Tôi đã tạo các lớp sau: MyMapType chứa danh sách lớp MyMapEntryType có hai trường là Khóa và giá trị. Làm cách nào để thay đổi phần tử Key thành @XmlElement và gán trường giá trị cho trường Khóa?


Đây là các tệp nguồn của tôi.

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; 
} 
} 

Xin cũng tìm thấy những lớp adapter:

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; 
    } 
} 

Đây là lớp học trong đó có lĩnh vực 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; 
} 


} 


Xin cho biết làm thế nào để đạt được điều này.

Kính trọng,
-Anand

Hiện nay nó xuất ra như sau:

Trả lời

14

Tôi có yêu cầu tương tự "Tôi cần Key là phần tử bản thân và giá trị của HashMap là giá trị của phần tử ".

Tôi không sử dụng bộ điều hợp tùy chỉnh, nhưng đã triển khai nó bằng cách chuyển đổi các mục nhập HashMap động thành danh sách đối tượng JAXBElement và sau đó chú thích danh sách bằng @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); 
    } 
} 

Kết quả là,

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

+1 cho giải pháp làm việc rất thú vị và bất ngờ. – informatik01

+0

giải pháp dễ nhất cho đến nay tôi đã thấy. Cảm ơn! – sinu

+0

Đây là một giải pháp gọn gàng cho XML, nhưng tiếc là MOXy dường như không thể xử lý điều này một cách đúng đắn khi marshalling thành JSON trong một phương thức chú thích JAX-RS.Bằng cách nào đó, trình kích hoạt Danh sách khớp với một mảng JSON, do đó kết quả trông giống như sau: {"root": {"key1": ["value1"], "key2": ["value2"], "key3": ["value3"] } } Tôi rất biết ơn nếu ai đó có ý tưởng khắc phục sự cố này. –