一、前言
在本文中,我们将研究如何禁用和自定义Spring Boot应用程序的默认错误页面,因为正确的错误处理体现了专业精神和高质量的工作。
二、禁用默认错误页面
首先,让我们看看如何通过将server.error.whitelabel.enabled属性设置为false来完全禁用默认的错误页面:
server.error.whitelabel.enabled=false
把上面这条配置添加到application.properties文件中会禁用Spring Boot的默认错误页面,并显示一个简洁的页面,该页面来自于底层的应用程序容器,比如:Tomcat。
我们还可以通过排除ErrorMvcAutoConfiguration来达到相同的结果。我们可以在application.properties文件中这样配置:
#SPring Boot 1.x
spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.web.ErrorMvcAutoConfiguration
#Spring Boot 2.x
#spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration
亦或者在主类中通过注解排除:
@EnableAutoConfiguration(exclude = {ErrorMvcAutoConfiguration.class})
上面提到的所有方法都将禁用Spring Boot的默认错误页面。
接下来的问题是谁来真正地处理错误?
好吧,就像上面所说的,它通常是底层应用程序容器。
这样的好处是我们可以显示自定义错误页面替换掉默认的错误页面,这是下一部分的重点。
三、显示自定义错误页面
首先,我们需要创建一个自定义的HTML错误页面。
由于我们使用的是Thymeleaf模版引擎,所以我们将这个文件保存为error.html:
<!DOCTYPE html>
<html>
<body>
<h1>Something went wrong! </h1>
<h2>Our Engineers are on it</h2>
<a href="/">Go Home</a>
</body>
</html>
如果我们把这个文件放入resources/templates目录,那么BasicErrorController将会自动选中它。
这就是我们显示自定义错误页面所需要的东西。我们还可以定义对用户更友好的错误页面。
我们可以通过使用HTTP状态码作为文件名来更具体的指定错误页面,比如在resources/templates/error目录中一个文件名为404.html的文件显示的指明它在发生404错误的时候被使用。
3.1 自定义ErrorController
当前存在的限制是在错误发生时我们无法执行自定义的错误处理逻辑。为此我们需要创建一个自定义的ErrorController来替换掉默认的处理逻辑。
对此,我们需要创建一个实现ErrorController接口的类并且覆写它的getErrorPath()方法用于在错误发生时返回一个自定义的路径:
@Controller
public class MyErrorController implements ErrorController {
@RequestMapping("/error")
public String handleError() {
//do something like logging
return "error";
}
@Override
public String getErrorPath() {
return "/error";
}
}
在上面的代码中,我们在这个类上使用了注解@Controller并且为getErrorPath()方法所返回的路径创建了一个请求映射。这样控制器就能处理发生在/error路径上的请求。
在handleError()方法中,我们返回之前创建的自定义错误页面。如果我们现在触发404错误,将会显示我们自定义的错误页面。
下面,我们进一步来加强handleError()方法,使它对不同的错误类型显示更具体的错误页面。
举个例子,我们可以有专门对404和500错误类型设计的页面。然后我们可以使用HTTP状态码来确定需要显示的错误页面:
@RequestMapping("/error")
public String handleError(HttpServletRequest request) {
Object status = request.getAttribute(RequestDispatcher.ERROR_STATUS_CODE);
if (status != null) {
Integer statusCode = Integer.valueOf(status.toString());
if(statusCode == HttpStatus.NOT_FOUND.value()) {
return "error-404";
}
else if(statusCode == HttpStatus.INTERNAL_SERVER_ERROR.value()) {
return "error-500";
}
}
return "error";
}
然后,以404错误为例,我们将看到error-404.html页面:
四、总结
有了这些知识,我们现在可以更优雅地处理错误并向用户展示美观的页面。
与往常一样,完整的源代码可以在Github上找到。