【问题标题】:Jackson serializing JAXB object gives strange results杰克逊序列化 JAXB 对象给出了奇怪的结果
【发布时间】:2013-04-16 12:51:58
【问题描述】:

我有一个 JAXB 对象。当我序列化它时,结果很有趣!像这样 =>

{"formData":{
"preConditions":{
    "acceptTermsAndConditions":"<?xml version=\"1.0\" encoding=\"UTF-16\"?>\n<acceptTermsAndConditions>true</acceptTermsAndConditions>",
    "receivePromoEmail":"<?xml version=\"1.0\" encoding=\"UTF-16\"?>\n<receivePromoEmail>false</receivePromoEmail>"
}, etc...

而源 XML 只有 truefalse 作为值:-

  <formData>
    <preConditions>
      <acceptTermsAndConditions>true</acceptTermsAndConditions>
      <receivePromoEmail>false</receivePromoEmail>
    </preConditions> etc...

我生成 JSON 的代码如下:-

    Application application = (Application) JAXBUtil.getXMLAsApplication();
    ObjectMapper mapper = new ObjectMapper();
    AnnotationIntrospector introspector = new JaxbAnnotationIntrospector(TypeFactory.defaultInstance());
    // make deserializer use JAXB annotations (only)
    mapper.getDeserializationConfig().with(introspector);
    // make serializer use JAXB annotations (only)
    mapper.getSerializationConfig().with(introspector);


    try {
        mapper.writeValue(new File("application.json"), application);
    } catch (IOException e) {
        e.printStackTrace();
    }

上面的 PreConditions 类是由 JAXB2 (XJC) 生成的。下面是一个sn-p:-

@XmlAccessorType(XmlAccessType.FIELD)
    @XmlType(name = "", propOrder = {
        "acceptTermsAndConditions",
        "receivePromoEmail"
    })
    public static class PreConditions {

        @XmlElement(required = true)
        protected Object acceptTermsAndConditions;
        @XmlElement(required = true)
        protected Object receivePromoEmail;

        /**
         * Gets the value of the acceptTermsAndConditions property.
         * 
         * @return
         *     possible object is
         *     {@link Object }
         *     
         */
        public Object getAcceptTermsAndConditions() {
            return acceptTermsAndConditions;
        }

        /**
         * Sets the value of the acceptTermsAndConditions property.
         * 
         * @param value
         *     allowed object is
         *     {@link Object }
         *     
         */
        public void setAcceptTermsAndConditions(Object value) {
            this.acceptTermsAndConditions = value;
        }

        /**
         * Gets the value of the receivePromoEmail property.
         * 
         * @return
         *     possible object is
         *     {@link Object }
         *     
         */
        public Object getReceivePromoEmail() {
            return receivePromoEmail;
        }

        /**
         * Sets the value of the receivePromoEmail property.
         * 
         * @param value
         *     allowed object is
         *     {@link Object }
         *     
         */
        public void setReceivePromoEmail(Object value) {
            this.receivePromoEmail = value;
        }

    }

关于 JSON 为何如此疯狂的任何线索?

【问题讨论】:

  • 信息不够:你能添加Application类型的定义吗?我的猜测是“acceptTermsAndConditions”和“receivePromoEmail”的类型是 DOM 文档之类的——这些不是 POJO 类型,只能序列化为原始字符串。
  • 根据要求更新了有关应用程序类型的信息。
  • 啊。现在,问题出在Application.FormData 之内(这就是“奇怪”JSON 所在的位置)。你也可以补充一下吗?我仍然认为类型被声明为 DOM Element 或其他一些特定于 XML 的类型,除了转储 XML 之外无法以其他方式处理。
  • 按要求添加了 Application.FormData。
  • 您如何查看您的数据以了解我为什么要求这些...答案就在其中,匹配已嵌入 XML 的字段。

标签: jaxb jackson


【解决方案1】:

由于acceptTermsAndConditions 的名义类型是java.lang.Object,因此很难知道到底发生了什么。序列化器将根据序列化的运行时类型进行选择——我的猜测是它会是 DOM Document。 在反序列化时,它不会很好地工作,只会变成java.util.Map

因此您可能需要更改架构以生成更具体的类型:java.lang.Object 的任何内容都可能导致问题。

您可能希望在序列化之前查看对象具有的实际 Java 类型。那应该解释奇怪的输出来自哪里。我不认为它可以是简单的布尔值。

【讨论】:

  • StaxMan - 感谢您的见解。不幸的是,我无法更改架构。我查看了运行时类型,它是 org.apache.xerces.dom.ElementNSImpl,所以我通过为此类型编写自定义序列化程序解决了我的问题。我有点惊讶 Jackson 的实现没有包含这个序列化器,因为这是 XJC 在模式中没有指定类型时生成的默认类型。
  • Jackson 不是 JAXB 实现,所以它可以做的最好的是将其序列化为字符串,它确实如此(DOM 元素有一个序列化器)。基本上,DOM 元素只是另一种外星数据类型。如果您想将其转换为 JSON 结构,自定义序列化程序是有意义的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-01-14
  • 2014-10-10
  • 2016-12-07
  • 2019-11-15
  • 2014-06-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多