Accessing Restful services. HTTP Message converters

When accessing to Restful services, the Spring class RestTemplate maintains a list of message converters. This list will be used to marshal objects into the request body, or unmarshalling them from the response. When instantiating the RestTemplate class, it automatically fills a list with several converters:

 
Also, the RestTemplate class may register additional message converters if it finds the required classes on the classpath:
<dependency>
    <groupId>javax.xml.bind</groupId>
    <artifactId>jaxb-api</artifactId>
    <version>2.2</version>
</dependency>
<dependency>
    <groupId>com.sun.xml.bind</groupId>
    <artifactId>jaxb-impl</artifactId>
    <version>2.2</version>
</dependency>

 

<dependency>
                  <groupId>org.codehaus.jackson</groupId>
                  <artifactId>jackson-mapper-asl</artifactId>
                  <version>1.4.2</version>
            </dependency>

 

Serving different content

 The following controller will execute three different operations that will generate xml, String and json content.
JSON content:
@RequestMapping(value="/users/{userId}", method=RequestMethod.GET)
public @ResponseBody User getUser(@PathVariable("userId") long id) {
       return userRepository.getUser(id);
}

Result: JSON. The User class can be serialized/deserialized by the Jackson object mapper.

{
name: "Xavi",
id: 1,
surname: "Padro"
}
String content:
@RequestMapping(value="/usernames/{userId}", method=RequestMethod.GET)
public @ResponseBody String getUsername(@PathVariable("userId") long id) {
       StringBuilder result = new StringBuilder();
       User user = userRepository.getUser(id);
       returnresult.append(user.getName()).append(" ").append(user.getSurname()).toString();
}

Result: String. The returned object is a String.

Xavi Padro
XML content:
@RequestMapping(value="/cars/{carId}", method=RequestMethod.GET)
public @ResponseBody Car getCar(@PathVariable("carId") long id) {
       return carRepository.getCar(id);
}

 

Result: XML. The Car class is annotated with @XmlRootElement
<car>
<brand>Ferrari</brand>
<id>1</id>
<model>GTO</model>
</car>
You can also specify the converters that will be used by the RestTemplate. You could, for example, only instantiate the needed converters or register your own message converter:
private RestTemplate restTemplate = new RestTemplate();

@Before
public void setup() {
List<HttpMessageConverter<?>> converters = new ArrayList<HttpMessageConverter<?>>();
       converters.add(newStringHttpMessageConverter());
       converters.add(newJaxb2RootElementHttpMessageConverter());
       converters.add(newMappingJacksonHttpMessageConverter());
       restTemplate.setMessageConverters(converters);
}

 

Just take into account that if you serve both json and xml content, you must add the jaxb2 converter before the json converter. Otherwise, regardless of the presence of xml annotations, the xml method response will be handled by the jackson converter and be converted to json. That happens because the HttpEntityRequestCallback inner class of the RestTemplate will use the first converter that can write/read the content.

 

You can get the source code from Github repository.