Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
228 views
in Technique[技术] by (71.8m points)

How can I unmarshal an XML response to 2 java objects using JAXB when there are 2 namespaces?

Thank you for taking the time to read.

My goal is to deserialize the response from an API request into 2 usable java objects.

I am sending an POST request to an endpoint to create a job in our schedule. The job is created successfully and the following XML is returned in the body:

<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>

When I attempt to only capture the elements id, title, and source the data is captured successfully. The problem is when I introduce the child object, which attempts to capture the data in the tes:result element.

Here's what the parent POJO looks like:

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

    private String id;

    private String title;

    private String source;

    ResponseDetails result;

    public Response() {}
}

and here is the child object:

@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;
}

Finally, here is the package-info.java file I am using:

@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;

Any ideas are greatly appreciated. Thanks.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

The problem is: Your Java code doesn't correctly specify the namespaces corresponding to the inner XML element

<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>

The <tes:result> XML element has the namespace "http://www.auto-schedule.com/client". The namespace prefix tes: itself is irrelevant for Java. (XML namespace prefixes were invented only for better readability of the XML code.) Therefore in your Response class, instead of just writing

ResponseDetails result;

you need to write

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

See also the javadoc of XmlElement.namespace.

Also all the XML sub-elements within the <tes:result> are specified with this namespace "http://www.auto-schedule.com/client". Therefore, also inside your ResponseDetails you have to correct the namespace stuff. For example, instead of

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

you need to write

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

You may also omit the name = "message" and simply write

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

because JAXB picks up this name from your Java property name message.

And similar for all the other properties in this class.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...