首页 > 解决方案 > 解析 XML 时出现 Jackson UnrecognizedProperyException

问题描述

我正在尝试解析使用maven-jaxb2-pluginxsd 文件生成 DTO 的 XML。但我得到了这个例外,不知道为什么,一切似乎都很好。

Caused by: com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "Publish_Date" (class com.compnay.package.SdnList$PublshInformation), not marked as ignorable (2 known properties: "publishDate", "recordCount"])
 at [Source: (PushbackInputStream); line: 4, column: 44] (through reference chain: com.compnay.package.SdnList["publshInformation"]->com.compnay.package.domain.SdnList$PublshInformation["Publish_Date"])

相关 xsd 的 Jaxb 执行

<execution>
  <id>tds</id>
  <goals>
    <goal>generate</goal>
  </goals>
  <configuration>
    <schemas>
      <schema>                              
        <url>xsd url</url>
      </schema>
  </schemas>                     
  <generatePackage>com.company.domain</generatePackage>
  <generateDirectory>${project.basedir}/domain/src/main/java</generateDirectory>
  <episode>false</episode>
  </configuration>
</execution>

我收到错误的 XML 文件的一部分。

<publshInformation>
  <Publish_Date>08/06/2021</Publish_Date>
  <Record_Count>9030</Record_Count>
</publshInformation>

休息模板配置

JacksonXmlModule module = new JacksonXmlModule();
module.setDefaultUseWrapper(false);

final XmlMapper xmlMapper = new XmlMapper(module);
xmlMapper.configure(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT, true);
// xmlMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); // Works when this is on

final MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(xmlMapper);
        converter.setSupportedMediaTypes(Collections.singletonList(MediaType.APPLICATION_XML));

        return new RestTemplateBuilder()
                .setReadTimeout(Duration.ofMillis(readTimeout))
                .setConnectTimeout(Duration.ofMillis(connectTimeout))
                .messageConverters(converter)
                .build();

生成的 DTO 的一部分

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "", propOrder = {
    "publshInformation",
    "sdnEntry"
})
@XmlRootElement(name = "sdnList")
public class SdnList {

    @XmlElement(required = true)
    protected SdnList.PublshInformation publshInformation;
    @XmlElement(required = true)
    protected List<SdnList.SdnEntry> sdnEntry;

    ........

    /**
     * <p>Java class for anonymous complex type.
     * 
     * <p>The following schema fragment specifies the expected content contained within this class.
     * 
     * <pre>
     * &lt;complexType&gt;
     *   &lt;complexContent&gt;
     *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType"&gt;
     *       &lt;sequence&gt;
     *         &lt;element name="Publish_Date" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/&gt;
     *         &lt;element name="Record_Count" type="{http://www.w3.org/2001/XMLSchema}int" minOccurs="0"/&gt;
     *       &lt;/sequence&gt;
     *     &lt;/restriction&gt;
     *   &lt;/complexContent&gt;
     * &lt;/complexType&gt;
     * </pre>
     * 
     * 
     */
    @XmlAccessorType(XmlAccessType.FIELD)
    @XmlType(name = "", propOrder = {
        "publishDate",
        "recordCount"
    })
    public static class PublshInformation {

        @XmlElement(name = "Publish_Date")
        protected String publishDate;
        @XmlElement(name = "Record_Count")
        protected Integer recordCount;
        ........
    }
}

我可以让它工作,xmlMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)但我不想丢失其他数据。谁能帮我弄清楚为什么我会得到 unrecognizedPropertyException?我将不胜感激任何指示。

标签: jacksonjaxbjackson-databindjaxb2-maven-plugin

解决方案


我猜您在使输入流为空之前正在做某事,derealization因此您会收到此错误。我使用了提供的 XML,似乎对我来说工作正常:

XML:

<publshInformation>
    <Publish_Date>08/06/2021</Publish_Date>
    <Record_Count>9030</Record_Count>
</publshInformation>

发布信息类:

@XmlRootElement(name = "publshInformation")
@Data
@XmlAccessorType(XmlAccessType.FIELD)
public class PublshInformation {

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

    @XmlElement(name = "Record_Count")
    private Integer recordCount;

}

PublishMain.class:

public class PublishMain {
    public static void main(String[] args) throws JAXBException, XMLStreamException, IOException {
        final InputStream inputStream = Unmarshalling.class.getClassLoader().getResourceAsStream("publish.xml");
        final XMLStreamReader xmlStreamReader = XMLInputFactory.newInstance().createXMLStreamReader(inputStream);
/*        final Unmarshaller unmarshaller = JAXBContext.newInstance(PublshInformation.class).createUnmarshaller();
        final PublshInformation publshInformation = unmarshaller.unmarshal(xmlStreamReader, PublshInformation.class).getValue();
        System.out.println(publshInformation.toString());

        Marshaller marshaller = JAXBContext.newInstance(PublshInformation.class).createMarshaller();
        marshaller.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);
        marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
        marshaller.marshal(publshInformation, System.out);*/

        System.out.println(inputStream);
        final XmlMapper xmlMapper = new XmlMapper();
        xmlMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        PublshInformation jacksonPublish = xmlMapper.readValue(xmlStreamReader, PublshInformation.class);
        System.out.println(jacksonPublish);

        xmlMapper.writerWithDefaultPrettyPrinter().writeValue(System.out, jacksonPublish);

    }
}

这将产生结果:

java.io.BufferedInputStream@73a28541
PublshInformation(Publish_Date=null, recordCount=null)
<PublshInformation>
  <recordCount/>
  <publish_Date/>
</PublshInformation>

上面的代码甚至可以使用纯 JAXB。如果您取消注释,那么它将使用 JAXB 来完成。我用的是最新的jackson-dataformat-xml 2.12.4

  1. 将您的字段设为私有。
  2. 使用最新版本的 Jackson
  3. 确保您的输入未被使用,之前可能会变为空。

我相信这应该有效。


推荐阅读