How to unmarshall XML response with restTemplate and jax2BMarshaller:
After spending a few hours and looking around, I was able to fix this issue:
First thing I learned: Spring 3.0 and jaxb unmarshaller have support for handling custom namespaces. Except, we should be able to specify it in the right way.
Here's what worked for me:
For Web Service of type:
Code:
<responseList xmlns="http://example.com/xmlns" attr1="val">
<response attr="val">
<element1>val</element1>
....
</response>
</responseList>
Create an ApplicationContext File. I called mine appContext and placed it under my project package where all my classes exist.
appContext.xml
Code:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="restTemplate" class="org.springframework.web.client.RestTemplate">
<property name="messageConverters">
<list>
<bean class="org.springframework.http.converter.xml.MarshallingHttpMessageConverter">
<property name="marshaller" ref="jaxbMarshaller"/>
<property name="unmarshaller" ref="jaxbMarshaller"/>
</bean>
</list>
</property>
</bean>
<bean id="jaxbMarshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller">
<property name="classesToBeBound">
<list>
<value>org.springframework.webflow.samples.booking.ResponseList</value>
<value>org.springframework.webflow.samples.booking.Response</value>
</list>
</property>
<!-- Optional Schema Declaration<property name="schema" value="schema.xsd"/> -->
</bean>
</beans>
Now, you need to create the classes you will need for binding
ResponseList.java
Code:
@XmlRootElement(name = "responseList", namespace = "http://example.com/xmlns")
@XmlAccessorType(XmlAccessType.FIELD)
public class ResponseList {
@XmlAttribute
private String attr1;
@XmlElement(name = "response", namespace = "http://example.com/xmlns")
private List<Response> response;
....
Response.java
Code:
public class Response {
@XmlAttribute
private String attr;
private String element1;
/**
* Add @XmlElement on the getter method for the elements
*/
@XmlElement(name = "element1", namespace = "http://example.com/xmlns")
public String getElement1() {
return element1;
}
Now, for the final logic to consume the webservice:
Code:
try {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("appContext.xml",
"CurrentClassHoldingThisFn".class);
RestTemplate restTemplate = applicationContext.getBean("restTemplate", RestTemplate.class);
String url = "http://example.com/getResponseList";
ResponseList rList = (ResponseList) restTemplate.getForObject(url, responseList.class);
/** Your code for parsing for the response object goes here **/
}
And, that's it. Hope this helps!!