SpringBoot 自定义 404 页面
- Java
- 2021-09-08
- 185热度
- 0评论
导航
第一次做,绕了很久的弯路。详细总结一下。
一、背景
用 SpringBoot 写的后端服务,遇到 404 的时候,默认会返回一个 WhiteLable 页面(如图所示)。
可读性很差,因此:
- 我们需要有自定义的错误提示页面;
- 针对不同类型的错误(404、403、500),返回不同的错误页面。
二、步骤
Step1 加入 thymeleaf 依赖
在 build.gradle 中加入:
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
Step2 添加默认错误页面
在 resources/templates/ 目录下,创建一个 error.html 文件。
例如内容为:
<!DOCTYPE html> <html> <body> <h1> Default Error - Something went wrong! </h1> <p><a href="/">Go Home</a></p> </body> </html>
此时,只要遇到错误,都会显示这个错误页面。
Step3 实现自定义的 ErrorController
先在 templates 目录中添加特定的错误页面:
- error-404.html
- error-403.html
- error-500.html
创建一个 Controller 类,去实现 ErrorController。其中有一个 GetMapping,路径是 /error。
@Controller public class MyErrorController implements ErrorController { // 如果接口中没有这个方法,就不写 @Override @SuppressWarnings("deprecation") public String getErrorPath() { return "error"; } @GetMapping("/error") public String handleError(HttpServletRequest request) { Object status = request.getAttribute(RequestDispatcher.ERROR_STATUS_CODE); if (status != null) { int statusCode = Integer.parseInt(status.toString()); if(statusCode == HttpStatus.NOT_FOUND.value()) { return "error-404"; } else if(statusCode == HttpStatus.FORBIDDEN.value()) { return "error-403"; } else if(statusCode == HttpStatus.INTERNAL_SERVER_ERROR.value()) { return "error-500"; } } return "error"; } // 附带一个测试接口,用于验证功能。验证完可以删掉 @GetMapping(value = "/test/{id}") public void testError(HttpServletResponse response, @PathVariable("id") int id) { if (id == 403) { throw new ResponseStatusException(HttpStatus.FORBIDDEN, "forbidden"); } else if (id == 404) { throw new ResponseStatusException(HttpStatus.NOT_FOUND, "Unable to find resource"); } else { throw new ResponseStatusException(HttpStatus.INTERNAL_SERVER_ERROR, "internal error"); } } }
三、原理浅析
细节还是要慢慢 debug 去看。
主要原理是:
服务器收到一个 request 后,尝试处理。处理过程中发生异常,就一层层地抛出。直到外层某个地方会 catch 住这个异常,把 request 对象的内容修改掉,请求路径改为 /error,然后再次进行处理。