Java JAXB映射适配器

Java JAXB映射适配器,java,xml,jaxb,Java,Xml,Jaxb,我在将XML复杂类型转换为java.util.Map时遇到问题。解组时,只填充值,键变为NULL。我希望下面的XML转换为java.util.Map,但它的格式类似于java.util.Map。有人能告诉我为什么把密钥设为空吗 XML <root> <myMap> <user_type>students</user_type> </myMap> </root> 学生 POJO @XmlRootEleme

我在将XML复杂类型转换为java.util.Map时遇到问题。解组时,只填充值,键变为NULL。我希望下面的XML转换为
java.util.Map
,但它的格式类似于
java.util.Map
。有人能告诉我为什么把密钥设为空吗

XML

<root>
  <myMap>
    <user_type>students</user_type>
  </myMap>
</root>

学生
POJO

@XmlRootElement(name = "root")
@XmlAccessorType(XmlAccessType.FIELD)
public class MyPojo implements Serializable {

private static final long serialVersionUID = -4589166768649033266L;

@XmlElement(name = "myMap")
@XmlJavaTypeAdapter(MapAdapter.class)
private Map<String,String> myMap;

 //getters and setters
}
@XmlRootElement(name=“root”)
@XmlAccessorType(XmlAccessType.FIELD)
公共类MyPojo实现可序列化{
私有静态最终长serialVersionUID=-4589166768649033266L;
@xmlement(name=“myMap”)
@XmlJavaTypeAdapter(MapAdapter.class)
私人地图myMap;
//接球手和接球手
}
MapAdapter实现是

@覆盖
公共映射解组(AdaptedMap AdaptedMap)引发异常{
列出adaptedEntries=adaptedMap.entries;
Map Map=newhashmap(adaptedEntries.size());
for(AdaptedEntry AdaptedEntry:AdaptedEntry){
map.put(adaptedEntry.key、adaptedEntry.value);
}
返回图;
}

我看到的第一个错误是,您使用的是
映射
映射,而您的XML有一个字符串值

按如下方式更改代码:

public class MapAdapter extends XmlAdapter<MapAdapter.AdaptedMap, Map<String, String>> {

    public static class AdaptedMap {

        @XmlVariableNode("key")
        List<AdaptedEntry> entries = new ArrayList<AdaptedEntry>();

    }

    public static class AdaptedEntry {

        @XmlTransient
        public String key;

        @XmlValue
        public String value;

    }

    @Override
    public AdaptedMap marshal(Map<String, String> map) throws Exception {
        AdaptedMap adaptedMap = new AdaptedMap();
        for(Entry<String, String> entry : map.entrySet()) {
            AdaptedEntry adaptedEntry = new AdaptedEntry();
            adaptedEntry.key = entry.getKey();
            adaptedEntry.value = entry.getValue();
            adaptedMap.entries.add(adaptedEntry);
        }
        return adaptedMap;
    }

    @Override
    public Map<String, String> unmarshal(AdaptedMap adaptedMap) throws Exception {
        List<AdaptedEntry> adaptedEntries = adaptedMap.entries;
        Map<String, String> map = new HashMap<String, String>(adaptedEntries.size());
        for(AdaptedEntry adaptedEntry : adaptedEntries) {
            map.put(adaptedEntry.key, adaptedEntry.value);
        }
        return map;
    }

}
public class Root
{
private MyPojo myPojo;

public MyPojo getMyPojo()
{
    return myPojo;
}

public void setMyPojo(MyPojo myPojo)
{
    this.myPojo = myPojo;
}

@Override
public String toString()
{
    return "Root [myPojo=" + myPojo + "]";
}
}

如果使用转换框,有两种方法可以实现此目的。。。()

方式1

将XML转换为映射,并将映射设置为POJO

import java.util.Map;

import cjm.component.cb.map.ToMap;

public class Testing
{
public static void main(String[] args)
{
    try
    {
        String xml = "<root><myMap><user_type>students</user_type></myMap></root>";

        System.out.println("XML: " + xml); // your XML

        ToMap toMap = new ToMap();

        Map<String, Object> map = toMap.convertToMap(xml);

        System.out.println("Converted Map: " + map); // converted map

        Map<String, Object> rootMap = (Map<String, Object>) map.get("root");
        Map<String, String> myMap = (Map<String, String>) rootMap.get("myMap");

        System.out.println("My Map: " + myMap); // final map you want);

        MyPojo myPojo = new MyPojo();

        myPojo.setMyMap(myMap); // map set to the POJO

        System.out.println("POJO: " + myPojo);
    }
    catch (Exception e)
    {
        e.printStackTrace();
    }
}
}
我的波乔

import java.io.Serializable;
import java.util.Map;

public class MyPojo implements Serializable
{
private static final long serialVersionUID = -4589166768649033266L;

private Map<String, String> myMap;

public Map<String, String> getMyMap()
{
    return myMap;
}

public void setMyMap(Map<String, String> myMap)
{
    this.myMap = myMap;
}

@Override
public String toString()
{
    return "MyPojo [myMap=" + myMap + "]";
}
}
import java.io.Serializable;
导入java.util.Map;
公共类MyPojo实现可序列化
{
私有静态最终长serialVersionUID=-4589166768649033266L;
私人地图myMap;
公共地图getMyMap()
{
返回myMap;
}
公共void setMyMap(映射myMap)
{
this.myMap=myMap;
}
@凌驾
公共字符串toString()
{
返回“MyPojo[myMap=“+myMap+”]”;
}
}
转化

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import cjm.component.cb.object.ToObject;

public class Testing
{
public static void main(String[] args)
{
    try
    {
        String xml = "<root><myMap><user_type>students</user_type></myMap></root>";

        System.out.println("XML: " + xml); // your XML

        Map<String, String> headerMap = new HashMap<String, String>();

        headerMap.put("root", "myPojo"); // header substitutions

        List<Object> objectList = new ArrayList<Object>();

        objectList.add(new MyPojo()); // since its a nested POJO

        ToObject toObject = new ToObject();

        Root root = (Root) toObject.convertToObject(xml, new Root(), objectList, headerMap); // conversion to POJO

        System.out.println("POJO: " + root);
    }
    catch (Exception e)
    {
        e.printStackTrace();
    }
}
}
import java.util.ArrayList;
导入java.util.HashMap;
导入java.util.List;
导入java.util.Map;
导入cjm.component.cb.object.ToObject;
公共类测试
{
公共静态void main(字符串[]args)
{
尝试
{
String xml=“students”;
System.out.println(“XML:+XML);//您的XML
Map headerMap=newhashmap();
headerMap.put(“root”,“myPojo”);//头替换
List objectList=new ArrayList();
objectList.add(new MyPojo());//因为它是嵌套的POJO
ToObject ToObject=新的ToObject();
Root=(Root)toObject.convertToObject(xml,new Root(),objectList,headerMap);//到POJO的转换
System.out.println(“POJO:+root”);
}
捕获(例外e)
{
e、 printStackTrace();
}
}
}
输出:

XML: <root><myMap><user_type>students</user_type></myMap></root>
-------- XML Detected -------- 
-------- Map created Successfully -------- 
Converted Map: {root={myMap={user_type=students}}}
My Map: {user_type=students}
POJO: MyPojo [myMap={user_type=students}]
XML: <root><myMap><user_type>students</user_type></myMap></root>
-------- XML Detected -------- 
-------- XML Detected -------- 
-------- Map created Successfully -------- 
-------- Object created Successfully -------- 
POJO: Root [myPojo=MyPojo [myMap={user_type=students}]]
XML:学生
--------检测到XML--------
--------检测到XML--------
--------已成功创建映射--------
--------已成功创建对象--------
POJO:Root[myPojo=myPojo[myMap={user\u type=students}]]

您是如何实现
MapAdapter.unmarshal()方法的?事实上,发布整个
MapAdapter
实现类代码。我在问题中添加了unmarshal方法。。我正在跟踪的具体实现。要使用(我的)博客文章中的方法,您需要确保使用MOXy作为您的JAXB(JSR-222)提供程序,因为它使用了
@XmlVariableNode
扩展,请参阅:非常感谢Blaise,我怀疑该注释,但没有深入研究。顺便说一句,我们有没有其他方法在不使用moxy的情况下实现map适配器?我在复制代码时将其更改为String。还是同样的问题。感谢Buhake的快速响应,但即使在添加XML元素之后,也会将密钥设置为NULL。我怀疑@XmlVariableNode(“key”),它到底做了什么,你能帮我吗?用你的整个源代码、POJO和适配器更新你的整个帖子,并指定整个异常stacktrace。根据企业安全策略,我不应该在公共论坛上发布实际的代码,但是适配器的实现与您发布的完全一样。那么我无法帮助您,因为我没有足够的信息来处理。祝你好运
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import cjm.component.cb.object.ToObject;

public class Testing
{
public static void main(String[] args)
{
    try
    {
        String xml = "<root><myMap><user_type>students</user_type></myMap></root>";

        System.out.println("XML: " + xml); // your XML

        Map<String, String> headerMap = new HashMap<String, String>();

        headerMap.put("root", "myPojo"); // header substitutions

        List<Object> objectList = new ArrayList<Object>();

        objectList.add(new MyPojo()); // since its a nested POJO

        ToObject toObject = new ToObject();

        Root root = (Root) toObject.convertToObject(xml, new Root(), objectList, headerMap); // conversion to POJO

        System.out.println("POJO: " + root);
    }
    catch (Exception e)
    {
        e.printStackTrace();
    }
}
}
XML: <root><myMap><user_type>students</user_type></myMap></root>
-------- XML Detected -------- 
-------- XML Detected -------- 
-------- Map created Successfully -------- 
-------- Object created Successfully -------- 
POJO: Root [myPojo=MyPojo [myMap={user_type=students}]]