Results 1 to 3 of 3

Thread: How to ignore namespaces while consuming web services using restTemplate

  1. #1
    Join Date
    Mar 2012
    Posts
    8

    Default Trouble unmarshalling XML response with RestTemplate & Jaxb2Marshaller

    Hi,

    Im having difficulty with unmarshalling an XML document with a namespace url:

    XML Doc
    Code:
    <?xml version="1.0" encoding="utf-8"?>
    <videos xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:ns="http://example.com" xmlns="http://example.com/example/xmlns" attr1="val" attr2="val">
    <video>
       <element1>
       <element2>....
    </video>
    </videos>
    I have created a class for videos and its attributes as properties (annotated as @XmlRootElement for class)
    another class video for its attributes and elements.(annotated as @XmlRootElement for class)

    If I remove the namespace from the document, the unmarshalling works perfectly fine and I can read my video objects.
    However, when I include the namespace in the xml document, I get the following unmarshalling exception:

    Code:
    org.springframework.http.converter.HttpMessageNotReadableException: Could not read [class org.springframework.webflow.samples.booking.Videos]; nested exception is org.springframework.oxm.UnmarshallingFailureException: JAXB unmarshalling exception; nested exception is javax.xml.bind.UnmarshalException: unexpected element (uri:"http://localhost:8080/booking-mvc/styles/blueprint/icons/empty", local:"videos"). Expected elements are <{}credit>,<{}credits>,<{}response>,<{}video>,<{}videos>
    If I add @XmlRootElement(namespace="http://example.com/example") to videos and video class, I get a null pointer exception.

    I know Im doing something terribly wrong , but Im trying to look around and getting only more confused. Can someone please let me know what are the correct steps to follow while unmarshalling an XML doc with namespaces using restTemplate, jaxb2. I would really appreciate the help.

    if it helps, here's the application context:

    Code:
    <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.Videos</value>
       		<value>org.springframework.webflow.samples.booking.Video</value>
       		</list>
        </property>
    and this is the application code:

    Code:
    try {
    	    String url = "http://localhost:8080/booking-mvc/styles/blueprint/icons/videos.xml";
    	    Videos videoList = (Videos) restTemplate.getForObject(url, Videos.class);     
                //some processing    
    }
    Thanks in advance.
    Last edited by smurthy; Mar 29th, 2012 at 02:47 PM.

  2. #2
    Join Date
    Mar 2012
    Posts
    8

    Default

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

  3. #3
    Join Date
    Dec 2011
    Posts
    14

    Default

    I was having the exact same problem. I wasn't using the namespace attribute correctly. This worked for me. Thanks a bunch!

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •