In web application development, it is imperative to possess the capability to manage and define the Content-Type response header. The Content-Type header informs the client about the format of the data being sent in the response body. In this post, we'll explore various approaches to manage the Content-Type response header in a Spring Boot application. We'll cover examples of using @RequestMapping, ResponseEntity and ContentNegotiationConfigurer to control the Content-Type header effectively.
The @RequestMapping annotation is commonly used to map HTTP requests to controller methods in Spring Boot applications. By specifying the produces attribute, you can control the Content-Type response headers for a specific endpoint. Let's take an example as below.
As you can see, in apis above, we are supporting produces a response with a application/json Content-Type or application/xml Content-Type base on the Accept header of the request, if there is no Accept header in the request then the first value Content-Type will be choose to response as default, in this case it is application/json.
Now, let's start the Spring Boot application and use postman to call 2 apis without Accept header. You will receive results as below.
For the first api, we configure MediaType.APPLICATION_JSON_VALUE as the first value, so we will receive the response with application/json as default.
Then for the second api, we configure MediaType.APPLICATION_XML_VALUE as the first value, so we will receive the response with application/xml as default.
The ResponseEntity class gives us fine-grained control over the response, including the Content-Type header. This is particularly useful when you need to customize not only the Content-Type but also other response aspects. Let's take an example as below.
So if you into the api /v1/customers/{id} then you can see we will create an HttpHeaders and then we can set any Content-Type that we want. In this example we will set application/xml.
Now, although you set the Accept is application/json in the request header, but we will always receive the Content-Type as application/xml.
The ContentNegotiationConfigurer provides a more centralized approach to configure content negotiation for our Spring Boot application. This allows us to define global rules for handling Content-Type headers. So this usually used for setting the default response Content-Type header if we don't use RequestMapping or ResponseEntity for setting Content-Type. So let's create WebMvcConfig.java as below.
With this configuration, the default Content-Type for responses in the application will be application/xml. We can further customize this behavior based on request parameters or headers.
Now, let's remove all setting Content-Type with RequestMapping or ResponseEntity in the CustomerController.java as below.
Now, let's use Postman to test, you will see all response Content-Type is application/xml.
Then now, if we set the Accept header in the request or set Content-Type with RequestMapping or ResponseEntity in the CustomerController.java then we can see all these setting will have higher priority than using ContentNegotiationConfigurer.
Controller Method Annotations: The @GetMapping, @PostMapping, @RequestMapping and other mapping annotations with produces attribute have the highest priority.
Explicitly Set Content-Type in ResponseEntity: This method has higher precedence over global settings but lower than the produces attribute in controller annotations.
ContentNegotiationConfigurer: The global content negotiation settings provide default values and fallbacks when no specific Content-Type is specified at the controller level.