How to Make a Spring Boot Controller Return JSON, XML, and YAML Dynamically
Learn how to configure Spring Boot 3.2.5 to let a single controller endpoint dynamically produce JSON, XML, or custom YAML responses using Accept headers, request parameters, path extensions, and custom HttpMessageConverters, with step‑by‑step code examples and necessary Maven dependencies.
Environment: SpringBoot 3.2.5
1. Introduction
In Spring Boot, a Controller handles HTTP requests and returns responses. Spring provides several matching strategies to define the relationship between requests and handler methods.
Typical RESTful API design guidelines include:
Use nouns to represent resources, e.g. /users , /products .
Use HTTP methods (GET, POST, PUT, DELETE, etc.) to represent operations on resources.
Use path variables for subsets or specific instances, e.g. /users/{userId} .
Use query parameters for filtering or sorting, e.g. /users?name=John&sort=asc .
These conventions keep APIs consistent and readable for front‑end developers.
Although JSON is the default response format, projects may require XML or custom formats. Spring MVC supports JSON, XML, and custom formats out of the box.
2. Practical Examples
2.1 Request Header
Use the Accept header to specify the desired response format.
<code>@RestController
@RequestMapping("/returnformat")
public class ReturnFormatController {
@GetMapping("")
public User format() {
User user = new User(666L, "张三");
return user;
}
}
</code>Send a request with the Accept header set to application/xml in Postman.
2.2 Request Parameter
Enable parameter‑based content negotiation in application.yml :
<code>spring:
mvc:
contentnegotiation:
favor-parameter: true
</code>Then request /returnformat?format=xml to get XML. The parameter name can be changed:
<code>spring:
mvc:
contentnegotiation:
favor-parameter: true
parameter-name: fmt
</code>2.3 Path Extension (Deprecated)
Path‑extension negotiation is discouraged. For Spring 5.3 and earlier it can be enabled with:
<code>spring:
mvc:
contentnegotiation:
favor-path-extension: true
</code>From Spring 6.0 onward you must implement WebMvcConfigurer :
<code>@Configuration
public class FavorPathConfigurer implements WebMvcConfigurer {
@Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
configurer.favorPathExtension(true);
}
}
</code>Controller example:
<code>@RestController
@RequestMapping("/favors")
public class FavorPathController {
@GetMapping("/p.*")
public User favor() {
return new User(1L, "张三");
}
}
</code>2.4 Custom Format (YAML)
Implement a custom HttpMessageConverter to output YAML:
<code>public class YamlHttpMessageConverter implements HttpMessageConverter<Object> {
@Override
public boolean canWrite(Class<?> clazz, MediaType mediaType) {
return User.class.isAssignableFrom(clazz);
}
@Override
public List<MediaType> getSupportedMediaTypes() {
return List.of(new MediaType("application", "yaml"));
}
@Override
public void write(Object t, MediaType contentType, HttpOutputMessage outputMessage)
throws IOException, HttpMessageNotWritableException {
StreamUtils.copy(new org.yaml.snakeyaml.Yaml().dump(t), StandardCharsets.UTF_8, outputMessage.getBody());
}
}
</code>Add the media type to configuration:
<code>spring:
mvc:
contentnegotiation:
media-types:
yaml: application/yaml
</code>After registration, the endpoint can return YAML, which can be deserialized back to a User object.
These steps enable a Spring Boot controller to return JSON, XML, or any custom format such as YAML.
Spring Full-Stack Practical Cases
Full-stack Java development with Vue 2/3 front-end suite; hands-on examples and source code analysis for Spring, Spring Boot 2/3, and Spring Cloud.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.