SpringBoot-自定义错误页

自定义错误页

1.源码解析

在SpringBoot中,默认情况下,如果用户在发起请求时发生了404错误,SpringBoot会有一个默认页面展示给用户。

在这里插入图片描述
SpringBoot在返回错误信息时不一定返回HTML页面,而是根据实际情况返回 HTML页面或者一段 JSON。
Spring Boot 中的错误默认是由 BasicErrorController 类来处理的 ,该类中的核心方法主要有两个:

@RequestMapping(
        produces = {"text/html"}
    )
    public ModelAndView errorHtml(HttpServletRequest request, HttpServletResponse response) {
        HttpStatus status = this.getStatus(request);
        Map<String, Object> model = Collections.unmodifiableMap(this.getErrorAttributes(request, this.getErrorAttributeOptions(request, MediaType.TEXT_HTML)));
        response.setStatus(status.value());
        ModelAndView modelAndView = this.resolveErrorView(request, response, status, model);
        return modelAndView != null ? modelAndView : new ModelAndView("error", model);
    }

    @RequestMapping
    public ResponseEntity<Map<String, Object>> error(HttpServletRequest request) {
        HttpStatus status = this.getStatus(request);
        if (status == HttpStatus.NO_CONTENT) {
            return new ResponseEntity(status);
        } else {
            Map<String, Object> body = this.getErrorAttributes(request, this.getErrorAttributeOptions(request, MediaType.ALL));
            return new ResponseEntity(body, status);
        }
    }
   

其中,errorHtml方法用来返回错误HTML页面,error用来返回错误JSON,具体返回的是HTML还是JSON,则要看请求头的Accept参数。在errorHTML方法中,通过调用resolveErrorView方法来获取一个错误视图的ModelAndView。而 resolveErrorView 方法的调用最终会来到 DefaultErrorViewResolver 类中 。 DefaultErrorViewResolver 类是 Spring Boot 中默认的错误信息视图解析器, 部分源码如下:

static {
		Map<Series, String> views = new EnumMap<>(Series.class);
		views.put(Series.CLIENT_ERROR, "4xx");
		views.put(Series.SERVER_ERROR, "5xx");
		SERIES_VIEWS = Collections.unmodifiableMap(views);
	}
	private ModelAndView resolve(String viewName, Map<String, Object> model) {
		String errorViewName = "error/" + viewName;
		TemplateAvailabilityProvider provider = this.templateAvailabilityProviders.getProvider(errorViewName,
				this.applicationContext);
		if (provider != null) {
			return new ModelAndView(errorViewName, model);
		}
		return resolveResource(errorViewName, model);
	}

SpringBoot默认是在error目录下查找4xx、5xx的文件作为错误视图,党找不到时会回到errorHtml方法中,然后使用error作为默认的错误页面视图名。

2.简单配置

要自定义错误页面,只需要提供4xx和5xx页面。如果不需要向用户展示详细的错误信息,可以把错误信息定义为静态页面,在resources/static目录下创建error目录。错误展示页面的命名规则有两种:4xx.hmtl、5xx.html,还可以404.html、405.html、500.html

Alt
当用户访问一个不存在的路径时,就会展示404.html的内容

在这里插入图片描述

这种定义都是使用了静态HTML页面,无法向用户展示完整的错误信息,若采用视图模板技术,则可以向用户展示更多的错误信息。如果要使用Thymeleaf模板,要先引入Thymeleaf模板相关的依赖。Thymeleaf 页面模板默认处于= classpath: /templates/目录下,因此在该目录下先创建 error 目录,再创建错误展示页。

在这里插入图片描述

页面代码:

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org/">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<table border="1">
    <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>

SpringBoot在这里返回了5条错误相关信息,分别是timestamp, status 、 error 、 message、path。

在这里插入图片描述

3.复杂配置

SpringBoot中支持对Error信息的深度定制,有三个方面:自定义Error数据、自定义Eoor视图、完全自定义

3.1 自定义Error数据

自定义Error数据就是对返回的数据进行自定义。在BasicErrorControllererrorHtmlerror方法中,都是通过getErrorAttributes方法获取Error信息。该方法最终会调用到DefaultErrorAttributes 类的 getErrorAttributes 方法,而DefaultError Attributes 类是在 ErrorMvcAutoConfiguration 中默认提供的 。ErrorMvcAutoConfiguration
类的 errorAttributes 方法源码如下:

@Bean
	@ConditionalOnMissingBean(value = ErrorAttributes.class, search = SearchStrategy.CURRENT)
	public DefaultErrorAttributes errorAttributes() {
		return new DefaultErrorAttributes();
	}

从源码中可以看出,当系统没有提供ErrorAttributes时会采用DefaultErrorAttributes。定义错误提示使,只需要自己提供ErrorAttributes,而 DefaultErrorAttributes 是Error Attributes 的子类,需要继承DefaultErrorAttributes

@Component
public class MyErrorAttribute extends DefaultErrorAttributes {
    @Override
    public Map<String, Object> getErrorAttributes(WebRequest webRequest, ErrorAttributeOptions options) {
        Map<String, Object> errorAttributes = super.getErrorAttributes(webRequest, options);
        errorAttributes.put("custommsg","出错啦");
        errorAttributes.remove("error");
        return errorAttributes;
    }
  

代码解释:

  • List item自定义MyErrorAttribute 继承自DefaultErrorAttributes,重写DefaultErrorAttributes中的getErrorAttributes方法。
  • 通过super.getErrorAttributes获取SpringBoot默认提供的错误信息。

页面代码

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org/">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<table border="1">
    <tr>
        <td>custommsg</td>
        <td th:text="${custommsg}"></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>

在第 9~ 12 行添加了 custommsg 属性。

在这里插入图片描述

3.2 自定义Error视图

Error 视图是展示给用户的页面,在BasicErrorController的errorHtml方法中调用resolveErrorView方法获取一个ModelAndView实例。resolveErrorView方法是由ErrorView Resolver 提供的。ErrorMvcAutoConfiguration类的源码可以看到默认采用的ErrorViewResolver是DefaultErrorViewResolver。ErrorMvcAutoConfiguration 源码如下:

	@Bean
		@ConditionalOnBean(DispatcherServlet.class)
		@ConditionalOnMissingBean(ErrorViewResolver.class)
		DefaultErrorViewResolver conventionErrorViewResolver() {
			return new DefaultErrorViewResolver(this.applicationContext, this.resources);
		}

从源码看出,如果用户没有定义ErrorViewResolver,那么默认使用的ErrorViewResolver是DefaultErrorViewResolver,正是在DefaultErrorViewResolver中默认配置了默认去error目录下寻找4xx.html。自定义Error视图,只需要提供自己的ErrorViewResolver即可。

@Component
public class MyErrorAttribute extends DefaultErrorAttributes {
    @Override
    public Map<String, Object> getErrorAttributes(WebRequest webRequest, ErrorAttributeOptions options) {
        Map<String, Object> errorAttributes = super.getErrorAttributes(webRequest, options);
        errorAttributes.put("custommsg","出错啦");
        errorAttributes.remove("error");
        return errorAttributes;
    }
}

代码解释:

  • 自定义MyErrorViewResolver实现 ErrorView Resolver 接口并实现接口中的resolveErrorView方法。
  • 在 resolveErrorView 方法中 最后一个 Map参数就是 Spring Boot 提供的默认的 5 条 Error信息,在 resolveErrorView方法中,返回一个 ModelAndVie趴在 ModelAndView 中设直 Error视图和 Error数据。

接下来在 resources/templates 目录下提供 errorPage.html 视图 ,内容如下:

<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org/">
<head>
    <meta charset="UTF-8">
    <title>errorPage</title>
</head>
<body>
<table border="1">
    <tr>
        <td>custommsg</td>
        <td th:text="${custommsg}"></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>

在 errorPage.html 除了展示 Spring Boot 提供的 5 条 Error信息外,也展示了开发者自定义的 Error 信息。此时,无论请求发生 4xx 的错误还是发生 5xx 的错误,都会来到 errorPage .html页面。

在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值