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
This commit is contained in:
Dave Syer 2015-08-26 14:17:48 +01:00
parent a0870c1c4a
commit 538afc4ab1
2 changed files with 16 additions and 5 deletions

View File

@ -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<Map<String, Object>> error(HttpServletRequest request) {
Map<String, Object> body = getErrorAttributes(request, getTraceParameter(request));
Map<String, Object> body = getErrorAttributes(request);
HttpStatus status = getStatus(request);
return new ResponseEntity<Map<String, Object>>(body, status);
}
@ -81,14 +82,18 @@ public class BasicErrorController implements ErrorController {
return !"false".equals(parameter.toLowerCase());
}
private Map<String, Object> getErrorAttributes(HttpServletRequest request,
protected Map<String, Object> getErrorAttributes(HttpServletRequest request) {
return getErrorAttributes(request, getTraceParameter(request));
}
protected Map<String, Object> 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) {

View File

@ -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`: