Thank you for taking the time to read.
Before asking I would like to point out that I've read as many similar posts on StackOverflow / the internet that I possibly can.
My goal is to deserialize the response from an API request into a usable java object.
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>
However, when I try to unmarshal this into a POJO, the mapping is not working as expected.
For the sake of simplicity, I am trying to capture only the first fields, id, title, and source (I have tried to capture only a single field -- id -- and I have also tried to do all fields to no avail).
Here's what the POJO looks like:
@XmlRootElement(name = "entry", namespace = "http://purl.org/atom/ns#")
@XmlAccessorType(XmlAccessType.FIELD)
public class Response {
@XmlElement(name = "id")
private String id;
@XmlElement(name = "title")
private String title;
@XmlElement(name = "source")
private String source;
public Response() {}
}
In order to check whether or not the Xml elements are captured, I'm logging the attributes, which are null:
Response{id='null', title='null', source='null'}
Feign is the HTTP client sending out the requests, and here is the client file:
@FeignClient(name="ReportSchedulerClient", url = "https://scheduler.com", configuration = FeignClientConfiguration.class)
public interface ReportSchedulerClient {
@PostMapping(value = "/webservice", consumes = "application/xml", produces = "text/xml")
Response sendJobConfigRequest(@RequestBody Request request);
}
and a simple custom config file for auth:
public class FeignClientConfiguration {
@Bean
public BasicAuthRequestInterceptor basicAuthRequestInterceptor() {
return new BasicAuthRequestInterceptor("user", "pass");
}
}
I am trying to avoid explicitly unmarshalling the file, but I have also tried to unmarshall the request explicitly using something like this:
Response response = (Response) unmarshaller.unmarshal(new StreamSource(new StringReader(response.body().toString())));
Please let me know if you have any advice, if anything is wrong with my code, or any alternative suggestions. Thanks in advance.
You need to specify the namespace
at the element level.
For example:
@XmlElement(name = "id", namespace = "http://purl.org/atom/ns#")
private String id;
To set a default namespace you can do it at the package level, creating the package-info.java file in the package folder with a content like this:
@XmlSchema(
namespace = "http://purl.org/atom/ns#",
elementFormDefault = XmlNsForm.QUALIFIED)
package your.model.package;
import javax.xml.bind.annotation.XmlNsForm;
import javax.xml.bind.annotation.XmlSchema;
Besides, as you are explicitly adding @XmlElement
to all your fields, you can remove the @XmlAccessorType(XmlAccessType.FIELD)
annotation, as it's purpose it's to map by default all fields to elements.