前文提到的两种自定义 Error 数据、Error 视图的方式都是对 BasicErrorController 类中的某个环节进行修补。如果需要更加灵活地对 Error 视图和数据进行处理,可以通过继承 BasicErrorController 来实现自己的 ErrorController。
三、高级:完全自定义 Error 数据、Error 视图
1,自定义 ErrorController 继承
我们继承 BasicErrorController 创建一个自定义的 ErrorController:
- 自定义的 MyErrorController 类添加 @Controller 注解,该类将被注册到 Spring MVC 容器中。
- 由于 BasicErrorController 没有无参构造方法,因此在创建 BasicErrorController 实例时需要传递参数,在 MyErrorController 的构造方法上添加 @Autowired 注解注入所需参数。
- 重写 errorHtml 和 error 方法,对 Error 的视图和数据进行充分的自定义。
@Controller public class MyErrorController extends BasicErrorController { @Autowired public MyErrorController(ErrorAttributes errorAttributes, ServerProperties serverProperties, List<ErrorViewResolver> errorViewResolvers) { super(errorAttributes, serverProperties.getError(), errorViewResolvers); } @Override public ModelAndView errorHtml(HttpServletRequest request, HttpServletResponse response) { HttpStatus status = getStatus(request); // 获取 Spring Boot 默认提供的错误信息,然后添加一个自定义的错误信息 Map<String, Object> model = getErrorAttributes(request, isIncludeStackTrace(request, MediaType.TEXT_HTML)); model.put("msg", "出错啦++++++"); ModelAndView modelAndView = new ModelAndView("errorPage", model, status); return modelAndView; } @Override public ResponseEntity<Map<String, Object>> error(HttpServletRequest request) { HttpStatus status = getStatus(request); // 获取 Spring Boot 默认提供的错误信息,然后添加一个自定义的错误信息 Map<String, Object> body = getErrorAttributes(request, isIncludeStackTrace(request, MediaType.TEXT_HTML)); body.put("msg", "出错啦------"); return new ResponseEntity<>(body, status); } }
2,创建视图页面
在 resource/templates 目录下创建一个 errorPage.html 文件作为视图页面,内容如下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <table border="1"> <tr> <td>msg</td> <td th:text="${msg}"></td> </tr> <tr> <td>timestamp</td> <td th:text="${timestamp}"></td> </tr> <tr> <td>status</td> <td th:text="${status}"></td> </tr> <tr> <td>error</td> <td th:text="${error}"></td> </tr> <tr> <td>message</td> <td th:text="${message}"></td> </tr> <tr> <td>path</td> <td th:text="${path}"></td> </tr> </table> </body> </html>
3,运行测试
(1)当我们使用浏览器访问一个不存在的接口,运行结果如下。可以看到自定义错误信息已经成功显示:
(2)如果通过 Postman 等工具来发起这个请求,那么会发现返回的 JSON 数据同样多了自定义错误信息: