From da53a0b8d5881295d6c0dd4e80280dc18fbf6531 Mon Sep 17 00:00:00 2001 From: Brian Clozel Date: Sat, 3 Nov 2018 21:28:48 +0100 Subject: [PATCH] Fix HTTP status error template rendering in WebFlux Prior to this commit, a change in `HttpStatus.toString` since SPR-16898 prevented the default WebFlux `ErrorWebExceptionHandler` to render template views for exact HTTP status (e.g. "404.html"). This issue does not affect the resolution of series, like "4xx.html". This commit fixes `DefaultErrorWebExceptionHandler` to use `HttpStatus.value()` when attempting to resolve error views. Closes gh-15083 --- .../DefaultErrorWebExceptionHandler.java | 2 +- ...orWebExceptionHandlerIntegrationTests.java | 37 +++++++++++++++++++ .../error/templates/error/404.mustache | 1 + .../error/templates/error/4xx.mustache | 1 + 4 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/web/reactive/error/templates/error/404.mustache create mode 100644 spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/web/reactive/error/templates/error/4xx.mustache 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 ffd699e563a..1bc722fbfe5 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 @@ -122,7 +122,7 @@ public class DefaultErrorWebExceptionHandler extends AbstractErrorWebExceptionHa ServerResponse.BodyBuilder responseBody = ServerResponse.status(errorStatus) .contentType(MediaType.TEXT_HTML); return Flux - .just("error/" + errorStatus.toString(), + .just("error/" + errorStatus.value(), "error/" + SERIES_VIEWS.get(errorStatus.series()), "error/error") .flatMap((viewName) -> renderErrorView(viewName, responseBody, error)) .switchIfEmpty(this.errorProperties.getWhitelabel().isEnabled() 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 c9e30b0d0b6..c5b98b1c897 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 @@ -257,6 +257,43 @@ public class DefaultErrorWebExceptionHandlerIntegrationTests { }); } + @Test + public void exactStatusTemplateErrorPage() { + this.contextRunner + .withPropertyValues("server.error.whitelabel.enabled=false", + "spring.mustache.prefix=" + getErrorTemplatesLocation()) + .run((context) -> { + WebTestClient client = WebTestClient.bindToApplicationContext(context) + .build(); + String body = client.get().uri("/notfound") + .accept(MediaType.TEXT_HTML).exchange().expectStatus() + .isNotFound().expectBody(String.class).returnResult() + .getResponseBody(); + assertThat(body).contains("404 page"); + }); + } + + @Test + public void seriesStatusTemplateErrorPage() { + this.contextRunner + .withPropertyValues("server.error.whitelabel.enabled=false", + "spring.mustache.prefix=" + getErrorTemplatesLocation()) + .run((context) -> { + WebTestClient client = WebTestClient.bindToApplicationContext(context) + .build(); + String body = client.get().uri("/badRequest") + .accept(MediaType.TEXT_HTML).exchange().expectStatus() + .isBadRequest().expectBody(String.class).returnResult() + .getResponseBody(); + assertThat(body).contains("4xx page"); + }); + } + + private String getErrorTemplatesLocation() { + String packageName = getClass().getPackage().getName(); + return "classpath:/" + packageName.replace('.', '/') + "/templates/"; + } + @Test public void invalidAcceptMediaType() { this.contextRunner.run((context) -> { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/web/reactive/error/templates/error/404.mustache b/spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/web/reactive/error/templates/error/404.mustache new file mode 100644 index 00000000000..e86570e1bda --- /dev/null +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/web/reactive/error/templates/error/404.mustache @@ -0,0 +1 @@ +404 page \ No newline at end of file diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/web/reactive/error/templates/error/4xx.mustache b/spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/web/reactive/error/templates/error/4xx.mustache new file mode 100644 index 00000000000..2e21387eb18 --- /dev/null +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/resources/org/springframework/boot/autoconfigure/web/reactive/error/templates/error/4xx.mustache @@ -0,0 +1 @@ +4xx page \ No newline at end of file