In this post, we will cover Spring HttpMessageConverters.We will discuss how to configure and create custom converters in Spring MVC.
Introduction
To put in laymen terms, message converters are to marshal and unmarshal object in a different format (like JSON, XML etc.).Spring MVC uses the HttpMessageConverter interface to convert HTTP requests and responses.Spring MVC provides some out of the box default configurations for the converters.
1. MVC Configurations
To enable support for the Http message converters with the Spring MVC, we need to enable Spring MVC support either using Java config or the traditional XML based configuration.
@Configuration
@EnableWebMvc
public class WebMVCConfig implements WebMvcConfigurer {
// Implement configuration methods...
}
For the XML, used <mvc:annotation-driven>
/p>
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
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
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<mvc:annotation-driven/>
</beans>
Above configurations help Spring MVC in
- Register and enable a number of core/infrastructure beans (e.g HandlerMapper, ViewResolver, ThemeResolver, LocalResolver etc. Beans).
- Configure and enable different message converter (e.g JSOn, XML etc.)
1. The Default Message Converters
By default, the following HttpMessageConverters
are loaded by Spring
ByteArrayHttpMessageConverter
– that can read and write byte arraysResourceHttpMessageConverter
-can read/writeResources
and supports byte range requestSourceHttpMessageConverter
– can read and writeSource
objects.StringHttpMessageConverter
– read and write stringsFormHttpMessageConverter
– read and write ‘normal’ HTML forms .
Spring provides other sets of message converters, but they will only be registered when the related library is in the classpath, here are some of the popular converters from the list
MappingJacksonHttpMessageConverter
– For converting JSONJaxb2RootElementHttpMessageConverter
– To convert Java objects to/from XMLMappingJackson2HttpMessageConverter
– To convert JSON.
Read HttpMessageConverter for more detail.
2. Spring MVC Content Negotiation
Http message converters work in close relation with the content negotiation.Before getting into more details, let’s discuss how content negotiation works in Spring.
- With the new request, Spring use “Accept” header to find what type of representation required on the client side.
Content-Type:
This header tells about the media type of the body of the request.- This header helps server or the client to select the correct approach to handle and eventually parse the data by selecting right converter.
- Based on this, Spring will try to find a converter which can handle and parse this request.
Let’s take a simple example to understand this more clearly.
- Client or browser send GET request to /customer resource with Accept header as application/json.
- Based on the Accept header, Spring will choose appropriate converter to parse the incoming request (In our example, it will choose JSON message converter).
- If no right converter is found, Spring will throw the exception.
Read Content Negotiation for more detail.Let’s take a deeper look at @RequestBody
and @ResponseBody
annotation to see how they work with Http message converters the Spring.
2.1 @RequestBody Annotation
Annotation indicating a method parameter should be bound to the body of the web request. It works with “Content-Type” header passed by the client.Spring use this header value to find the right converter.
@PostMapping(value = "/greeting")
public @ResponseBody void greeting(@RequestBody Customer customer){
//create customer
}
Use any REST client or curl to execute code, we will get 200 OK response.
curl -i -X POST -H "Content-Type: application/json" -d '{"id":"14","name":"Java Dev Journal"}' http://localhost:8080/greeting
HTTP/1.1 200
Content-Length: 0
Date: Tue, 27 Mar 2018 04:28:23 GMT
2.2 @ResponseBody Annotation
@ResponseBody
is used on the argument of a Controller method.This annotation tells Spring that the return value of the method serialized directly to the body of the HTTP Response.
@ResponseBody
annotation work with “Accept” header passed by the client to decide what type of representation required on the client side.
@GetMapping(value = "/greeting")
public @ResponseBody Customer greeting(){
Customer customer = new Customer(14, "Java Dev Journal");
return customer;
}
Output
curl --header "Accept: application/json" http://localhost:8080/greeting
{
"id":14,
"name":"Java Dev Journal"
}
3. Custom Converter
To create a custom message converter in Spring, we should overrideconfigureMessageConverters()
by extending WebMvcConfigurerAdapter
class.
@Configuration
public class WebConfig implements configureMessageConverters {
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
MarshallingHttpMessageConverter xmlConverter =new MarshallingHttpMessageConverter();
XStreamMarshaller xstream = new XStreamMarshaller();
xmlConverter.setMarshaller(xstream);
xmlConverter.setUnmarshaller(xstream);
converters.add(xmlConverter);
}
}
[pullquote align=”normal”]We need Xtream library in the classpath [/pullquote]
Let’s check what we did in this example
- We are overriding configureMessageConverters() method under configureMessageConverters to define our own custom converter.
- Created instance of MarshallingHttpMessageConverter to read and write XML using Spring’s Marshaller and Unmarshaller.
- We created XStreamMarshaller instance and set Marshaller and Unmarshaller for the MarshallingHttpMessageConverter.
- Finally, we added this converter to the list of converters.
Let’s see our custom converter in action
curl --header "Accept: application/json" http://localhost:8080/greeting
curl --header "Accept: application/xml" http://localhost:8080/greeting
Output
{
"id":14,
"name":"Java Dev Journal"
}
<?xml version="1.0" encoding="UTF-8"?>
<customer>
<id>14</id>
<name>Java Dev Journal</name>
</customer>
Summary
In this post, we will cover Spring HttpMessageConverters.We discussed how content negotiation works and how to create and register your custom converter in Spring.