Skip to content

Commit f61ac29

Browse files
committed
Document HttpMessageConverters detection changes
This commit updates the reference documentation to better reflect changes applied in gh-48310. As of Spring Boot 4.0.1, `HttpMessageConverter` beans are all considered as "custom" converters and will be set ahead of the converters list in the auto-configuration support. For more specific changes, developers should contribute `ClientHttpMessageConvertersCustomizer` or `ServerHttpMessageConvertersCustomizer` beans to better reflect their intent: should the converter be configured for client, server or both? How should this converter be used? Previously, Spring Boot was relying on heuristics but they would cause issues for server-only converters, or for specific configuration that were not meant to replace the default converter for a given media type. Closes gh-48574
1 parent 2519a5d commit f61ac29

File tree

3 files changed

+65
-1
lines changed

3 files changed

+65
-1
lines changed

documentation/spring-boot-docs/src/docs/antora/modules/reference/pages/web/servlet.adoc

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,10 @@ Any javadoc:org.springframework.http.converter.HttpMessageConverter[] bean that
9898
You can also override default converters in the same way.
9999

100100
If you need to add or customize converters, you can declare one or more javadoc:org.springframework.boot.http.converter.autoconfigure.ClientHttpMessageConvertersCustomizer[] or
101-
javadoc:org.springframework.boot.http.converter.autoconfigure.ServerHttpMessageConvertersCustomizer[] as beans, as shown in the following listing:
101+
javadoc:org.springframework.boot.http.converter.autoconfigure.ServerHttpMessageConvertersCustomizer[] as beans. There, you can choose whether converter instances should be added
102+
before default ones (`addCustomConverter`) or if they should override a specific default converter (like `withJsonConverter`).
103+
104+
See the following listing for an example:
102105

103106
include-code::MyHttpMessageConvertersConfiguration[]
104107

documentation/spring-boot-docs/src/main/java/org/springframework/boot/docs/web/servlet/springmvc/messageconverters/MyHttpMessageConvertersConfiguration.java

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,17 @@
1616

1717
package org.springframework.boot.docs.web.servlet.springmvc.messageconverters;
1818

19+
import java.text.SimpleDateFormat;
20+
21+
import tools.jackson.databind.json.JsonMapper;
22+
1923
import org.springframework.boot.http.converter.autoconfigure.ClientHttpMessageConvertersCustomizer;
24+
import org.springframework.boot.http.converter.autoconfigure.ServerHttpMessageConvertersCustomizer;
2025
import org.springframework.context.annotation.Bean;
2126
import org.springframework.context.annotation.Configuration;
27+
import org.springframework.http.converter.HttpMessageConverters.ClientBuilder;
28+
import org.springframework.http.converter.HttpMessageConverters.ServerBuilder;
29+
import org.springframework.http.converter.json.JacksonJsonHttpMessageConverter;
2230

2331
@Configuration(proxyBeanMethods = false)
2432
public class MyHttpMessageConvertersConfiguration {
@@ -29,4 +37,32 @@ public ClientHttpMessageConvertersCustomizer myClientConvertersCustomizer() {
2937
.addCustomConverter(new AnotherHttpMessageConverter());
3038
}
3139

40+
@Bean
41+
public JacksonConverterCustomizer jacksonConverterCustomizer() {
42+
JsonMapper jsonMapper = JsonMapper.builder().defaultDateFormat(new SimpleDateFormat("yyyy-MM")).build();
43+
return new JacksonConverterCustomizer(jsonMapper);
44+
}
45+
46+
// contribute a custom JSON converter to both client and server
47+
static class JacksonConverterCustomizer
48+
implements ClientHttpMessageConvertersCustomizer, ServerHttpMessageConvertersCustomizer {
49+
50+
private final JsonMapper jsonMapper;
51+
52+
JacksonConverterCustomizer(JsonMapper jsonMapper) {
53+
this.jsonMapper = jsonMapper;
54+
}
55+
56+
@Override
57+
public void customize(ClientBuilder builder) {
58+
builder.withJsonConverter(new JacksonJsonHttpMessageConverter(this.jsonMapper));
59+
}
60+
61+
@Override
62+
public void customize(ServerBuilder builder) {
63+
builder.withJsonConverter(new JacksonJsonHttpMessageConverter(this.jsonMapper));
64+
}
65+
66+
}
67+
3268
}

documentation/spring-boot-docs/src/main/kotlin/org/springframework/boot/docs/web/servlet/springmvc/messageconverters/MyHttpMessageConvertersConfiguration.kt

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,13 @@
1717
package org.springframework.boot.docs.web.servlet.springmvc.messageconverters
1818

1919
import org.springframework.boot.http.converter.autoconfigure.ClientHttpMessageConvertersCustomizer
20+
import org.springframework.boot.http.converter.autoconfigure.ServerHttpMessageConvertersCustomizer
2021
import org.springframework.context.annotation.Bean
2122
import org.springframework.context.annotation.Configuration
2223
import org.springframework.http.converter.HttpMessageConverters
24+
import org.springframework.http.converter.json.JacksonJsonHttpMessageConverter
25+
import tools.jackson.databind.json.JsonMapper
26+
import java.text.SimpleDateFormat
2327

2428
@Configuration(proxyBeanMethods = false)
2529
class MyHttpMessageConvertersConfiguration {
@@ -33,5 +37,26 @@ class MyHttpMessageConvertersConfiguration {
3337
}
3438
}
3539

40+
@Bean
41+
fun jacksonConverterCustomizer(): JacksonConverterCustomizer {
42+
val jsonMapper = JsonMapper.builder()
43+
.defaultDateFormat(SimpleDateFormat("yyyy-MM"))
44+
.build()
45+
return JacksonConverterCustomizer(jsonMapper)
46+
}
47+
48+
// contribute a custom JSON converter to both client and server
49+
class JacksonConverterCustomizer(private val jsonMapper: JsonMapper) :
50+
ClientHttpMessageConvertersCustomizer, ServerHttpMessageConvertersCustomizer {
51+
52+
override fun customize(builder: HttpMessageConverters.ClientBuilder) {
53+
builder.withJsonConverter(JacksonJsonHttpMessageConverter(this.jsonMapper))
54+
}
55+
56+
override fun customize(builder: HttpMessageConverters.ServerBuilder) {
57+
builder.withJsonConverter(JacksonJsonHttpMessageConverter(this.jsonMapper))
58+
}
59+
}
60+
3661
}
3762

0 commit comments

Comments
 (0)