Spring Boot 自定义与禁用Whitelabel Error页面

作者 | 2020年4月1日

1. 前言

在本文中我们将学习如何禁用与自定义Spring Boot默认的错误页面

2. 禁用Whitelabel Error页面

首先,我们来看一下如何完全禁用Whitelabel Error页面,很简单,只要设置属性server.error.whitelabel.enabled为false即可:

server.error.whitelabel.enabled=false

把上面这个属性加到application.properties文件中就可以禁用Spring Boot的错误页面,但是,转而会显示来自底层容器的错误页面,例如,Tomcat。

此外,我们也可以通过排除 ErrorMvcAutoConfiguration类来达到同样的目的,在application.properties文件中添加即可:

spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.web.ErrorMvcAutoConfiguration

#for Spring Boot 2.0
#spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration

或者在启动类上添加注解:

@EnableAutoConfiguration(exclude = {ErrorMvcAutoConfiguration.class})

上面这几个方法都可以禁用Whitelabel Error页面,那么剩下的问题是到底谁来处理错误?

好吧,就像我们上面所说,在我们禁用Spring Boot的默认错误页面之后,错误的处理将由底层Servlet容器接管。
好消息是我们也可以选择展示我们自定义的错误页面来替换掉所有默认的错误页面。

3. 显示自定义错误页面

我们先来创建一个自定义的HTML错误页面。

PS:使用Thyneleaf模板引擎

我们把该文件保存为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目录中,Spring Boot会将该文件选择为默认的错误页面。

上述就是我们为了实现自定义错误页面所要做的全部事情,在加上一些样式我们就有了一个看起来不错的错误页面。

我们还可以进一步使用HTTP状态码来命名错误页面,例如,保存文件为404.html到目录resources/templates/error中,这意味着该文件被用作展示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";
    }
}

上面的代码中,当错误发生时会先从getErrorPath()获取到错误页面的路径并重定向到该路径上,在本例中,在错误发生时会跳转到/error页面,然后handleError()返回自定义的错误处理页面。

让我们来进一步增强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页面。

4. 总结

根据上述步骤,我们可以更优雅地处理并显示一个对用户更友好的错误页面。

发表评论

电子邮件地址不会被公开。 必填项已用*标注