Dictionary JAXB封送和解封送映射到/来自<;键>;价值</键>;

Dictionary JAXB封送和解封送映射到/来自<;键>;价值</键>;,dictionary,jaxb,key-value,unmarshalling,Dictionary,Jaxb,Key Value,Unmarshalling,我正在尝试对值对之间的映射进行封送和解封送。我可以成功封送该对象,但是,我无法将其从xml中解组。解组结果是映射中存在的键,但其值为null 以下是我要封送和解封送的模型: import java.util.Map; import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlElement

我正在尝试对值对之间的映射进行封送和解封送。我可以成功封送该对象,但是,我无法将其从xml中解组。解组结果是映射中存在的键,但其值为null

以下是我要封送和解封送的模型:

import java.util.Map;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;

@XmlRootElement(name="TestModel")
@XmlAccessorType(XmlAccessType.FIELD)
public class TestModel {

    @XmlElement(name="Name")
    private String name;

    @XmlJavaTypeAdapter(MapAdapter.class)
    private Map<String, String> metadata;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Map<String, String> getMetadata() {
        return metadata;
    }

    public void setMetadata(Map<String, String> metadata) {
        this.metadata = metadata;
    }
}
import java.util.Map;
导入javax.xml.bind.annotation.XmlAccessType;
导入javax.xml.bind.annotation.XmlAccessorType;
导入javax.xml.bind.annotation.xmlement;
导入javax.xml.bind.annotation.XmlRootElement;
导入javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
@XmlRootElement(name=“TestModel”)
@XmlAccessorType(XmlAccessType.FIELD)
公共类测试模型{
@xmlement(name=“name”)
私有字符串名称;
@XmlJavaTypeAdapter(MapAdapter.class)
私有地图元数据;
公共字符串getName(){
返回名称;
}
公共void集合名(字符串名){
this.name=名称;
}
公共映射getMetadata(){
返回元数据;
}
公共void setMetadata(映射元数据){
this.metadata=元数据;
}
}
我为封送和解封送创建了一个映射适配器,如下所示:

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.annotation.XmlAnyElement;
import javax.xml.bind.annotation.adapters.XmlAdapter;
import javax.xml.namespace.QName;
import org.w3c.dom.Element;

public class MapAdapter extends XmlAdapter<MapWrapper, Map<String, String>> {

@Override
public MapWrapper marshal(Map<String, String> m) throws Exception {
    MapWrapper wrapper = new MapWrapper();
    List<JAXBElement<String>> elements = new ArrayList<JAXBElement<String>>();
    if (m != null && !m.isEmpty()) {
        for (Entry<String, String> property : m.entrySet()) {
            elements.add(new JAXBElement<String>(new QName(property.getKey()), 
                    String.class, property.getValue().toString()));
        }
    }
    wrapper.elements = elements;
    return wrapper;
}

@Override
public Map<String, String> unmarshal(MapWrapper v) throws Exception {
    Map<String, String> map = new HashMap<String, String>();
    if (v != null && v.elements != null && !v.elements.isEmpty()) {
        for (Object object : v.elements) {
            Element element = (Element) object;
            map.put(element.getNodeName(), element.getNodeValue());
        }
    }
    return map;
}

}

class MapWrapper {

    @XmlAnyElement(lax=true)
    protected List<JAXBElement<String>> elements;
}
import java.util.ArrayList;
导入java.util.HashMap;
导入java.util.List;
导入java.util.Map;
导入java.util.Map.Entry;
导入javax.xml.bind.JAXBElement;
导入javax.xml.bind.annotation.xmlanyement;
导入javax.xml.bind.annotation.adapters.XmlAdapter;
导入javax.xml.namespace.QName;
导入org.w3c.dom.Element;
公共类MapAdapter扩展了XmlAdapter{
@凌驾
公共MapWrapper封送处理程序(Map m)引发异常{
MapWrapper=新的MapWrapper();
列表元素=新的ArrayList();
如果(m!=null&&!m.isEmpty()){
对于(条目属性:m.entrySet()){
添加(新的JAXBElement(新的QName(property.getKey()),
String.class、property.getValue().toString());
}
}
wrapper.elements=元素;
返回包装器;
}
@凌驾
公共映射解组器(MapWrapper v)引发异常{
Map Map=newhashmap();
如果(v!=null&&v.elements!=null&&v.elements.isEmpty()){
对于(对象:v.elements){
元素=(元素)对象;
put(element.getNodeName(),element.getNodeValue());
}
}
返回图;
}
}
类映射包装器{
@xmlanyement(lax=true)
受保护的列表元素;
}
下面的类可以测试上述模型的封送和解封:

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;

public class TestEntry {

public static void main(String[] args) throws JAXBException {
    testMarshal();
    testUnmarshal();
}

public static void testMarshal() throws JAXBException {

    Map<String, String> metadata = new HashMap<String, String>();
    metadata.put("category", "test");
    metadata.put("creation", new SimpleDateFormat("yyyy-MM-dd").format(new Date()));
    TestModel model = new TestModel();
    model.setMetadata(metadata);
    model.setName("TESTMODEL");

    marshal(model, System.out);
}

public static void testUnmarshal() throws JAXBException {

    String model = "<?xml version='1.0' encoding='UTF-8' standalone='yes'?>"
            + "<TestModel>"
            +   "<Name>TESTMODEL</Name>"
            +   "<metadata>"
            +       "<category>test</category>"
            +       "<creation>2015-09-29</creation>"
            +   "</metadata>"
            + "</TestModel>";

    TestModel result = unmarshal(new ByteArrayInputStream(model.getBytes()), TestModel.class);
    System.out.println("name=" + result.getName());
    for (String key : result.getMetadata().keySet()) {
        System.out.println(key + ", " + result.getMetadata().get(key));
    }
}

public static <T> void marshal(T cls, OutputStream os) throws JAXBException {
    JAXBContext context = JAXBContext.newInstance(cls.getClass());
    Marshaller marshaller = context.createMarshaller();
    marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
    marshaller.marshal(cls, os);
}

@SuppressWarnings("unchecked")
public static <T> T unmarshal(InputStream is, Class<T> cls)
        throws JAXBException {
    JAXBContext context = JAXBContext.newInstance(cls);
    Unmarshaller unmarshaller = context.createUnmarshaller();
    return (T) unmarshaller.unmarshal(is);
}
}
import java.io.ByteArrayInputStream;
导入java.io.InputStream;
导入java.io.OutputStream;
导入java.text.simpleDataFormat;
导入java.util.Date;
导入java.util.HashMap;
导入java.util.Map;
导入javax.xml.bind.JAXBContext;
导入javax.xml.bind.JAXBException;
导入javax.xml.bind.Marshaller;
导入javax.xml.bind.Unmarshaller;
公共类测试中心{
公共静态void main(字符串[]args)抛出JAXBEException{
testMarshal();
testUnmarshal();
}
public static void testmarshall()抛出JAXBEException{
映射元数据=新建HashMap();
元数据。put(“类别”、“测试”);
metadata.put(“创建”,新SimpleDataFormat(“yyyy-MM-dd”).format(新日期());
TestModel model=新的TestModel();
model.setMetadata(元数据);
model.setName(“TESTMODEL”);
编组(模型、系统、输出);
}
public static void testUnmarshal()抛出jaxbeexception{
字符串模型=“”
+ ""
+“测试模型”
+   ""
+“测试”
+       "2015-09-29"
+   ""
+ "";
TestModel result=unmarshal(新的ByteArrayInputStream(model.getBytes()),TestModel.class);
System.out.println(“name=“+result.getName());
for(字符串键:result.getMetadata().keySet()){
System.out.println(key+,“+result.getMetadata().get(key));
}
}
公共静态无效封送处理(TCLS、OutputStream os)抛出JAXBEException{
JAXBContext context=JAXBContext.newInstance(cls.getClass());
Marshaller=context.createMarshaller();
setProperty(marshaller.JAXB_格式化的_输出,true);
marshaller.marshall(cls,os);
}
@抑制警告(“未选中”)
公共静态T解组(InputStream is,类cls)
抛出异常{
JAXBContext context=JAXBContext.newInstance(cls);
Unmarshaller Unmarshaller=context.createUnmarshaller();
返回(T)解组器。解组器(is);
}
}
似乎在调用“publicmap unmarshal(MapWrapper v)抛出异常”时,映射只包含具有“null”值的键

我还发现了一个关于这个问题“”的类似问题,但是,它没有解决解编问题?

一个非常小的更正:

map.put(element.getNodeName(), element.getTextContent());

最后,你救了我一天。@Janewzh只要接受你认为正确的答案就行了。