异常是什么
异常就是一个应用程序在运行过程中,出现了一些预期之外的故障,导致程序无法按照正常的逻辑运行,从而使一个流程中断达不到最终所要的结果。

为什么要处理异常
这个最直接的答案就是为了保障程序能够正常运行。不管是一个简单或复杂的应用程序,它的出现都是有一定的道理,能够解决相关的问题(产品、客户需求)。相信任何一个开发人员都无法保证一开始程序就100%没有问题,更何况体量稍大的应用都会依赖一些第三方服务,或者我们常见的微服务也是,一旦我们的程序对外部有依赖就避免不了异常的发生,原因是外部依赖的服务不是我们的可控范围,这时候就必须处理异常,也就是通过异常处理将应用程序的故障降到最低。就像程序过多的依赖中间件,如果出现异常没有做好保护措施,那么可能导致服务器宕机数据库挂掉都有可能。

异常种类
在java中异常体系结构大致如下图:

Throwable:作为所有异常的父类,就是说所有的异常类都是通过一次或多层次继承Throwable类实现的。
Error:jdk内部的异常类型,在出现这种异常的情况那是无法处理的,就比如程序运行过程中出现OutOfMemoryError开发人员也奈何不了,JVM就会将应用程序终止掉,这时候可能我们就要花费大把时间排查那个对象过大导致内存溢出了,所以这一类的异常在开发过程中也无需处理。
Exception:主要分为运行时异常和非运行时异常两大类,非运行时异常即是在我们代码编写完成后,使用javac命令对代码进行编译(通常Idea、Eclipse等代码编辑软件都会实时编译检测代码非运行时的异常),只有编译通过的代码才能正常进入JVM运行。
RuntimeException:常见的运行时异常有NullPointerException(空指针异常)、IndexOutOfBoundsException(下标越界异常)、ClassCastException(类型转换异常)、IllegalArgumentException(非法参数)等。
非运行时异常:也称做检查性异常,例如ClassNotFoundException(找不到类异常)、SQLException(数据库访问异常)等。
异常处理方案
防止异常的出现
首先对于一些常见的异常,开发人员是可以认为控制好防止它的出现,比如说NullPointerException、IndexOutOfBoundsException等等,在参数使用之前做好预防措施即可保证此类异常不会出现。

异常捕获
对于一些开发人员无法直接预测到的异常,比如jdk内部或第三方框架抛出的检查性异常我们必须进行异常捕获,并对异常进行处理,得到我们想要的结果,如下一段读取文件内容的代码:

private static String readFile(String path) {
File file = new File(path);
FileInputStream fis;
// 创建FileInputStream会打开一个文件,程序会显示的检测异常,提示需要对文件不存在异常进行处理,这里就需要主动进行异常捕获,否则就必须使用throws对该异常向上一层抛出,供调用者去处理
try {
fis = new FileInputStream(file);
}
catch (FileNotFoundException e) {
log.error(“file is not found.”);
return null;
}
// 正常继续执行
StringBuilder sb = new StringBuilder();
// 读取文件流的时候,程序会显示的检测可能出现IO异常,开发人员就必须对此异常进行捕获处理
try {
byte[] bt = new byte[1024];
int read;
while ((read = fis.read(bt)) != -1) {
sb.append(new String(bt));
}
}
catch (IOException e) {
log.error(“file read exception.”);
return null;
}
// 同理关闭文件的时候也可能出现IO异常需要处理
try {
fis.close();
}
catch (IOException e) {
log.error(“file close exception.”);
}
return sb.toString();
}
以上的代码块都是简单的捕获异常,并进行一系列的日志输出,让程序正常运行下去,调用者可以根据返回结果是否为null判断是否有文件内容要输出。

异常管理
通常应用程序出现问题,用户在页面上是不想看到一堆杂乱不齐的代码,看也看不懂什么意思,这时候我们通常需要对异常进行一个统一管理,开发人员可以前后端约定好接口成功以及失败的代码编号。

比如说接口访问成功就返回code=success,前端也可以根据访问成功进行下一步的流程。
除了code=success其余的均为失败,失败也可以根据特定的代码进行划分,前端也可对特定的异常类型做处理,比如说用户未登录后端返回code=unlogin,前端检测到此代码即可直接跳转至登录页。
全局异常处理
在Spring应用程序中我们可以配置一个全局的异常拦截方案,使用@ControllerAdvice注解设计一个异常处理类GlobalExceptionHandler,结合上一点异常管理对异常再做进一步优化。如下定义一个异常公共类:

public class BaseException extends RuntimeException {
// 错误代码
private String code;
// 错误内容
private String message;

public BaseException(String code, String message) {this.code = code;this.message = message;
}

}
如果业务模块划分比较多,我们还可以继承BaseException类实现业务侧特殊的异常输出。紧接着如下对业务异常统一管理:

@ControllerAdvice
public class GlobalExceptionHandler {
// 配置拦截特定异常类型
@ExceptionHandler(BaseException.class)
@ResponseBody
// 返回对应的http状态为200,前端根据返回的code做处理
@ResponseStatus(HttpStatus.OK)
public CommonResult baseExceptionHandler(BaseException exception) {
// log输出日志文件记录
log.error("baseExceptionHandler: ", exception);
return CommonResult.builder()
.code(exception.getCode())
.msg(exception.getMessage()).build();
}

// 无法预料的异常,就按Exception类进行拦截,并返回错误代码999999
@ResponseBody
@ExceptionHandler(Exception.class)
@ResponseStatus(HttpStatus.OK)
public CommonResult<Object> exceptionHandler(Exception exception) {log.error("exceptionHandler: ", exception);// 没有错误信息,则使用默认错误信息填充String message = exception.getMessage();return CommonResult.builder().code("999999").msg(StringUtils.isEmpty(message) ? "system error!" : message).build();
}
// 更多的异常类型需要进行独特的处理可以参照上面的进行配置,主要还是要跟前端人员配合好

}
总结
没有哪个程序100%没有漏洞的,只有一次次的积累不断的把程序优化的更好,尽可能的把错误率降低,以及把错误的影响范围降至最低,最终得以保证程序能够健壮的运行下去。

如何设计好系统异常处理相关推荐

  1. 架构设计:系统间通信(20)——MQ:消息协议(下)

    (接上文<架构设计:系统间通信(19)--MQ:消息协议(上)>) 上篇文章中我们重点讨论了"协议"的重要性,并为各位读者介绍了Stomp协议和XMPP协议.这两种协议 ...

  2. 寿险业务系统异常处理方案

    我们的系统使用的java语言开发,基于Spring框架搭建的业务中台,在讨论业务系统异常处理策略之前,先把java的异常机制进行简单说明. 一.Java的异常机制 1.Java异常分类 [Error] ...

  3. MIT将AI引入中学课堂,除了设计AI系统,还要学生思考背后的伦理

    大数据文摘出品 来源:MIT 编译:曹培信 近日,姚期智领衔主编.清华姚班师资做编委的高中AI教材在清华举行了签约仪式,AI走进高中课堂又迈出了坚实的一步.近期,MIT的研究人员也开发了一个AI课程, ...

  4. 请设计各种管理系统、业务系统的大哥大姐们,设计新系统时,拜托您,请允许我修改用户名、密码...

    大概在2-3年前,我在宁波最大的一家IT公司工作,我们公司日常开发人员经常会使用的系统有很多,夸张的 说接近10个吧,有些是自己公司开发的,有些是成熟的商品化软件,这些系统又由不同的维护人员维护,新员 ...

  5. 微服务架构案例(02):业务架构设计,系统分层管理

    本文源码:GitHub·点这里 || GitEE·点这里 更新进度(共6节): 01:项目技术选型简介,架构图解说明 02:业务架构设计,系统分层管理 一.业务架构设计 1.基础概念 服务的架构设计决 ...

  6. 从0到1设计业务系统

    从事基因检测产品经理岗位一年多,工作重心逐渐从前端产品设计转移到后端的业务系统产品设计.由于行业的特殊性,很难在市面上找到符合公司实际业务需求的第三方业务管理系统,所以公司决定自己内部团队开发符合自己 ...

  7. 设计OA系统的用户-角色-权限分配

    转载:http://www.cnblogs.com/jsping/archive/2013/01/23/2872972.html 设计OA系统的用户-角色-权限分配 一,前言  本文主要讲述在OA系统 ...

  8. java课程设计 考试系统,java课程设计考试系统.

    java课程设计考试系统.Tag内容描述: 1.目 录 第一章第一章 引言引言 3 1 1目的 3 1 2名词解释 3 1 3参考资料 3 1 4文档结构 3 第第 2 章章远景远景 4 2 1项目概 ...

  9. VI设计中系统视觉基本要素优漫动游

      很多同学对于VI设计中系统视觉基本要素还是不太了解,可能大家对于学习VI设计还带着很多小疑问,别担心,今天给大家一一解答.   企业标志   企业标志,可分为企业自身的标志和商品标志.   企业标 ...

最新文章

  1. SQLServer 扫盲
  2. 覆盖(override)和重载(overload)
  3. hadoop 1.x升级至hadoop-2.2.0记录
  4. linux--cut命令
  5. Windows进程与线程学习笔记(一)—— 进程结构体
  6. python运行报错
  7. POJ - 2187 Beauty Contest(最远点对)
  8. 常用公有云接入——AZURE
  9. 降低软件复杂性一般原则和方法
  10. 使用 redis 减少 秒杀库存 超卖思路 (转)
  11. 屏幕分辨率修改工具SwitchResX for Mac
  12. 分布式光纤传感技术(DTS/BOTDA/BOTDR/光栅/OTDR)近几年会有较快的发展(本人预测)
  13. 京东商品分类API接口-(cat_get-获得jd商品分类API接口),京东分类API接口
  14. 无线射频专题《无线局域网排错,第二层重传问题7@远近问题》
  15. 打造数字化软件工厂 —— 一站式 DevOps 平台全景解读
  16. ESXI6.7.0 升级到7.0U3f(2022年7月12 更新)
  17. Notes from Google Play | Google Play 持续助力您的应用和游戏
  18. Smartphone--Android真机管理平台
  19. 双曲三角函数图像及计算
  20. NFC framework introduce(二)

热门文章

  1. 面向对象的三个基本概念
  2. 3D模型欣赏:Cyber-boy机车不良风男孩
  3. 机器人中的yaw/pitch/roll
  4. rx6800s什么水平N卡 rx6800s什么水平
  5. 中荷人寿山东省分公司开展保险消费者权益保护教育宣传周活动
  6. KB、kb和MB、Mb的区别
  7. grpc---客户端流式
  8. 淘宝新店运营怎么选品?API接口助您高效选品
  9. 页面中查看pdf,且可以上下翻页(不是一个pdf多页,是多个pdf)
  10. 这些安全管理方法,让你不怕勒索者