阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

SpringBoot异常处理和退出

400次阅读
没有评论

共计 5377 个字符,预计需要花费 14 分钟才能阅读完成。

1、自定义错误页面

1.1、概述

SpringBoot 默认的处理异常的机制:SpringBoot 默认的已经提供了一套处理异常的机制。
一旦程序中出现了异常 SpringBoot 会向 /error 的 url 发送请求。在 springBoot 中提供了一个叫 BasicExceptionController 来处理 /error 请求,然后跳转到默认显示异常的页面来展示异常信息。

1.2、自定义错误页面

在 src/main/resources/templates 目录下创建 error.html 页面

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> 出错了,请与管理员联系。。。</body> </html>

** 注意:** 名称必须叫 error, 工程中要添加 thymeleaf 依赖

2、@ExceptionHandler 注解处理局部异常

2.1、Controller

@Controller public class HelloController {@GetMapping("/hello") public String hello(){int result=10/0; return "index"; } /** * java.lang.ArithmeticException * 该方法需要返回一个 ModelAndView:目的是可以让我们封装异常信息以及视 图的指定 * 参数 Exception e: 会将产生异常对象注入到方法中 */ @ExceptionHandler(value={java.lang.ArithmeticException.class}) public ModelAndView arithmeticExceptionHandler(Exception e){ModelAndView mv = new ModelAndView(); mv.addObject("error", e.toString()); mv.setViewName("error"); return mv; } }

2.2、修改 error.html

<!DOCTYPE html> <html lang="en" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title> 错误页面 </title> </head> <body> <span th:text="${error}"></span>, 请与管理员联系...... </body> </html>

3、处理全局异常

3.1、@ControllerAdvice+@ExceptionHandler:

@ControllerAdvice public class GlobalException {/** * java.lang.ArithmeticException * 该方法需要返回一个 ModelAndView:目的是可以让我们封装异常信息以及视 图的指定 * 参数 Exception e: 会将产生异常对象注入到方法中 */ @ExceptionHandler(value={java.lang.ArithmeticException.class}) public ModelAndView arithmeticExceptionHandler(Exception e){ModelAndView mv = new ModelAndView(); mv.addObject("error", e.toString()); mv.setViewName("error"); return mv; } }

3.2、配置 SimpleMappingExceptionResolver 处理异常

在全局异常类中添加一个方法完成异常的统一处理, 代码如下:

@Configuration public class GlobalException {/** * 该方法必须要有返回值。返回值类型必须是:* SimpleMappingExceptionResolver */ @Bean public SimpleMappingExceptionResolver getSimpleMappingExceptionResolver() {SimpleMappingExceptionResolver resolver = new SimpleMappingExceptionResolver(); Properties mappings = new Properties(); /** * 参数一:异常的类型,注意必须是异常类型的全名 * 参数二:视图名称 */ mappings.put("java.lang.ArithmeticException", "error"); // 设置异常与视图映射信息的 resolver.setExceptionMappings(mappings); return resolver; } }

3.3、自定义 HandlerExceptionResolver 类处理异常

在全 局 异 常 处 理 类 中 实 现 HandlerExceptionResolver 接口, 代码如下:

@Configuration public class GlobalException implements HandlerExceptionResolver {@Override public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {ModelAndView mv = new ModelAndView(); // 判断不同异常类型,做不同视图跳转 if(ex instanceof ArithmeticException){mv.setViewName("error"); } mv.addObject("error", ex.toString()); return mv; } }

4、Spring Boot 应用正常退出

查看 SpringApplication 源码

public class SpringApplication { ...... // 退出方法 public static int exit(ApplicationContext context, ExitCodeGenerator... exitCodeGenerators) {// 断言 conext 不能为 null Assert.notNull(context, "Context must not be null"); byte exitCode = 0; int exitCode; try {try {// 创建退出码生成器 ExitCodeGenerators generators = new ExitCodeGenerators(); // 从 Spring 容器中获取所有的退出码生成器实例 Collection<ExitCodeGenerator> beans = context.getBeansOfType(ExitCodeGenerator.class).values(); generators.addAll(exitCodeGenerators); generators.addAll(beans); // 获得退出码 exitCode = generators.getExitCode(); // 如果退出码不为 0 if (exitCode != 0) {// 发布退出码事件监听 context.publishEvent(new ExitCodeEvent(context, exitCode)); } } finally {close(context); } } catch (Exception var9) {var9.printStackTrace(); exitCode = exitCode != 0 ? exitCode : 1; } // 返回退出码 return exitCode; } }

案例:

验证程序退出时 ExitCodeGenerators 的 getExitCode() 方法执行了

@EnableAutoConfiguration public class ExiteCodeGeneratorBootstrap {@Bean public ExitCodeGenerator exitCodeGenerator(){System.out.println("ExitCodeGenerator Bean 创建..."); return ()->{System.out.println("执行退出码 88"); return 88; }; } public static void main(String[] args) {// 在非 Web 应用中退出 SpringApplication.exit(new SpringApplicationBuilder(ExiteCodeGeneratorBootstrap.class) .web(WebApplicationType.NONE) .run(args)); } }

5、Spring Boot 应用异常退出

源码:

private void handleRunFailure(ConfigurableApplicationContext context, Throwable exception, Collection<SpringBootExceptionReporter> exceptionReporters, SpringApplicationRunListeners listeners) {try {try {// 处理退出码 this.handleExitCode(context, exception); // 如果 Spring 应用运行监听器不为 null if (listeners != null) {// 监听异常退出 listeners.failed(context, exception); } } finally {// 报告错误 this.reportFailure(exceptionReporters, exception); // 关闭 Spring 上下文 if (context != null) {context.close(); } } } catch (Exception var9) {logger.warn("Unable to close ApplicationContext", var9); } ReflectionUtils.rethrowRuntimeException(exception); } // 退出码处理方法 private void handleExitCode(ConfigurableApplicationContext context, Throwable exception) {// 从异常中获取退出码 int exitCode = this.getExitCodeFromException(context, exception); if (exitCode != 0) {if (context != null) {// 如果退出码不为 0,context 不为 null,发布退出码事件监听 context.publishEvent(new ExitCodeEvent(context, exitCode)); } // 获取 SpringBoot 异常处理器 SpringBootExceptionHandler handler = this.getSpringBootExceptionHandler(); if (handler != null) {// 如果处理器不为 null,注册退出码 handler.registerExitCode(exitCode); } } } // 从异常中获得退出码 private int getExitCodeFromException(ConfigurableApplicationContext context, Throwable exception) {// 从 MappedException 获得退出码 int exitCode = this.getExitCodeFromMappedException(context, exception); // 如果 exitCode==0 if (exitCode == 0) {// 从异常退出码生成器中获取退出码 exitCode = this.getExitCodeFromExitCodeGeneratorException(exception); } // 退出码 return exitCode; } private int getExitCodeFromExitCodeGeneratorException(Throwable exception) {// 如果 exception==null, 直接返回 0 if (exception == null) {return 0; } else {// 从退出码生成器中获得退出码 return exception instanceof ExitCodeGenerator ? ((ExitCodeGenerator)exception).getExitCode() : this.getExitCodeFromExitCodeGeneratorException(exception.getCause()); } }

由源码可知当异常实现 ExitCodeGenerator 接口时, 退出码直接采用 getExitCode() 方法返回。

正文完
星哥玩云-微信公众号
post-qrcode
 0
星锅
版权声明:本站原创文章,由 星锅 于2022-06-06发表,共计5377字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中

星哥玩云

星哥玩云
星哥玩云
分享互联网知识
用户数
4
文章数
19348
评论数
4
阅读量
7822048
文章搜索
热门文章
开发者必备神器:阿里云 Qoder CLI 全面解析与上手指南

开发者必备神器:阿里云 Qoder CLI 全面解析与上手指南

开发者必备神器:阿里云 Qoder CLI 全面解析与上手指南 大家好,我是星哥。之前介绍了腾讯云的 Code...
星哥带你玩飞牛NAS-6:抖音视频同步工具,视频下载自动下载保存

星哥带你玩飞牛NAS-6:抖音视频同步工具,视频下载自动下载保存

星哥带你玩飞牛 NAS-6:抖音视频同步工具,视频下载自动下载保存 前言 各位玩 NAS 的朋友好,我是星哥!...
云服务器部署服务器面板1Panel:小白轻松构建Web服务与面板加固指南

云服务器部署服务器面板1Panel:小白轻松构建Web服务与面板加固指南

云服务器部署服务器面板 1Panel:小白轻松构建 Web 服务与面板加固指南 哈喽,我是星哥,经常有人问我不...
我把用了20年的360安全卫士卸载了

我把用了20年的360安全卫士卸载了

我把用了 20 年的 360 安全卫士卸载了 是的,正如标题你看到的。 原因 偷摸安装自家的软件 莫名其妙安装...
星哥带你玩飞牛NAS-3:安装飞牛NAS后的很有必要的操作

星哥带你玩飞牛NAS-3:安装飞牛NAS后的很有必要的操作

星哥带你玩飞牛 NAS-3:安装飞牛 NAS 后的很有必要的操作 前言 如果你已经有了飞牛 NAS 系统,之前...
阿里云CDN
阿里云CDN-提高用户访问的响应速度和成功率
随机文章
星哥带你玩飞牛NAS-16:不再错过公众号更新,飞牛NAS搭建RSS

星哥带你玩飞牛NAS-16:不再错过公众号更新,飞牛NAS搭建RSS

  星哥带你玩飞牛 NAS-16:不再错过公众号更新,飞牛 NAS 搭建 RSS 对于经常关注多个微...
星哥带你玩飞牛NAS-11:咪咕视频订阅部署全攻略

星哥带你玩飞牛NAS-11:咪咕视频订阅部署全攻略

星哥带你玩飞牛 NAS-11:咪咕视频订阅部署全攻略 前言 在家庭影音系统里,NAS 不仅是存储中心,更是内容...
240 元左右!五盘位 NAS主机,7 代U硬解4K稳如狗,拓展性碾压同价位

240 元左右!五盘位 NAS主机,7 代U硬解4K稳如狗,拓展性碾压同价位

  240 元左右!五盘位 NAS 主机,7 代 U 硬解 4K 稳如狗,拓展性碾压同价位 在 NA...
星哥带你玩飞牛NAS-6:抖音视频同步工具,视频下载自动下载保存

星哥带你玩飞牛NAS-6:抖音视频同步工具,视频下载自动下载保存

星哥带你玩飞牛 NAS-6:抖音视频同步工具,视频下载自动下载保存 前言 各位玩 NAS 的朋友好,我是星哥!...
再见zabbix!轻量级自建服务器监控神器在Linux 的完整部署指南

再见zabbix!轻量级自建服务器监控神器在Linux 的完整部署指南

再见 zabbix!轻量级自建服务器监控神器在 Linux 的完整部署指南 在日常运维中,服务器监控是绕不开的...

免费图片视频管理工具让灵感库告别混乱

一言一句话
-「
手气不错
每天一个好玩的网站-手机博物馆-CHAZ 3D Experience

每天一个好玩的网站-手机博物馆-CHAZ 3D Experience

每天一个好玩的网站 - 手机博物馆 -CHAZ 3D Experience 一句话介绍:一个用 3D 方式重温...
150元打造低成本NAS小钢炮,捡一块3865U工控板

150元打造低成本NAS小钢炮,捡一块3865U工控板

150 元打造低成本 NAS 小钢炮,捡一块 3865U 工控板 一块二手的熊猫 B3 工控板 3865U,搭...
你的云服务器到底有多强?宝塔跑分告诉你

你的云服务器到底有多强?宝塔跑分告诉你

你的云服务器到底有多强?宝塔跑分告诉你 为什么要用宝塔跑分? 宝塔跑分其实就是对 CPU、内存、磁盘、IO 做...
星哥带你玩飞牛NAS硬件 01:捡垃圾的最爱双盘,暴风二期矿渣为何成不老神话?

星哥带你玩飞牛NAS硬件 01:捡垃圾的最爱双盘,暴风二期矿渣为何成不老神话?

星哥带你玩飞牛 NAS 硬件 01:捡垃圾的最爱双盘,暴风二期矿渣为何成不老神话? 前言 在选择 NAS 用预...
星哥带你玩飞牛NAS-16:不再错过公众号更新,飞牛NAS搭建RSS

星哥带你玩飞牛NAS-16:不再错过公众号更新,飞牛NAS搭建RSS

  星哥带你玩飞牛 NAS-16:不再错过公众号更新,飞牛 NAS 搭建 RSS 对于经常关注多个微...