diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/HttpMessageConvertersAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/HttpMessageConvertersAutoConfiguration.java index 96c3db64b7..255f69751c 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/HttpMessageConvertersAutoConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/http/HttpMessageConvertersAutoConfiguration.java @@ -30,12 +30,13 @@ import org.springframework.boot.autoconfigure.gson.GsonAutoConfiguration; import org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration.NotReactiveWebApplicationCondition; import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; import org.springframework.boot.autoconfigure.jsonb.JsonbAutoConfiguration; -import org.springframework.boot.autoconfigure.web.ServerProperties; -import org.springframework.boot.context.properties.EnableConfigurationProperties; +import org.springframework.boot.context.properties.bind.Binder; +import org.springframework.boot.web.servlet.server.Encoding; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Conditional; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; +import org.springframework.core.env.Environment; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.http.converter.StringHttpMessageConverter; @@ -71,14 +72,13 @@ public class HttpMessageConvertersAutoConfiguration { @Configuration(proxyBeanMethods = false) @ConditionalOnClass(StringHttpMessageConverter.class) - @EnableConfigurationProperties(ServerProperties.class) protected static class StringHttpMessageConverterConfiguration { @Bean @ConditionalOnMissingBean - public StringHttpMessageConverter stringHttpMessageConverter(ServerProperties serverProperties) { - StringHttpMessageConverter converter = new StringHttpMessageConverter( - serverProperties.getServlet().getEncoding().getCharset()); + public StringHttpMessageConverter stringHttpMessageConverter(Environment environment) { + Encoding encoding = Binder.get(environment).bindOrCreate("server.servlet.encoding", Encoding.class); + StringHttpMessageConverter converter = new StringHttpMessageConverter(encoding.getCharset()); converter.setWriteAcceptCharset(false); return converter; } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/http/HttpMessageConvertersAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/http/HttpMessageConvertersAutoConfigurationTests.java index 4b8286d986..f850fe9a60 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/http/HttpMessageConvertersAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/http/HttpMessageConvertersAutoConfigurationTests.java @@ -16,6 +16,8 @@ package org.springframework.boot.autoconfigure.http; +import java.nio.charset.StandardCharsets; + import javax.json.bind.Jsonb; import com.fasterxml.jackson.databind.ObjectMapper; @@ -28,6 +30,7 @@ import org.springframework.boot.autoconfigure.gson.GsonAutoConfiguration; import org.springframework.boot.autoconfigure.http.JacksonHttpMessageConvertersConfiguration.MappingJackson2HttpMessageConverterConfiguration; import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration; import org.springframework.boot.autoconfigure.jsonb.JsonbAutoConfiguration; +import org.springframework.boot.autoconfigure.web.ServerProperties; import org.springframework.boot.test.context.FilteredClassLoader; import org.springframework.boot.test.context.assertj.AssertableApplicationContext; import org.springframework.boot.test.context.runner.ApplicationContextRunner; @@ -237,6 +240,38 @@ class HttpMessageConvertersAutoConfigurationTests { .run((context) -> assertThat(context).doesNotHaveBean(HttpMessageConverters.class)); } + @Test + void whenEncodingCharsetIsNotConfiguredThenStringMessageConverterUsesUtf8() { + new WebApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(HttpMessageConvertersAutoConfiguration.class)) + .run((context) -> { + assertThat(context).hasSingleBean(StringHttpMessageConverter.class); + assertThat(context.getBean(StringHttpMessageConverter.class).getDefaultCharset()) + .isEqualTo(StandardCharsets.UTF_8); + }); + } + + @Test + void whenEncodingCharsetIsConfiguredThenStringMessageConverterUsesSpecificCharset() { + new WebApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(HttpMessageConvertersAutoConfiguration.class)) + .withPropertyValues("server.servlet.encoding.charset=UTF-16").run((context) -> { + assertThat(context).hasSingleBean(StringHttpMessageConverter.class); + assertThat(context.getBean(StringHttpMessageConverter.class).getDefaultCharset()) + .isEqualTo(StandardCharsets.UTF_16); + }); + } + + @Test // gh-21789 + void whenAutoConfigurationIsActiveThenServerPropertiesConfigurationPropertiesAreNotEnabled() { + new WebApplicationContextRunner() + .withConfiguration(AutoConfigurations.of(HttpMessageConvertersAutoConfiguration.class)) + .run((context) -> { + assertThat(context).hasSingleBean(HttpMessageConverters.class); + assertThat(context).doesNotHaveBean(ServerProperties.class); + }); + } + private ApplicationContextRunner allOptionsRunner() { return this.contextRunner.withConfiguration(AutoConfigurations.of(GsonAutoConfiguration.class, JacksonAutoConfiguration.class, JsonbAutoConfiguration.class));