0、引言
不晓得大家有没有注意过,目前支流的网站,如果申请出错了,个别都会有敌对提醒页,比方 Bilibili ,拜访一个不存在的页面,返回提醒页:
这样的页面显然比返回一堆错误代码,甚至堆栈信息要敌对多了。
本文将应用 SpringBoot 2.3.3 + Thymeleaf 来演示如何在申请出错的状况下返回敌对提醒页面。
1、搭建我的项目
作为演示我的项目,咱们只须要 Web 和 Thymleaf 组件即可,pom 中依赖如下:
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> <exclusions> <exclusion> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> </exclusion> </exclusions> </dependency> </dependencies>
搭建完我的项目,写个简略的 HelloWorldController,环境就算是搭建好了
@Controllerpublic class HelloWorldController { @GetMapping("hello") public String hello() { return "hello"; }}
2.定制谬误页面
申请已定义的 /hello
接口天然是没什么问题,但此时如果申请一个不存在的 URL 呢?比方/hi
,因为并没有定义此接口,SpringBoot 将返回一个默认的谬误页面:
简略解释一下这个页面的来历:
当 SpringBoot 启动的时候,有一个配置类: ErrorMvcAutoConfiguration
外面会配置一些错误处理,其中就包含申请出错时的默认页面。
相干代码如下:
@Configuration(proxyBeanMethods = false)@ConditionalOnProperty(prefix = "server.error.whitelabel", name = "enabled", matchIfMissing = true)@Conditional(ErrorTemplateMissingCondition.class)protected static class WhitelabelErrorViewConfiguration { private final StaticView defaultErrorView = new StaticView(); @Bean(name = "error") @ConditionalOnMissingBean(name = "error") public View defaultErrorView() { return this.defaultErrorView; } // 省略无关代码 }}
能够看到,属性server.error.whitelabel.enabled
管制着这个类是否主动拆卸,而它的默认值是true
能够间接在 yml 中将他禁用掉:
server: error: whitelabel: enabled: false
此时再拜访 未定义的/hi
接口,将会收到 Tomcat 返回的默认页面 ,提醒 HTTP Status 404 – Not Found
.
这是因为咱们禁用了默认的谬误页面,并且没指定新的谬误页面, Thymleaf 不晓得该渲染什么页面了,从后端的报错信息中也能看到此提醒:
Caused by: org.thymeleaf.exceptions. TemplateInputException: Error resolving template [error], template might not exist or might not be accessible by any of the configured Template Resolvers
Thymeleaf 没找到 error 模板,于是报错了,能够在 templates
目录下,新建一个error.html
模板,再次申请未定义的/hi
接口,就会失去自定义的谬误页面:
到目前为止,一个简略的全局谬误页面就搞定了。
不过这个办法尽管简略,其局限性也是不言而喻的,一切都是写死的,它没法在出错时执行业务逻辑。
3.自定义 ErrorController
想要在出错时依据谬误类型进行非凡解决,就须要自定义一个 ErrorController
来实现了。
这里展现如何依据不同的谬误类型返回不同的页面:
@Controllerpublic class CustomErrorController implements ErrorController { @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 "my404"; } else if (statusCode == HttpStatus.UNAUTHORIZED.value()) { return "my401"; } else if (statusCode == HttpStatus.INTERNAL_SERVER_ERROR.value()) { return "my500"; } // 这里前期能够扩大其余谬误页面 } return "my404"; }
只须要实现handlerError
办法,即可解决相应的业务逻辑,如果有需要的话,也能够在外面组装 model 数据。
解释一下为什么有 @RequestMapping("/error")
,因为默认的错误处理门路就是 /error
,在ErrorProperties.java
中定义如下:
public class ErrorProperties {
/**
- Path of the error controller.
*/
@Value("${error.path:/error}")
private String path = "/error";
// 省略...
}
咱们齐全能够依据须要去批改这个门路,只须要在 yml 里配置一下,并放弃 yml 的设置和 ErrorController
实现类的@RequestMapping
值统一即可
server: error: # 应用默认的 /error path: /error whitelabel: enabled: false
至此,一个可编写业务代码的自定义谬误页面就编写实现了。
4.总结
本文采纳两种不同的形式,介绍了自定义谬误页面的实现:
- 默认 error 模板
- 自定义 ErrorController
文中相干代码已上传至课代表的 github
如果本文对你有帮忙,欢送珍藏、分享、在看三连
????关注 Java课代表,获取最新 Java 干货????