October 21, 2014
Hot Topics:
RSS RSS feed Download our iPhone app

Get RESTful with Spring 3.0

  • December 23, 2009
  • By Michael Pilone
  • Send Email »
  • More Articles »

The Simple XML Endpoint

The first logical step in the transition from SOAP web services to REST-like services is to introduce a simple XML endpoint that can leverage the same XML messages and domain objects defined for the web services, but without the SOAP envelope, fault complexity, or WSDL. A new MVC annotation in Spring 3.0, @RequestBody, allows a controller (the C in MVC) to receive the body of a request as a parameter. The best part is that Spring will perform the same JAXB unmarshalling you saw previously with Spring-WS, making it simple to reuse the same domain objects generated from the web service's XML schema.

To use the new annotations, introduce a WeatherRestEndpoint and annotate it with the @Controller annotation, which tells Spring MVC that the DispatcherServlet should use this class as a controller to handle requests. You will implement the same three methods implemented in the web service endpoint in this endpoint to support the three API methods discussed previously. However, this time, you will map each method to a specific request URI using the @RequestMapping annotation. To keep things simple and consistent, the requests map to a URI with the same name as the original web service operation name, while in a pure REST endpoint, the mapping may point to a specific resource. For example, you map the convertTemperature method with this annotation:

@RequestMapping(value = "/convertTemperature", method = RequestMethod.POST)
public ModelAndView convertTemperature(@RequestBody ConvertTemperature request)
{	
 ...
}

This code listing also demonstrates how you use the new @RequestBody annotation to get the actual content of the request. Again, using reflection and JAXB, Spring can automatically unmarshal the request XML into the generated domain object. Listing 7 shows the complete WeatherRestEndpoint, which again delegates to the same WeatherService business-tier object to perform all the business logic. Figure 2 shows the implemented flow at this point.


Figure 2. The Message Flow for an XML Message Through Spring, JAXB, and the Service Endpoint:
The endpoint simply delegates all requests to the common business logic backend services.

Now, the endpoint needs to return the business service response value to the caller in an XML response message. To accomplish this, you use a MarshallingView (the view in MVC), which delegates to JAXB to marshal the response object (the model in MVC) into XML and returns it to the caller. The MarshallingView is another Spring 3.0 feature that uses the new Spring object to XML mapping (OXM) support to simply invoke JAXB and makes for one fewer class the developer needs to worry about.

Now that the implementation of the endpoint is complete, everything needs to be linked together in the web.xml servlet definition and the WeatherRestXmlService-servlet.xml Spring bean configuration file. The servlet definition uses the classic Spring MVC DispatcherServlet, so there isn't much new to discuss (see Listing 8). The REST-like functionality comes mostly from the configuration of the new Spring 3.0 MarshallingHttpMessageConverter as it is added to the AnnotationMethodHandlerAdapter to perform the JAXB unmarshalling of HTTP requests, as well as the MarshallingView to marshal the HTTP responses.

<!--
    Maps incoming requests to the appropriate controller based on the annotations on
    the controller methods.
  -->
  <bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping"/>
  <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
    <property name="messageConverters">
      <list>
        <bean class="org.springframework.http.converter.xml.MarshallingHttpMessageConverter">
          <property name="unmarshaller" ref="restXmlMarshaller"/>
        </bean>
      </list>
    </property>
  </bean>
  
  <!--
    View for rendering the XML for result objects using JAXB annotations.
  -->
  <bean id="restXmlMarshalView" class="org.springframework.web.servlet.view.xml.MarshallingView">
    <property name="marshaller" ref="restXmlMarshaller"/>
  </bean>

You can see the full Spring servlet bean configuration in Listing 9. To test the new functionally, deploy the application and post an XML message to the configured endpoint using a testing tool such as SoapUI or through a test case with the new Spring 3.0 RestTemplate:

RestTemplate restOps = new RestTemplate();
StringHttpMessageConverter stringConverter = new StringHttpMessageConverter();
List<MediaType> mediaTypes = new ArrayList<MediaType>();
mediaTypes.add(MediaType.parseMediaType("application/xml"));
stringConverter.setSupportedMediaTypes(mediaTypes);
restOps
	.setMessageConverters(new HttpMessageConverter[] { stringConverter });

String xmlRequest = "<weat:ConvertTemperature xmlns:weat=\"http://mpilone.org/weather\">\r\n"
	+ "   <weat:temperature>38</weat:temperature>\r\n"
	+ "   <weat:targetScale>celcius</weat:targetScale>\r\n"
	+ "</weat:ConvertTemperature>";

String xmlResponse = restOps.postForObject(
	"http://localhost:8080/weather/xml/convertTemperature", xmlRequest,
	String.class);
System.out.println(xmlResponse);




Page 2 of 3



Comment and Contribute

 


(Maximum characters: 1200). You have characters left.

 

 


Sitemap | Contact Us

Rocket Fuel