diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/error/DefaultErrorWebExceptionHandler.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/error/DefaultErrorWebExceptionHandler.java index 1171f94a105..9726d75c640 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/error/DefaultErrorWebExceptionHandler.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/error/DefaultErrorWebExceptionHandler.java @@ -16,6 +16,7 @@ package org.springframework.boot.autoconfigure.web.reactive.error; +import java.nio.charset.StandardCharsets; import java.util.Collections; import java.util.EnumMap; import java.util.List; @@ -73,6 +74,9 @@ import static org.springframework.web.reactive.function.server.RouterFunctions.r */ public class DefaultErrorWebExceptionHandler extends AbstractErrorWebExceptionHandler { + private static final MediaType TEXT_HTML_UTF8 = new MediaType("text", "html", + StandardCharsets.UTF_8); + private static final Map SERIES_VIEWS; static { @@ -105,8 +109,6 @@ public class DefaultErrorWebExceptionHandler extends AbstractErrorWebExceptionHa this::renderErrorResponse); } - private static final MediaType HTML_CONTENT_TYPE = MediaType.valueOf(MediaType.TEXT_HTML_VALUE+";charset=UTF-8"); - /** * Render the error information as an HTML view. * @param request the current request @@ -117,7 +119,7 @@ public class DefaultErrorWebExceptionHandler extends AbstractErrorWebExceptionHa Map error = getErrorAttributes(request, includeStackTrace); HttpStatus errorStatus = getHttpStatus(error); ServerResponse.BodyBuilder responseBody = ServerResponse.status(errorStatus) - .contentType(HTML_CONTENT_TYPE); + .contentType(TEXT_HTML_UTF8); return Flux .just("error/" + errorStatus.value(), "error/" + SERIES_VIEWS.get(errorStatus.series()), "error/error") diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/error/ErrorMvcAutoConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/error/ErrorMvcAutoConfiguration.java index 19cdc03daf9..1db1e56bc35 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/error/ErrorMvcAutoConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/error/ErrorMvcAutoConfiguration.java @@ -16,6 +16,7 @@ package org.springframework.boot.autoconfigure.web.servlet.error; +import java.nio.charset.StandardCharsets; import java.util.Date; import java.util.Map; import java.util.stream.Collectors; @@ -66,6 +67,7 @@ import org.springframework.context.annotation.Conditional; import org.springframework.context.annotation.Configuration; import org.springframework.core.Ordered; import org.springframework.core.type.AnnotatedTypeMetadata; +import org.springframework.http.MediaType; import org.springframework.web.servlet.DispatcherServlet; import org.springframework.web.servlet.View; import org.springframework.web.servlet.view.BeanNameViewResolver; @@ -202,6 +204,9 @@ public class ErrorMvcAutoConfiguration { */ private static class StaticView implements View { + private static final MediaType TEXT_HTML_UTF8 = new MediaType("text", "html", + StandardCharsets.UTF_8); + private static final Log logger = LogFactory.getLog(StaticView.class); @Override @@ -212,6 +217,7 @@ public class ErrorMvcAutoConfiguration { logger.error(message); return; } + response.setContentType(TEXT_HTML_UTF8.toString()); StringBuilder builder = new StringBuilder(); Date timestamp = (Date) model.get("timestamp"); Object message = model.get("message"); diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/reactive/error/DefaultErrorWebExceptionHandlerIntegrationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/reactive/error/DefaultErrorWebExceptionHandlerIntegrationTests.java index 8e117662fde..6ebfa800314 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/reactive/error/DefaultErrorWebExceptionHandlerIntegrationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/reactive/error/DefaultErrorWebExceptionHandlerIntegrationTests.java @@ -16,6 +16,8 @@ package org.springframework.boot.autoconfigure.web.reactive.error; +import java.nio.charset.StandardCharsets; + import javax.validation.Valid; import org.junit.jupiter.api.Test; @@ -55,6 +57,9 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType; */ public class DefaultErrorWebExceptionHandlerIntegrationTests { + private static final MediaType TEXT_HTML_UTF8 = new MediaType("text", "html", + StandardCharsets.UTF_8); + private final LogIdFilter logIdFilter = new LogIdFilter(); @RegisterExtension @@ -106,8 +111,8 @@ public class DefaultErrorWebExceptionHandlerIntegrationTests { WebTestClient client = getWebClient(context); String body = client.get().uri("/").accept(MediaType.TEXT_HTML).exchange() .expectStatus().isEqualTo(HttpStatus.INTERNAL_SERVER_ERROR) - .expectHeader().contentType(MediaType.TEXT_HTML) - .expectBody(String.class).returnResult().getResponseBody(); + .expectHeader().contentType(TEXT_HTML_UTF8).expectBody(String.class) + .returnResult().getResponseBody(); assertThat(body).contains("status: 500").contains("message: Expected!"); }); } @@ -201,7 +206,7 @@ public class DefaultErrorWebExceptionHandlerIntegrationTests { String body = client.get().uri("/").accept(MediaType.TEXT_HTML) .exchange().expectStatus() .isEqualTo(HttpStatus.INTERNAL_SERVER_ERROR).expectHeader() - .contentType(MediaType.TEXT_HTML).expectBody(String.class) + .contentType(TEXT_HTML_UTF8).expectBody(String.class) .returnResult().getResponseBody(); assertThat(body).contains("Whitelabel Error Page") .contains(this.logIdFilter.getLogId()) @@ -219,7 +224,7 @@ public class DefaultErrorWebExceptionHandlerIntegrationTests { String body = client.get().uri("/html").accept(MediaType.TEXT_HTML) .exchange().expectStatus() .isEqualTo(HttpStatus.INTERNAL_SERVER_ERROR).expectHeader() - .contentType(MediaType.TEXT_HTML).expectBody(String.class) + .contentType(TEXT_HTML_UTF8).expectBody(String.class) .returnResult().getResponseBody(); assertThat(body).contains("Whitelabel Error Page") .contains(this.logIdFilter.getLogId()) @@ -235,7 +240,7 @@ public class DefaultErrorWebExceptionHandlerIntegrationTests { WebTestClient client = getWebClient(context); String body = client.get().uri("/notfound") .accept(MediaType.TEXT_HTML).exchange().expectStatus() - .isNotFound().expectHeader().contentType(MediaType.TEXT_HTML) + .isNotFound().expectHeader().contentType(TEXT_HTML_UTF8) .expectBody(String.class).returnResult().getResponseBody(); assertThat(body).contains("Whitelabel Error Page") .contains(this.logIdFilter.getLogId()) diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/error/ErrorMvcAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/error/ErrorMvcAutoConfigurationTests.java index 6c4bb62c98a..2e6694d0e55 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/error/ErrorMvcAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/error/ErrorMvcAutoConfigurationTests.java @@ -56,6 +56,8 @@ public class ErrorMvcAutoConfigurationTests { new IllegalStateException("Exception message"), false); errorView.render(errorAttributes.getErrorAttributes(webRequest, true), webRequest.getRequest(), webRequest.getResponse()); + assertThat(webRequest.getResponse().getContentType()) + .isEqualTo("text/html;charset=UTF-8"); String responseString = ((MockHttpServletResponse) webRequest.getResponse()) .getContentAsString(); assertThat(responseString).contains(