【问题标题】:JAXB: Getting empty values when serializing nested mapsJAXB:序列化嵌套映射时获取空值
【发布时间】:2013-10-27 10:56:48
【问题描述】:

我正在尝试使用 JAXB 序列化 XML 中的类。

@XmlRootElement
class Foo
{
   Hashtable<String, Hashtable<String, Integer>> table = new Hashtable<>();

   public Hashtable<String, Hashtable<String, Integer>> getTable() {
     return table;
   }

   public void setTable(Hashtable<String, Hashtable<String, Integer>> t) {
     table = t;
  }
}

但是,这会生成带有空值的 XML(我向您保证这些值确实存在!)

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Foo>
    <table>
        <entry>
            <key>Test key</key>
            <value/>
        </entry>
    </table>
</Foo>

有没有简单的方法来解决这个问题?我真的不想使用@XmlJavaTypeAdapters,除非我真的必须这样做。

使用普通的哈希表可以正常工作:Hashtable&lt;String, Integer&gt;&gt; table = new Hashtable&lt;&gt;();

【问题讨论】:

    标签: java xml jaxb


    【解决方案1】:

    很抱歉让您失望了,但目前没有简单的方法可以解决它。外部和内部哈希表之间存在显着差异。外层是一个属性,由com.sun.xml.bind.v2.runtime.property.SingleMapNodeProperty&lt;BeanT, ValueT&gt; 类在内部处理。这个类做了一些魔术来将映射表示为键/值条目。

    但是,在内部 Hashtable 的情况下,它不是“静态”属性,而是动态属性。这就是为什么它由通用com.sun.xml.bind.v2.model.impl.RuntimeClassInfoImpl 处理。此类在 Hashtable 中找不到任何 JAXB 属性(即 java bean 属性 - 同时具有 getter 和 setter)。结果你得到空的value 元素。

    由于同样的原因,以下动态 Hashtable 属性也不起作用:

    @XmlRootElement
    @XmlSeeAlso(Hashtable.class)
    public static class TypeWithHashtableAsObject {
        private Object property;
    
        public Object getProperty() {
            return property;
        }
    
        public void setProperty(Object property) {
            this.property = property;
        }
    
    }
    
    ...
    TypeWithHashtableAsObject foo = new TypeWithHashtableAsObject();
    Hashtable<String, Integer> property = new Hashtable<>();
    property.put("innerKey", 12);
    foo.setProperty(property);
    StringWriter writer = new StringWriter();
    marshaller.marshal(foo, writer);
    System.out.println(writer.toString());
    

    结果:

    <typeWithHashtableAsObject>
        <property xsi:type="hashtable" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"/>
    </typeWithHashtableAsObject>
    

    那是空元素。

    In another answer 您可以找到更多如何编组嵌套集合的示例。另一种解决方案是用另一种类型包装 Hashtable。喜欢表:

    public class Table {
        private Hashtable<String, Integer> table = new Hashtable<>();
    
        public Table(Hashtable<String, Integer> table) {
            this.table = table;
        }
    
        public Table() {
    
        }
    
        public Hashtable<String, Integer> getTable() {
            return table;
        }
    
        public void setTable(Hashtable<String, Integer> table) {
            this.table = table;
        }
    
    }
    

    并将Foo.table 类型更改为Hashtable&lt;String, Table&gt;

    结果比原来的更详细,但恕我直言,非常一致:

    <foo>
       <table>
          <entry>
             <key>key1</key>
             <value>
                <table>
                   <entry>
                      <key>innerKey</key>
                      <value>12</value>
                   </entry>
                </table>
             </value>
          </entry>
       </table>
    </foo>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-12-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-05
      • 1970-01-01
      • 2012-04-27
      相关资源
      最近更新 更多