Spring Boot decides which format (JSON, XML, Protobuf, etc.) to use when handling a request based on the configuration for content negotiation.
1. Content Negotiation in Spring Boot
Spring Boot decides how to serialize and deserialize request/response bodies using HttpMessageConverters. These converters are automatically registered based on the libraries in the classpath.
2. How Does Spring Boot Choose the Response Format?
Spring Boot determines the response format in this order:
- Request
Accept
Header- If the client sends
Accept: application/json
, Spring returns JSON. - If the client sends
Accept: application/xml
, Spring returns XML. - If the client sends
Accept: application/x-protobuf
, Spring returns Protocol Buffers (if Protobuf support is configured).
- If the client sends
- Produces Annotation on Controller Methods
@GetMapping(value = "/user", produces = "application/xml") public User getUser() { return new User("John", "Doe"); }
- This forces Spring to always return XML for this endpoint.
- Default Fallback
- If no
Accept
header is provided, Spring defaults to JSON (if Jackson is on the classpath).
- If no
3. How to Enable Different Formats?
JSON (Default in Spring Boot)
- Uses Jackson (
com.fasterxml.jackson.databind.ObjectMapper
). - Automatically configured if
spring-boot-starter-web
is included.
XML Support
- Add the dependency for
jackson-dataformat-xml
:<dependency> <groupId>com.fasterxml.jackson.dataformat</groupId> <artifactId>jackson-dataformat-xml</artifactId> </dependency>
- Annotate your model with
@XmlRootElement
(optional for Jackson).@XmlRootElement public class User { private String firstName; private String lastName; }
- Spring will return XML if
Accept: application/xml
is present.
Protocol Buffers (Protobuf)
- Add the dependency:
<dependency> <groupId>com.google.protobuf</groupId> <artifactId>protobuf-java</artifactId> </dependency>
- Define a
.proto
file:syntax = "proto3"; message User { string first_name = 1; string last_name = 2; }
- Generate Java classes using the Protobuf compiler.
- Use
ProtobufHttpMessageConverter
in Spring Boot:@Bean public ProtobufHttpMessageConverter protobufHttpMessageConverter() { return new ProtobufHttpMessageConverter(); }
4. Customizing output format
Spring Boot uses ContentNegotiationConfigurer
to configure format selection manually.
Example: Enable XML and Protobuf globally:
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
configurer
.favorParameter(true) // Enable format selection via URL parameter (e.g., ?format=xml)
.parameterName("format")
.defaultContentType(MediaType.APPLICATION_JSON)
.mediaType("json", MediaType.APPLICATION_JSON)
.mediaType("xml", MediaType.APPLICATION_XML)
.mediaType("proto", MediaType.APPLICATION_OCTET_STREAM);
}
}
Now, clients can request different formats using:
/user?format=json
→ JSON/user?format=xml
→ XML/user?format=proto
→ Protobuf
Conclusion
Spring Boot decides how to map controllers based on:
- The Accept header sent by the client.
- The
produces
attribute on the controller method. - The default behavior, which is JSON unless overridden.
- The available
HttpMessageConverters
based on dependencies in the classpath.
For More Spring Boot content, checl out here: https://programtom.com/dev/category/software-development/spring/