Content type negotiation helps your app decide what format to send data in, like JSON or XML, based on what the user or client wants.
Content type negotiation in Spring Boot
In Spring Boot, content type negotiation is often handled automatically by using @RestController and returning objects. You can also configure it with: @Configuration public class WebConfig implements WebMvcConfigurer { @Override public void configureContentNegotiation(ContentNegotiationConfigurer configurer) { configurer.favorParameter(true) .parameterName("format") .ignoreAcceptHeader(false) .defaultContentType(MediaType.APPLICATION_JSON) .mediaType("json", MediaType.APPLICATION_JSON) .mediaType("xml", MediaType.APPLICATION_XML); } }
Spring Boot automatically supports JSON if Jackson is on the classpath.
You can customize content negotiation by overriding configureContentNegotiation in a WebMvcConfigurer.
@RestController public class MyController { @GetMapping("/data") public MyData getData() { return new MyData("Hello", 123); } }
@Configuration public class WebConfig implements WebMvcConfigurer { @Override public void configureContentNegotiation(ContentNegotiationConfigurer configurer) { configurer.favorParameter(true) .parameterName("format") .ignoreAcceptHeader(true) .defaultContentType(MediaType.APPLICATION_JSON) .mediaType("json", MediaType.APPLICATION_JSON) .mediaType("xml", MediaType.APPLICATION_XML); } }
@RestController public class MyController { @GetMapping(value = "/data", produces = MediaType.APPLICATION_XML_VALUE) public MyData getDataXml() { return new MyData("Hello", 123); } }
This Spring Boot app has one endpoint '/data' that returns a simple record. The config allows clients to request JSON or XML by adding '?format=json' or '?format=xml' to the URL or by setting the Accept header.
package com.example.demo; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.annotation.Configuration; import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @SpringBootApplication public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } } @Configuration class WebConfig implements WebMvcConfigurer { @Override public void configureContentNegotiation(ContentNegotiationConfigurer configurer) { configurer.favorParameter(true) .parameterName("format") .ignoreAcceptHeader(false) .defaultContentType(MediaType.APPLICATION_JSON) .mediaType("json", MediaType.APPLICATION_JSON) .mediaType("xml", MediaType.APPLICATION_XML); } } @RestController class MyController { record MyData(String message, int number) {} @GetMapping("/data") public MyData getData() { return new MyData("Hello, world!", 42); } }
Content negotiation uses HTTP headers like Accept or URL parameters to decide response format.
Always test your API with different Accept headers or URL parameters to see the format change.
Make sure you have the right libraries (like Jackson for JSON, JAXB for XML) in your project.
Content type negotiation lets your app send data in the format the client wants.
Spring Boot supports this automatically but you can customize it with WebMvcConfigurer.
You can use URL parameters or HTTP headers to control the response format.
Practice
Solution
Step 1: Understand content type negotiation concept
Content type negotiation allows the server to send data in different formats like JSON or XML based on what the client requests.Step 2: Identify the main purpose in Spring Boot
Spring Boot uses content type negotiation to automatically choose the response format that matches the client's preference.Final Answer:
To send data in the format the client prefers -> Option AQuick Check:
Content type negotiation = send preferred format [OK]
- Confusing content type negotiation with security features
- Thinking it speeds up database queries
- Assuming it manages user sessions
Solution
Step 1: Understand 'produces' vs 'consumes'
'produces' defines the response content type; 'consumes' defines the request content type.Step 2: Identify correct annotation for JSON response
@GetMapping with produces = "application/json" tells Spring Boot to send JSON data in response.Final Answer:
@GetMapping(value = "/data", produces = "application/json") -> Option BQuick Check:
produces = JSON means response is JSON [OK]
- Mixing 'consumes' with response content type
- Using wrong HTTP method annotation
- Setting produces to unrelated content types
@GetMapping(value = "/info", produces = {"application/json", "application/xml"})
public Data getInfo() {
return new Data("Spring", 5);
}
What will happen if the client sends an HTTP Accept header with value application/xml?Solution
Step 1: Check the produces attribute
The method supports both JSON and XML response formats as per the produces array.Step 2: Match client Accept header with produces
The client requests 'application/xml', which is supported, so Spring Boot will respond with XML.Final Answer:
The server responds with XML format -> Option DQuick Check:
Accept header matches produces = XML response [OK]
- Assuming JSON is always returned
- Thinking 406 error occurs if multiple produces are set
- Ignoring the Accept header
@Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
configurer.favorParameter(true)
.parameterName("format")
.defaultContentType(MediaType.APPLICATION_JSON)
.mediaType("xml", MediaType.APPLICATION_XML)
.mediaType("json", MediaType.APPLICATION_JSON);
}
What is the likely problem if a client requests /api/data?format=txt?Solution
Step 1: Analyze configured media types
Only 'json' and 'xml' are mapped to media types; 'txt' is not recognized.Step 2: Check default content type behavior
If the parameter value is unknown, Spring Boot falls back to the default content type, which is JSON here.Final Answer:
The server will respond with JSON as default -> Option CQuick Check:
Unknown format uses default JSON [OK]
- Expecting an error for unknown format
- Assuming XML is default
- Thinking plain text is sent automatically
?type= instead of the default ?format=. Which code snippet correctly achieves this?Solution
Step 1: Enable parameter-based content negotiation
Set favorParameter(true) to allow URL parameter control.Step 2: Change parameter name to 'type'
Use parameterName("type") to listen for '?type=' instead of default '?format='.Step 3: Set default content type to JSON
defaultContentType(MediaType.APPLICATION_JSON) ensures JSON if no parameter is given.Final Answer:
configurer.favorParameter(true).parameterName("type").defaultContentType(MediaType.APPLICATION_JSON); -> Option AQuick Check:
favorParameter + parameterName = custom URL param [OK]
- Disabling favorParameter disables URL param negotiation
- Using wrong parameter name
- Setting inappropriate default content type
Ready to prove it?
Pass the test and this pattern moves unknown
