Skip to content

Commit f039c73

Browse files
committed
Move spring.codec properties to spring.http.codecs
Closes gh-44925
1 parent 5e8812a commit f039c73

File tree

7 files changed

+178
-49
lines changed

7 files changed

+178
-49
lines changed

buildSrc/src/main/java/org/springframework/boot/build/context/properties/DocumentConfigurationProperties.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,6 @@ private void corePrefixes(Config config) {
8787
config.accept("spring.autoconfigure");
8888
config.accept("spring.banner");
8989
config.accept("spring.beaninfo");
90-
config.accept("spring.codec");
9190
config.accept("spring.config");
9291
config.accept("spring.info");
9392
config.accept("spring.jmx");

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/codec/CodecProperties.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,20 @@
1616

1717
package org.springframework.boot.autoconfigure.codec;
1818

19+
import org.springframework.boot.autoconfigure.http.codec.HttpCodecsProperties;
1920
import org.springframework.boot.context.properties.ConfigurationProperties;
21+
import org.springframework.boot.context.properties.DeprecatedConfigurationProperty;
2022
import org.springframework.util.unit.DataSize;
2123

2224
/**
2325
* {@link ConfigurationProperties Properties} for reactive codecs.
2426
*
2527
* @author Brian Clozel
2628
* @since 2.2.1
29+
* @deprecated since 3.5.0 for removal in 4.0.0 in favor of {@link HttpCodecsProperties}
2730
*/
2831
@ConfigurationProperties("spring.codec")
32+
@Deprecated(since = "3.5.0", forRemoval = true)
2933
public class CodecProperties {
3034

3135
/**
@@ -41,6 +45,7 @@ public class CodecProperties {
4145
*/
4246
private DataSize maxInMemorySize;
4347

48+
@DeprecatedConfigurationProperty(since = "3.5.0", replacement = "spring.http.codec.log-request-details")
4449
public boolean isLogRequestDetails() {
4550
return this.logRequestDetails;
4651
}
@@ -49,6 +54,7 @@ public void setLogRequestDetails(boolean logRequestDetails) {
4954
this.logRequestDetails = logRequestDetails;
5055
}
5156

57+
@DeprecatedConfigurationProperty(since = "3.5.0", replacement = "spring.http.codec.max-in-memory-size")
5258
public DataSize getMaxInMemorySize() {
5359
return this.maxInMemorySize;
5460
}

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/codec/CodecsAutoConfiguration.java

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020

2121
import org.springframework.boot.autoconfigure.AutoConfiguration;
2222
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
23-
import org.springframework.boot.autoconfigure.codec.CodecProperties;
2423
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
2524
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
2625
import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration;
@@ -29,7 +28,9 @@
2928
import org.springframework.boot.web.codec.CodecCustomizer;
3029
import org.springframework.context.annotation.Bean;
3130
import org.springframework.context.annotation.Configuration;
31+
import org.springframework.core.Ordered;
3232
import org.springframework.core.annotation.Order;
33+
import org.springframework.core.env.Environment;
3334
import org.springframework.http.codec.CodecConfigurer;
3435
import org.springframework.http.codec.json.Jackson2JsonDecoder;
3536
import org.springframework.http.codec.json.Jackson2JsonEncoder;
@@ -47,7 +48,6 @@
4748
*/
4849
@AutoConfiguration(after = JacksonAutoConfiguration.class)
4950
@ConditionalOnClass({ CodecConfigurer.class, WebClient.class })
50-
@EnableConfigurationProperties(CodecProperties.class)
5151
public class CodecsAutoConfiguration {
5252

5353
private static final MimeType[] EMPTY_MIME_TYPES = {};
@@ -69,21 +69,48 @@ CodecCustomizer jacksonCodecCustomizer(ObjectMapper objectMapper) {
6969

7070
}
7171

72+
@SuppressWarnings("removal")
7273
@Configuration(proxyBeanMethods = false)
74+
@EnableConfigurationProperties({ org.springframework.boot.autoconfigure.codec.CodecProperties.class,
75+
HttpCodecsProperties.class })
7376
static class DefaultCodecsConfiguration {
7477

7578
@Bean
76-
@Order(0)
77-
CodecCustomizer defaultCodecCustomizer(CodecProperties codecProperties) {
78-
return (configurer) -> {
79+
DefaultCodecCustomizer defaultCodecCustomizer(
80+
org.springframework.boot.autoconfigure.codec.CodecProperties codecProperties,
81+
HttpCodecsProperties httpCodecProperties, Environment environment) {
82+
return new DefaultCodecCustomizer(
83+
httpCodecProperties.isLogRequestDetails(codecProperties::isLogRequestDetails),
84+
httpCodecProperties.getMaxInMemorySize(codecProperties::getMaxInMemorySize));
85+
}
86+
87+
static final class DefaultCodecCustomizer implements CodecCustomizer, Ordered {
88+
89+
private final boolean logRequestDetails;
90+
91+
private final DataSize maxInMemorySize;
92+
93+
DefaultCodecCustomizer(boolean logRequestDetails, DataSize maxInMemorySize) {
94+
this.logRequestDetails = logRequestDetails;
95+
this.maxInMemorySize = maxInMemorySize;
96+
}
97+
98+
@Override
99+
public void customize(CodecConfigurer configurer) {
79100
PropertyMapper map = PropertyMapper.get();
80101
CodecConfigurer.DefaultCodecs defaultCodecs = configurer.defaultCodecs();
81-
defaultCodecs.enableLoggingRequestDetails(codecProperties.isLogRequestDetails());
82-
map.from(codecProperties.getMaxInMemorySize())
102+
defaultCodecs.enableLoggingRequestDetails(this.logRequestDetails);
103+
map.from(this.maxInMemorySize)
83104
.whenNonNull()
84105
.asInt(DataSize::toBytes)
85106
.to(defaultCodecs::maxInMemorySize);
86-
};
107+
}
108+
109+
@Override
110+
public int getOrder() {
111+
return 0;
112+
}
113+
87114
}
88115

89116
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
/*
2+
* Copyright 2012-2025 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.boot.autoconfigure.http.codec;
18+
19+
import java.util.function.Supplier;
20+
21+
import org.springframework.boot.context.properties.ConfigurationProperties;
22+
import org.springframework.util.unit.DataSize;
23+
24+
/**
25+
* {@link ConfigurationProperties Properties} for reactive HTTP codecs.
26+
*
27+
* @author Brian Clozel
28+
* @author Andy Wilkinson
29+
* @since 3.5.0
30+
*/
31+
@ConfigurationProperties("spring.http.codecs")
32+
public class HttpCodecsProperties {
33+
34+
/**
35+
* Whether to log form data at DEBUG level, and headers at TRACE level.
36+
*/
37+
private boolean logRequestDetails;
38+
39+
@Deprecated(since = "3.5.0", forRemoval = true)
40+
private boolean logRequestDetailsBound = false;
41+
42+
/**
43+
* Limit on the number of bytes that can be buffered whenever the input stream needs
44+
* to be aggregated. This applies only to the auto-configured WebFlux server and
45+
* WebClient instances. By default this is not set, in which case individual codec
46+
* defaults apply. Most codecs are limited to 256K by default.
47+
*/
48+
private DataSize maxInMemorySize;
49+
50+
@Deprecated(since = "3.5.0", forRemoval = true)
51+
private boolean maxInMemorySizeBound = false;
52+
53+
public boolean isLogRequestDetails() {
54+
return this.logRequestDetails;
55+
}
56+
57+
boolean isLogRequestDetails(Supplier<Boolean> fallback) {
58+
return this.logRequestDetailsBound ? this.logRequestDetails : fallback.get();
59+
}
60+
61+
public void setLogRequestDetails(boolean logRequestDetails) {
62+
this.logRequestDetails = logRequestDetails;
63+
this.logRequestDetailsBound = true;
64+
}
65+
66+
public DataSize getMaxInMemorySize() {
67+
return this.maxInMemorySize;
68+
}
69+
70+
DataSize getMaxInMemorySize(Supplier<DataSize> fallback) {
71+
return this.maxInMemorySizeBound ? this.maxInMemorySize : fallback.get();
72+
}
73+
74+
public void setMaxInMemorySize(DataSize maxInMemorySize) {
75+
this.maxInMemorySize = maxInMemorySize;
76+
this.maxInMemorySizeBound = true;
77+
}
78+
79+
}

spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/http/codec/CodecsAutoConfigurationTests.java

Lines changed: 56 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2023 the original author or authors.
2+
* Copyright 2012-2025 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -16,22 +16,21 @@
1616

1717
package org.springframework.boot.autoconfigure.http.codec;
1818

19-
import java.lang.reflect.Method;
2019
import java.util.List;
2120

2221
import com.fasterxml.jackson.databind.ObjectMapper;
2322
import org.junit.jupiter.api.Test;
2423

2524
import org.springframework.boot.autoconfigure.AutoConfigurations;
26-
import org.springframework.boot.autoconfigure.codec.CodecProperties;
25+
import org.springframework.boot.test.context.assertj.AssertableWebApplicationContext;
2726
import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
2827
import org.springframework.boot.web.codec.CodecCustomizer;
2928
import org.springframework.context.annotation.Bean;
3029
import org.springframework.context.annotation.Configuration;
31-
import org.springframework.core.annotation.AnnotationAwareOrderComparator;
30+
import org.springframework.core.Ordered;
3231
import org.springframework.http.codec.CodecConfigurer;
32+
import org.springframework.http.codec.CodecConfigurer.DefaultCodecs;
3333
import org.springframework.http.codec.support.DefaultClientCodecConfigurer;
34-
import org.springframework.util.ReflectionUtils;
3534

3635
import static org.assertj.core.api.Assertions.assertThat;
3736

@@ -48,34 +47,58 @@ class CodecsAutoConfigurationTests {
4847

4948
@Test
5049
void autoConfigShouldProvideALoggingRequestDetailsCustomizer() {
51-
this.contextRunner.run((context) -> {
52-
CodecCustomizer customizer = context.getBean(CodecCustomizer.class);
53-
CodecConfigurer configurer = new DefaultClientCodecConfigurer();
54-
customizer.customize(configurer);
55-
assertThat(configurer.defaultCodecs()).hasFieldOrPropertyWithValue("enableLoggingRequestDetails", false);
56-
});
50+
this.contextRunner.run((context) -> assertThat(defaultCodecs(context))
51+
.hasFieldOrPropertyWithValue("enableLoggingRequestDetails", false));
52+
}
53+
54+
@Test
55+
void loggingRequestDetailsCustomizerShouldUseCodecProperties() {
56+
this.contextRunner.withPropertyValues("spring.codec.log-request-details=true")
57+
.run((context) -> assertThat(defaultCodecs(context))
58+
.hasFieldOrPropertyWithValue("enableLoggingRequestDetails", true));
59+
}
60+
61+
@Test
62+
void loggingRequestDetailsCustomizerShouldUseHttpCodecsProperties() {
63+
this.contextRunner.withPropertyValues("spring.http.codecs.log-request-details=true")
64+
.run((context) -> assertThat(defaultCodecs(context))
65+
.hasFieldOrPropertyWithValue("enableLoggingRequestDetails", true));
66+
}
67+
68+
@Test
69+
void logRequestDetailsShouldGivePriorityToHttpCodecProperty() {
70+
this.contextRunner
71+
.withPropertyValues("spring.http.codecs.log-request-details=true", "spring.codec.log-request-details=false")
72+
.run((context) -> assertThat(defaultCodecs(context))
73+
.hasFieldOrPropertyWithValue("enableLoggingRequestDetails", true));
74+
}
5775

76+
@Test
77+
void maxInMemorySizeShouldUseCodecProperties() {
78+
this.contextRunner.withPropertyValues("spring.codec.max-in-memory-size=64KB")
79+
.run((context) -> assertThat(defaultCodecs(context)).hasFieldOrPropertyWithValue("maxInMemorySize",
80+
64 * 1024));
81+
}
82+
83+
@Test
84+
void maxInMemorySizeShouldUseHttpCodecProperties() {
85+
this.contextRunner.withPropertyValues("spring.http.codecs.max-in-memory-size=64KB")
86+
.run((context) -> assertThat(defaultCodecs(context)).hasFieldOrPropertyWithValue("maxInMemorySize",
87+
64 * 1024));
5888
}
5989

6090
@Test
61-
void loggingRequestDetailsCustomizerShouldUseHttpProperties() {
62-
this.contextRunner.withPropertyValues("spring.codec.log-request-details=true").run((context) -> {
63-
CodecCustomizer customizer = context.getBean(CodecCustomizer.class);
64-
CodecConfigurer configurer = new DefaultClientCodecConfigurer();
65-
customizer.customize(configurer);
66-
assertThat(configurer.defaultCodecs()).hasFieldOrPropertyWithValue("enableLoggingRequestDetails", true);
67-
});
91+
void maxInMemorySizeShouldGivePriorityToHttpCodecProperty() {
92+
this.contextRunner
93+
.withPropertyValues("spring.http.codecs.max-in-memory-size=64KB", "spring.codec.max-in-memory-size=32KB")
94+
.run((context) -> assertThat(defaultCodecs(context)).hasFieldOrPropertyWithValue("maxInMemorySize",
95+
64 * 1024));
6896
}
6997

7098
@Test
7199
void defaultCodecCustomizerBeanShouldHaveOrderZero() {
72-
this.contextRunner.run((context) -> {
73-
Method customizerMethod = ReflectionUtils.findMethod(
74-
CodecsAutoConfiguration.DefaultCodecsConfiguration.class, "defaultCodecCustomizer",
75-
CodecProperties.class);
76-
Integer order = new TestAnnotationAwareOrderComparator().findOrder(customizerMethod);
77-
assertThat(order).isZero();
78-
});
100+
this.contextRunner
101+
.run((context) -> assertThat(context.getBean("defaultCodecCustomizer", Ordered.class).getOrder()).isZero());
79102
}
80103

81104
@Test
@@ -101,21 +124,16 @@ void userProvidedCustomizerCanOverrideJacksonCodecCustomizer() {
101124

102125
@Test
103126
void maxInMemorySizeEnforcedInDefaultCodecs() {
104-
this.contextRunner.withPropertyValues("spring.codec.max-in-memory-size=1MB").run((context) -> {
105-
CodecCustomizer customizer = context.getBean(CodecCustomizer.class);
106-
CodecConfigurer configurer = new DefaultClientCodecConfigurer();
107-
customizer.customize(configurer);
108-
assertThat(configurer.defaultCodecs()).hasFieldOrPropertyWithValue("maxInMemorySize", 1048576);
109-
});
127+
this.contextRunner.withPropertyValues("spring.codec.max-in-memory-size=1MB")
128+
.run((context) -> assertThat(defaultCodecs(context)).hasFieldOrPropertyWithValue("maxInMemorySize",
129+
1048576));
110130
}
111131

112-
static class TestAnnotationAwareOrderComparator extends AnnotationAwareOrderComparator {
113-
114-
@Override
115-
public Integer findOrder(Object obj) {
116-
return super.findOrder(obj);
117-
}
118-
132+
private DefaultCodecs defaultCodecs(AssertableWebApplicationContext context) {
133+
CodecCustomizer customizer = context.getBean(CodecCustomizer.class);
134+
CodecConfigurer configurer = new DefaultClientCodecConfigurer();
135+
customizer.customize(configurer);
136+
return configurer.defaultCodecs();
119137
}
120138

121139
@Configuration(proxyBeanMethods = false)

spring-boot-project/spring-boot-docs/src/docs/antora/modules/reference/pages/using/devtools.adoc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ NOTE: If you do not want property defaults to be applied you can set configprop:
7878

7979
Because you need more information about web requests while developing Spring MVC and Spring WebFlux applications, developer tools suggests you to enable `DEBUG` logging for the `web` logging group.
8080
This will give you information about the incoming request, which handler is processing it, the response outcome, and other details.
81-
If you wish to log all request details (including potentially sensitive information), you can turn on the configprop:spring.mvc.log-request-details[] or configprop:spring.codec.log-request-details[] configuration properties.
81+
If you wish to log all request details (including potentially sensitive information), you can turn on the configprop:spring.mvc.log-request-details[] or configprop:spring.http.codecs.log-request-details[] configuration properties.
8282

8383

8484

spring-boot-project/spring-boot-docs/src/docs/antora/modules/reference/pages/web/reactive.adoc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ When not configured, the following defaults are used:
8787
Spring WebFlux uses the javadoc:org.springframework.http.codec.HttpMessageReader[] and javadoc:org.springframework.http.codec.HttpMessageWriter[] interfaces to convert HTTP requests and responses.
8888
They are configured with javadoc:org.springframework.http.codec.CodecConfigurer[] to have sensible defaults by looking at the libraries available in your classpath.
8989

90-
Spring Boot provides dedicated configuration properties for codecs, `+spring.codec.*+`.
90+
Spring Boot provides dedicated configuration properties for codecs, `+spring.http.codecs.*+`.
9191
It also applies further customization by using javadoc:org.springframework.boot.web.codec.CodecCustomizer[] instances.
9292
For example, `+spring.jackson.*+` configuration keys are applied to the Jackson codec.
9393

0 commit comments

Comments
 (0)