Skip to content

Commit d46de7a

Browse files
committed
Polish "Set UTF-8 charset for whitelabel HTML error pages"
Closes gh-16611
1 parent 64a8326 commit d46de7a

File tree

4 files changed

+23
-8
lines changed

4 files changed

+23
-8
lines changed

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/reactive/error/DefaultErrorWebExceptionHandler.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
package org.springframework.boot.autoconfigure.web.reactive.error;
1818

19+
import java.nio.charset.StandardCharsets;
1920
import java.util.Collections;
2021
import java.util.EnumMap;
2122
import java.util.List;
@@ -73,6 +74,9 @@
7374
*/
7475
public class DefaultErrorWebExceptionHandler extends AbstractErrorWebExceptionHandler {
7576

77+
private static final MediaType TEXT_HTML_UTF8 = new MediaType("text", "html",
78+
StandardCharsets.UTF_8);
79+
7680
private static final Map<HttpStatus.Series, String> SERIES_VIEWS;
7781

7882
static {
@@ -105,8 +109,6 @@ protected RouterFunction<ServerResponse> getRoutingFunction(
105109
this::renderErrorResponse);
106110
}
107111

108-
private static final MediaType HTML_CONTENT_TYPE = MediaType.valueOf(MediaType.TEXT_HTML_VALUE+";charset=UTF-8");
109-
110112
/**
111113
* Render the error information as an HTML view.
112114
* @param request the current request
@@ -117,7 +119,7 @@ protected Mono<ServerResponse> renderErrorView(ServerRequest request) {
117119
Map<String, Object> error = getErrorAttributes(request, includeStackTrace);
118120
HttpStatus errorStatus = getHttpStatus(error);
119121
ServerResponse.BodyBuilder responseBody = ServerResponse.status(errorStatus)
120-
.contentType(HTML_CONTENT_TYPE);
122+
.contentType(TEXT_HTML_UTF8);
121123
return Flux
122124
.just("error/" + errorStatus.value(),
123125
"error/" + SERIES_VIEWS.get(errorStatus.series()), "error/error")

spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/servlet/error/ErrorMvcAutoConfiguration.java

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

1717
package org.springframework.boot.autoconfigure.web.servlet.error;
1818

19+
import java.nio.charset.StandardCharsets;
1920
import java.util.Date;
2021
import java.util.Map;
2122
import java.util.stream.Collectors;
@@ -66,6 +67,7 @@
6667
import org.springframework.context.annotation.Configuration;
6768
import org.springframework.core.Ordered;
6869
import org.springframework.core.type.AnnotatedTypeMetadata;
70+
import org.springframework.http.MediaType;
6971
import org.springframework.web.servlet.DispatcherServlet;
7072
import org.springframework.web.servlet.View;
7173
import org.springframework.web.servlet.view.BeanNameViewResolver;
@@ -202,6 +204,9 @@ public ConditionOutcome getMatchOutcome(ConditionContext context,
202204
*/
203205
private static class StaticView implements View {
204206

207+
private static final MediaType TEXT_HTML_UTF8 = new MediaType("text", "html",
208+
StandardCharsets.UTF_8);
209+
205210
private static final Log logger = LogFactory.getLog(StaticView.class);
206211

207212
@Override
@@ -212,6 +217,7 @@ public void render(Map<String, ?> model, HttpServletRequest request,
212217
logger.error(message);
213218
return;
214219
}
220+
response.setContentType(TEXT_HTML_UTF8.toString());
215221
StringBuilder builder = new StringBuilder();
216222
Date timestamp = (Date) model.get("timestamp");
217223
Object message = model.get("message");

spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/reactive/error/DefaultErrorWebExceptionHandlerIntegrationTests.java

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616

1717
package org.springframework.boot.autoconfigure.web.reactive.error;
1818

19+
import java.nio.charset.StandardCharsets;
20+
1921
import javax.validation.Valid;
2022

2123
import org.junit.jupiter.api.Test;
@@ -55,6 +57,9 @@
5557
*/
5658
public class DefaultErrorWebExceptionHandlerIntegrationTests {
5759

60+
private static final MediaType TEXT_HTML_UTF8 = new MediaType("text", "html",
61+
StandardCharsets.UTF_8);
62+
5863
private final LogIdFilter logIdFilter = new LogIdFilter();
5964

6065
@RegisterExtension
@@ -106,8 +111,8 @@ public void htmlError() {
106111
WebTestClient client = getWebClient(context);
107112
String body = client.get().uri("/").accept(MediaType.TEXT_HTML).exchange()
108113
.expectStatus().isEqualTo(HttpStatus.INTERNAL_SERVER_ERROR)
109-
.expectHeader().contentType(MediaType.TEXT_HTML)
110-
.expectBody(String.class).returnResult().getResponseBody();
114+
.expectHeader().contentType(TEXT_HTML_UTF8).expectBody(String.class)
115+
.returnResult().getResponseBody();
111116
assertThat(body).contains("status: 500").contains("message: Expected!");
112117
});
113118
}
@@ -201,7 +206,7 @@ public void defaultErrorView() {
201206
String body = client.get().uri("/").accept(MediaType.TEXT_HTML)
202207
.exchange().expectStatus()
203208
.isEqualTo(HttpStatus.INTERNAL_SERVER_ERROR).expectHeader()
204-
.contentType(MediaType.TEXT_HTML).expectBody(String.class)
209+
.contentType(TEXT_HTML_UTF8).expectBody(String.class)
205210
.returnResult().getResponseBody();
206211
assertThat(body).contains("Whitelabel Error Page")
207212
.contains(this.logIdFilter.getLogId())
@@ -219,7 +224,7 @@ public void escapeHtmlInDefaultErrorView() {
219224
String body = client.get().uri("/html").accept(MediaType.TEXT_HTML)
220225
.exchange().expectStatus()
221226
.isEqualTo(HttpStatus.INTERNAL_SERVER_ERROR).expectHeader()
222-
.contentType(MediaType.TEXT_HTML).expectBody(String.class)
227+
.contentType(TEXT_HTML_UTF8).expectBody(String.class)
223228
.returnResult().getResponseBody();
224229
assertThat(body).contains("Whitelabel Error Page")
225230
.contains(this.logIdFilter.getLogId())
@@ -235,7 +240,7 @@ public void testExceptionWithNullMessage() {
235240
WebTestClient client = getWebClient(context);
236241
String body = client.get().uri("/notfound")
237242
.accept(MediaType.TEXT_HTML).exchange().expectStatus()
238-
.isNotFound().expectHeader().contentType(MediaType.TEXT_HTML)
243+
.isNotFound().expectHeader().contentType(TEXT_HTML_UTF8)
239244
.expectBody(String.class).returnResult().getResponseBody();
240245
assertThat(body).contains("Whitelabel Error Page")
241246
.contains(this.logIdFilter.getLogId())

spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/web/servlet/error/ErrorMvcAutoConfigurationTests.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ public void renderContainsViewWithExceptionDetails() throws Exception {
5656
new IllegalStateException("Exception message"), false);
5757
errorView.render(errorAttributes.getErrorAttributes(webRequest, true),
5858
webRequest.getRequest(), webRequest.getResponse());
59+
assertThat(webRequest.getResponse().getContentType())
60+
.isEqualTo("text/html;charset=UTF-8");
5961
String responseString = ((MockHttpServletResponse) webRequest.getResponse())
6062
.getContentAsString();
6163
assertThat(responseString).contains(

0 commit comments

Comments
 (0)