From 538afc4ab1f0d4273bbdef841f9a7457ce6ab7ca Mon Sep 17 00:00:00 2001 From: Dave Syer Date: Wed, 26 Aug 2015 14:17:48 +0100 Subject: [PATCH] Make some methods in BasicErrorController protected Spring MVC requires all handlers for the same path to be on the same handler so if anyone wants to add new handlers for different content types they have to copy a lot of code from BasicErrorController. This change increases the visibility of the basic utility methods in BasicErrorController so that custom handlers can be added easily. Fixes gh-3828 --- .../autoconfigure/web/BasicErrorController.java | 15 ++++++++++----- .../src/main/asciidoc/spring-boot-features.adoc | 6 ++++++ 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/BasicErrorController.java b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/BasicErrorController.java index ab7a812106..27f843167e 100644 --- a/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/BasicErrorController.java +++ b/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/web/BasicErrorController.java @@ -43,6 +43,7 @@ import org.springframework.web.servlet.ModelAndView; * @see ErrorAttributes */ @Controller +@RequestMapping("${error.path:/error}") public class BasicErrorController implements ErrorController { @Value("${error.path:/error}") @@ -60,15 +61,15 @@ public class BasicErrorController implements ErrorController { return this.errorPath; } - @RequestMapping(value = "${error.path:/error}", produces = "text/html") + @RequestMapping(produces = "text/html") public ModelAndView errorHtml(HttpServletRequest request) { return new ModelAndView("error", getErrorAttributes(request, false)); } - @RequestMapping(value = "${error.path:/error}") + @RequestMapping @ResponseBody public ResponseEntity> error(HttpServletRequest request) { - Map body = getErrorAttributes(request, getTraceParameter(request)); + Map body = getErrorAttributes(request); HttpStatus status = getStatus(request); return new ResponseEntity>(body, status); } @@ -81,14 +82,18 @@ public class BasicErrorController implements ErrorController { return !"false".equals(parameter.toLowerCase()); } - private Map getErrorAttributes(HttpServletRequest request, + protected Map getErrorAttributes(HttpServletRequest request) { + return getErrorAttributes(request, getTraceParameter(request)); + } + + protected Map getErrorAttributes(HttpServletRequest request, boolean includeStackTrace) { RequestAttributes requestAttributes = new ServletRequestAttributes(request); return this.errorAttributes.getErrorAttributes(requestAttributes, includeStackTrace); } - private HttpStatus getStatus(HttpServletRequest request) { + protected HttpStatus getStatus(HttpServletRequest request) { Integer statusCode = (Integer) request .getAttribute("javax.servlet.error.status_code"); if (statusCode != null) { diff --git a/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc b/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc index 504396c5a1..d1dadfa0ef 100644 --- a/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc +++ b/spring-boot-docs/src/main/asciidoc/spring-boot-features.adoc @@ -1401,6 +1401,12 @@ the same data in HTML format (to customize it just add a `View` that resolves to `ErrorController` and register a bean definition of that type, or simply add a bean of type `ErrorAttributes` to use the existing mechanism but replace the contents. +TIP: The `BasicErrorController` can be used as a base class for a custom `ErrorController`. +This is particularly useful if you want to add a handler for a new content type (the default +is to handle `text/html` specifically and provide a fallback for everything else). To do that +just extend `BasicErrorController` and add a public method with a `@RequestMapping` that +has a `produces` attribute, and create a bean of your new type. + If you want more specific error pages for some conditions, the embedded servlet containers support a uniform Java DSL for customizing the error handling. Assuming that you have a mapping for `/400`: