Java Jaxb中的地图编组问题

Java Jaxb中的地图编组问题,java,map,jaxb,marshalling,Java,Map,Jaxb,Marshalling,我有一个包含人类地图的类世界。如果我封送类世界,我会得到以下输出: <world> <humans> <human key="2"> <value> <name>Tom</name> </value> </human> <human key="1">

我有一个包含人类地图的类世界。如果我封送类世界,我会得到以下输出:

<world>
    <humans>
        <human key="2">
            <value>
                <name>Tom</name>
            </value>
        </human>
        <human key="1">
            <value>
                <name>Max</name>
            </value>
        </human>
    </humans>
</world>

汤姆
马克斯
但是我不想显示“value”-标记。它应该是这样的:

<world>
    <humans>
        <human key="2">
            <name>Tom</name>
        </human>
        <human key="1">
            <name>Max</name>
        </human>
    </humans>
</world>

汤姆
马克斯
这可能吗

下面是世界级和人类级的代码:

@XmlRootElement
public class Human {

    @XmlElement
    private String name;

    public Human(){}
}

@XmlRootElement
public class World {

    private Map<String, Human> humans = new HashMap<String, Human>();

    public World(){}

    @XmlElementWrapper( name = "humans")
    @XmlElement(name = "human")
    public HumanEntry[] getMap() {
        List<HumanEntry> list = new ArrayList<HumanEntry>();
        for (Entry<String, Human> entry : humans.entrySet()) {
            HumanEntry mapEntry =new HumanEntry();
            mapEntry.key = entry.getKey();
            mapEntry.value = entry.getValue();
            list.add(mapEntry);
        }
        return list.toArray(new HumanEntry[list.size()]);
    }

    public void setMap(HumanEntry[] arr) {
        for(HumanEntry entry : arr) {
            this.humans.put(entry.key, entry.value);
        }
    }

    public static class HumanEntry {
        @XmlAttribute
        public String key;

        @XmlElement
        public Human value;
    }

    public void addHuman(String key, Human human){
        this.humans.put(key, human);
    }
}
@XmlRootElement
公共级人员{
@XmlElement
私有字符串名称;
公共人权({}
}
@XmlRootElement
公共阶级世界{
私有映射人=新HashMap();
公共世界(){}
@XmlElementWrapper(name=“humans”)
@xmlement(name=“human”)
public HumanEntry[]getMap(){
列表=新的ArrayList();
for(条目:humans.entrySet()){
HumanEntry mapEntry=新的HumanEntry();
mapEntry.key=entry.getKey();
mapEntry.value=entry.getValue();
列表。添加(地图条目);
}
return list.toArray(新的HumanEntry[list.size()]);
}
公共无效设置映射(HumanEntry[]arr){
用于(人工输入:arr){
this.humans.put(entry.key,entry.value);
}
}
公共静态类入口{
@XmlAttribute
公共字符串密钥;
@XmlElement
公共人文价值;
}
public void addHuman(字符串键,Human-Human){
这个.人.放(键,人);
}
}

我想您正在寻找XmlValue注释:

在您的例子中,它将应用于HumanEntry.value,而不是XmlElement,正如
XmlAdapter所指出的那样,可以使用
将替代映射应用于JAXB中的映射(或任何类型)。下面是一个具体示例的链接:

了解更多信息


    • 我的解决方案

      我将key属性添加到human,然后将贴图转换为数组:

      @XmlRootElement
      public class World {
      
          @XmlJavaTypeAdapter(HumanAdapter.class)
          private Map<String, Human> humans = new HashMap<String, Human>();
      
          public World(){}
      }
      
      public class Human {
      
          @XmlElement
          private String name;
      
          @XmlAttribute(name="key")
          private String key;
      
          public Human(){}
      }
      
      public class HumanAdapter extends XmlAdapter<HumanJaxbCrutch, Map<String, Human>> {
      
          @Override
          public HumanJaxbCrutch marshal(Map<String, Human> humans) throws Exception {
              List<Human> list = new ArrayList<Human>();
              for (Entry<String, Human> entry : humans.entrySet()) {
                  list.add(entry.getValue());
              }
      
              HumanJaxbCrutch humanJaxbCrutch = new HumanJaxbCrutch();
              humanJaxbCrutch.setCourses(list.toArray(new Human[list.size()])); 
      
              return humanJaxbCrutch;
          }
      
          @Override
          public Map<String, Human> unmarshal(HumanJaxbCrutch humans) throws Exception {
              Map<String, Human> map = new HashMap<String, Human>();
      
              for(Human human : humans.getCourses()){
                  map.put(human.getKey(), human);
              }
      
              return map;
          }
      }
      
      class HumanJaxbCrutch {
      
          private Human[] courses;
      
          @XmlElement(name = "human")
          public Human[] getCourses() {
              return courses;
          }
      
          public void setCourses(Human[] courses) {
              this.courses = courses;
          }
      }
      
      @XmlRootElement
      公共阶级世界{
      @XmlJavaTypeAdapter(HumanAdapter.class)
      私有映射人=新HashMap();
      公共世界(){}
      }
      公共级人员{
      @XmlElement
      私有字符串名称;
      @xmltattribute(name=“key”)
      私钥;
      公共人权({}
      }
      公共类HumanAdapter扩展了XmlAdapter{
      @凌驾
      公共HumanJaxbCrutch封送处理(映射人)引发异常{
      列表=新的ArrayList();
      for(条目:humans.entrySet()){
      list.add(entry.getValue());
      }
      HumanJaxbCrutch HumanJaxbCrutch=新的HumanJaxbCrutch();
      humanJaxbCrutch.setCourses(list.toArray(新的Human[list.size()]);
      返回到bcrutch;
      }
      @凌驾
      公共映射解组(HumanJaxbCrutch humans)引发异常{
      Map Map=newhashmap();
      for(Human:humans.getCourses()){
      map.put(human.getKey(),human);
      }
      返回图;
      }
      }
      类jaxbcrutch{
      私人人权课程;
      @xmlement(name=“human”)
      公共人权课程(){
      返回课程;
      }
      公共课程(人类[]课程){
      本课程=课程;
      }
      }
      
      不幸的是@XmlValue需要引用映射到XML文本的Java类型。所以我不能使用它,特别是如果人类变得越来越复杂,你是对的“如果字段或属性的类型不是集合类型,那么该类型必须映射到XML模式简单类型”,那么我想你唯一的选择就是创建一个类型适配器use@XmlJavaTypeAdapter(HumanAdapter.class)在HumanEntry上,创建一个适配器,将HumanEntry转换为human,反之亦然,从HumanEntryThank中删除所有其他JaxB注释。请参阅我的答案以获得完整的解决方案。