首页 > 解决方案 > 当有 2 个命名空间时,如何使用 JAXB 解组对 2 个 java 对象的 XML 响应?

问题描述

感谢您花时间阅读。

我的目标是将 API 请求的响应反序列化为 2 个可用的 java 对象。

我正在向端点发送一个 POST 请求,以在我们的计划中创建一个作业。作业创建成功,正文中返回以下 XML:

<entry xmlns="http://purl.org/atom/ns#">
    <id>0</id>
    <title>Job has been created.</title>
    <source>com.tidalsoft.framework.rpc.Result</source>
    <tes:result xmlns:tes="http://www.auto-schedule.com/client">
        <tes:message>Job has been created.</tes:message>
        <tes:objectid>42320</tes:objectid>
        <tes:id>0</tes:id>
        <tes:operation>CREATE</tes:operation>
        <tes:ok>true</tes:ok>
        <tes:objectname>Job</tes:objectname>
    </tes:result>
</entry>

当我尝试仅捕获元素idtitlesource时,数据被成功捕获。问题是当我引入子对象时,它试图捕获tes:result元素中的数据。

这是父 POJO 的样子:

@XmlRootElement(name = "entry")
@XmlAccessorType(XmlAccessType.FIELD)
public class Response {

    private String id;

    private String title;

    private String source;

    ResponseDetails result;

    public Response() {}
}

这是子对象:

@XmlAccessorType(XmlAccessType.FIELD)
public class ResponseDetails {

    @XmlElement(name = "tes:message")
    String message;
    
    @XmlElement(name = "tes:objectid")
    String objectid;

    @XmlElement(name = "tes:operation")
    String operation;

    @XmlElement(name = "tes:ok")
    String ok;

    @XmlElement(name = "tes:objectname")
    String objectname;
}

最后,这是我正在使用的 package-info.java 文件:

@XmlSchema(
        namespace = "http://purl.org/atom/ns#",
        elementFormDefault = XmlNsForm.QUALIFIED)
package com.netspend.raven.tidal.request.response;

import javax.xml.bind.annotation.XmlNsForm;
import javax.xml.bind.annotation.XmlSchema;

任何想法都非常感谢。谢谢。

标签: javaxmlxmlhttprequestjaxbfeign

解决方案


问题是:您的 Java 代码没有正确指定对应于内部 XML 元素的命名空间

<tes:result xmlns:tes="http://www.auto-schedule.com/client">
    <tes:message>Job has been created.</tes:message>
    <tes:objectid>42320</tes:objectid>
    <tes:id>0</tes:id>
    <tes:operation>CREATE</tes:operation>
    <tes:ok>true</tes:ok>
    <tes:objectname>Job</tes:objectname>
</tes:result>

<tes:result>XML 元素具有命名空间"http://www.auto-schedule.com/client"。命名空间前缀tes:本身与 Java 无关。(发明 XML 命名空间前缀只是为了提高 XML 代码的可读性。)因此,在您的Response类中,而不是仅仅编写

ResponseDetails result;

你需要写

@XmlElement(namespace = "http://www.auto-schedule.com/client")
ResponseDetails result;

另请参见XmlElement.namespace.

此外, 中的所有 XML 子元素<tes:result>都使用此命名空间指定"http://www.auto-schedule.com/client"。因此,在你的内部你ResponseDetails也必须更正命名空间的东西。例如,而不是

@XmlElement(name = "tes:message")
String message;

你需要写

@XmlElement(name = "message", namespace = "http://www.auto-schedule.com/client")
String message;

你也可以省略name = "message"并简单地写

@XmlElement(namespace = "http://www.auto-schedule.com/client")
String message;

因为 JAXB 从您的 Java 属性名称中获取此名称message

与此类中的所有其他属性类似。


推荐阅读