使用jackson-dataformat-xml自定义根元素进行XML反序列化?

6

我一直在使用Jackson进行JSON序列化/反序列化,并且已经成功地使用了它。现在,我也想使用它来进行XML序列化/反序列化,使用的是它的jackson-dataformat-xml-2.3.0.jar包。

我使用了

objectmapper.reader(Student.class).withRootName("prefix:student").readValue(jsonString)

将我的JSON(具有前缀的根名称)反序列化为Student类,这很成功。

现在,我正在尝试将具有前缀的XML字符串反序列化为Student

XML:

<prefix:student>
  <name>
    Jack Jones
  </name>
  <id>1</id>
</prefix:student>

我的POJO:

    @XmlAccessorType(XmlAccessType.FIELD)
    @XmlType(name = "", propOrder = {
        "name",
        "id",
        ....
    })
    @XmlRootElement(name = "student")
    public class Student
    {

        protected String name;
        BigInteger id;  
..........................
    }

我使用 jackson-dataformat-xml 中的 XmlMapper 进行反序列化,代码如下:

xmlMapper.reader(Student.class).withRootName("prefix:student").readValue(xmlString)

我遇到了以下异常:
java.io.IOException: com.ctc.wstx.exc.WstxParsingException: Undeclared namespace prefix "prefix"
 at [row,col {unknown-source}]: [1,9]
    at com.fasterxml.jackson.dataformat.xml.util.StaxUtil.throwXmlAsIOException(StaxUtil.java:24)
    at com.fasterxml.jackson.dataformat.xml.XmlFactory._createParser(XmlFactory.java:473)
    at com.fasterxml.jackson.dataformat.xml.XmlFactory._createParser(XmlFactory.java:26)
    at com.fasterxml.jackson.core.JsonFactory.createParser(JsonFactory.java:844)
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2091)

Caused by: com.ctc.wstx.exc.WstxParsingException: Undeclared namespace prefix "prefix"
 at [row,col {unknown-source}]: [1,9]
    at com.ctc.wstx.sr.StreamScanner.constructWfcException(StreamScanner.java:606)
    at com.ctc.wstx.sr.StreamScanner.throwParseError(StreamScanner.java:479)
    at com.ctc.wstx.sr.InputElementStack.resolveAndValidateElement(InputElementStack.java:507)
    at com.ctc.wstx.sr.BasicStreamReader.handleStartElem(BasicStreamReader.java:2977)
    at com.ctc.wstx.sr.BasicStreamReader.handleRootElem(BasicStreamReader.java:2098)
    at com.ctc.wstx.sr.BasicStreamReader.nextFromProlog(BasicStreamReader.java:2078)
    at com.ctc.wstx.sr.BasicStreamReader.next(BasicStreamReader.java:1134)
    at com.fasterxml.jackson.dataformat.xml.XmlFactory._initializeXmlReader(XmlFactory.java:581)
    at com.fasterxml.jackson.dataformat.xml.XmlFactory._createParser(XmlFactory.java:471)
    ... 6 more

我需要为自定义根名称的XML反序列化做些什么?

你的根元素名称不是 student,就像这里定义的一样:@XmlRootElement(name = "student") - My-Name-Is
@My-Name-Is:我已经编辑了这个问题。基本上,我有一个命名空间前缀在根名称内。因此,根名称“student”变成了“prefix:student”。 - Siddharth Trikha
2个回答

6

尝试配置XmlMapper以忽略命名空间:

XMLInputFactory input = new WstxInputFactory();
input.setProperty(XMLInputFactory.IS_NAMESPACE_AWARE, Boolean.FALSE);
XmlMapper xmlMapper = new XmlMapper(new XmlFactory(input, new WstxOutputFactory()));

另外,您可能需要将您的@XmlRootElement(name= "student")更改为@XmlRootElement(name= "prefix:student") 编辑:
正如StaxMan所说,您的问题是由于使用了未声明的前缀而引起的。
这可以通过您提供给我们的日志推断出来(第1行和第9行 => 未声明的命名空间前缀"prefix")。
我原本以为您不能修改XML字符串。
但如果您可以的话,StaxMan的解决方案更加简洁,您应该添加名称空间声明,而不是禁用解析器名称空间验证:
<prefix:student xmlns:prefix="http://www.somenamespace.org">
  <name>
    Jack Jones
  </name>
  <id>1</id>
</prefix:student>

2
你的问题是XML输入无效,因为它缺少prefix的命名空间声明:如果启用了命名空间处理(大多数现代XML解析器都启用了),Jackson XML模块将无法处理该问题。
但是根据其他答案,通常可以配置底层XML解析器以禁用命名空间处理,在这种情况下,整个元素名称只被视为“本地名称”的一部分,不会保留任何命名空间信息。
请确保使用WoodstoxAalto Stax解析器:我认为JDK中的一个不支持无命名空间模式。

我遇到了同样的问题,我使用了JacksonXmlModuleXmlMapper序列化类,并使用@JacksonXmlProperty(localName = "namespaceprefix:localname")。有没有办法在本地名称中添加命名空间前缀,以便我不会再使用Jackson XML模块时出现“未声明的命名空间前缀”的错误! - Raghu DV

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接