Springboot异常处理:

1、局部异常处理:

直接对Controller类进行操作

2、全局统一异常处理

Springboot两种全局异常统一处理的方式:

A使用继承BasicErrorController 来实现

B通过@ControllerAdvice 注解来处理统一错误(Advice 异常处理)

(1)Java 异常的 Root 是 Throwable, 其下有 Error 和 Exception. Error 是 JVM 级的致命错误, 应用系统内部一般不用关心这类错误. Exception 是异常的父类, 其下分为两类, 一类是 Runtime Exception, 一类是 Checked Exception. Checked Exception 是那些编译器能检查到的异常, 如果一个函数中抛出了这类异常, 我们要么 catch 它, 要么在函数签名上继续抛出去, 否则程序将不能编译通过。

Runtime Exception 有, 包括 RuntimeException 和它的子类. 比如 ArrayIndexOutOfBoundsException/ClassCastException/被 0 除等. 
Checked Exception 有: Exception 类和所有非 RuntimeException 类的异常都属于 checked exception, 比如 IoException 等.

(2)dao、service、controller出现的未知异常都通过throws Exception向上抛出,最后由springmvc前端控制器交由异常处理器进行异常处理,springmvc提供全局异常处理器进行统一的异常处理,一个系统只有一个异常处理器。Springboot也有统一的异常处理器ControllerAdvice。

一般思路:系统有自定义异常时,在程序中手动抛出throw MyException,对于未知异常通过在函数上声明throws Exception向上抛出,dao抛给service,service再抛给Controller,最后Controller抛给前端控制器,前端控制器调用全局异常处理器进行处理。

(3)异常处理的一般实践步骤。

===================================
自定义类的最佳实践:
===================================
1. 先定义一个基类 BusinessException, 继承自 RuntimeException. 
2. 定义一套BusinessErrorCode 枚举类型, 包含 BusinessErrorCode/HttpStatus/BusinessErrorMessage, 这里的 BusinessErrorCode 不同于 HttpStatus, 它是业务上的错误代码 (int 型). 
2. 在 BusinessException 基类上, 加上绑定 BusinessErrorCode 枚举类型的机制. 
3. 基于 BusinessException 定义一组子类, 比如 UserNotLoginException/PermissionForbiddenException/DataNotFoundException 等等, 并将这些子类加入到一个 BusinessExceptionEnum 枚举中, 方便使用.

===================================
Spring 项目数据验证最佳实践
===================================
1. 针对 UI 输入检查, 如果 js 前端检查有困难, 可以在 Controller 层使用 Pojo validation 手段做检查, 然后前端使用 ajax 拿到校验结果. 检查过程没有触发 UI 完整渲染, 用户体验会很好. 
2. Controller 层使用 validation 进行检查, 可以在视图函数的形参上检查, 或者在视图函数内部检查. 
3. Service 层, 使用 org.springframework.util.Assert 进行数据验证, 比如 Assert.notNull(user, "user is not null.");
4. DAO 层, 不做任何数据验证, 因为所有数据问题应该在Service层或Controller层做个验证.

===================================
Spring 各层封装的手法
===================================
1. DAO 层, 函数的形参最好以 DO 类做参数, 而不是传入很多个字段参数. 这样的好处是, 避免Table增删字段, DAO层函数定义也要跟着修改, 上层的调用代码也要修改. 
2. DAO 层, insert 和 update 要独立为两个函数. 到底是新增还是更新, 应由 Service 层进行逻辑控制. 
3. Service 层函数的形参, 到底是使用 DO 类, 还是简单的属性清单, 看具体情况吧.

===================================
Spring 日志和异常处理的最佳实践
===================================
异常处理的基本思路是: 早抛出, 晚捕获. 日志输出的基本思路是, 详尽但不冗余. 
落实到具体的项目中, 在不同分层中, 应采用不同的规则, 一般的分层有: DAO -> Service -> Controller -> 统一异常 Controller 层.

1. DAO 层: 
   (1) 尽量不 catch 任何异常, 该向上抛就抛. 
   (2) 不用记录 log 日志, 或者仅使用 logger.debug() 记录

2. Service 层的做法: 
    (1) @Transactional 注解应该加在 Service 层上. 
    (2) 对于一些关键问题, 比如 Checked Exception 或者数据的问题, 应该及时 throw new BusinessException 异常, 以确保事务完整. 
    (3) throw new BusinessException 时的日志, 为了避免日志重复, 不需要 log 日志输出. 
    (4) Service 层一般的日志级别, 应该用 logger.debug() 记日志. 
    (5) Service 层函数的返回值应该是 Optional 类型, 方便 Controller 做 null 判断.

3. Controller 层: 
   (1) Controller 层负责组装 Service, 在关键步骤上应该加日志输出 (info 级别) 
   (2) Controller 层不应再主动 throw 异常. 
4. 统一异常 Controller 层: 
   (1) 通过 json 或 UI 返回详细的报错信息, 包括 HttpStatus 和详尽的 BusinessErrorCode/BusinessErrorMessage 以及 DetailErrorMessage(来源于 exception.getMessage()), 甚至包括 exception 的 stack trace. 
   (2) 对于 Exception 类的异常, 说明这是我们预料之外的报错, 应该使用 logger.error() 级别记录; 
   (3) 对于 BusinessException 和子类的异常, 则说明我们的程序已经预料到了, 事物该回滚也已经回滚了, 所以应该以 logger.warn() 或 logger.info() 记录日志. 
   (4) 对于 Spring Boot 缺省的 /error 进行定制, 增加一些"系统主页"和"返回"的链接, 改善用户体验.

(4)一些重要的注意事项:

Adao层一般不需要抛出异常,有事务的情况下,会将service的异常抛出到控制层做处理的,不然可能会影响事务的回滚,如果不存在事务,则可以直接在service层进行处理。

B针对预期可能发生的异常(检查类型(checked)),在代码手动处理异常可以try/catch捕获,可以向上抛出,可以声明。

try-catch 是在当前位置处理异常,尝试能不能正常的走完整个作用域,如果不能则抛出一个异常。
throws是向上抛出异常,用来声明一个方法可能产生的所有异常,不做任何处理而是将异常往上传,谁调用我我就抛给谁,throws在方法后边声明异常,其实就是自己不想对异常做出任何的处理,告诉别人自己可能出现的异常,交给别人处理

throw 就是抛出一个具体的异常,并获取这个异常的引用,这个异常会被抛到外部的环境,由外部环境进行处理。

C 在service中如果声明了@Transactional,但是又在方法里面自己捕获了异常,也就是try catch掉了,那就不会回滚了,因为切入点根本没捕获到,也谈不上调用增强处理中的方法了。解决:1.抛出RuntimeException 2.抛出Exception,同时在事务声明中加上@Transactional(rollbackFor = Exception.class)

SpringBoot异常处理的简单理解相关推荐

  1. SpringBoot异常处理ErrorController详解

    文章目录 一.背景 二.SpringBoot的默认异常处理BasicErrorController 三.自定义错误异常 写在前面: 我是「境里婆娑」.我还是从前那个少年,没有一丝丝改变,时间只不过是考 ...

  2. SpringBoot异常处理以及对数据正确性的检查

    SpringBoot异常处理以及对数据正确性的检查 一个项目中的异常处理是非常沉重的话题,每次做项目中如果异常处理的不好,轻微一点的会让测试人员找到你的问题,严重点的会把报错的日志打印给客户展示,这可 ...

  3. SpringBoot框架实现简单业务逻辑

    SpringBoot框架实现简单业务逻辑 总述 Entity层 Dao层 Mapper.xml Service层 ServiceImpl Controller层 完整的业务逻辑实现写法示例 Dao层声 ...

  4. Spring Security并没有那么难嗷 简单理解OAuth2.0

    文章目录 1. 基本概念 1.1 什么是认证 1.2 什么是会话 1.3 什么是授权 1.4 授权的数据模型 1.5 RBAC 1.5.1 基于角色的访问控制 1.5.2 基于资源的访问控制 2. 基 ...

  5. 谈谈你对Java异常处理机制的理解

    谈谈你对Java异常处理机制的理解 先谈谈我的理解:异常处理机制可以说是让我们编写的程序运行起来更加的健壮,无论是在程序调试.运行期间发生的异常情况的捕获,都提供的有效的补救动作,任何业务逻辑都会存在 ...

  6. android 点击事件消费,Android View事件分发和消费源码简单理解

    Android View事件分发和消费源码简单理解 前言: 开发过程中觉得View事件这块是特别烧脑的,看了好久,才自认为看明白.中间上网查了下singwhatiwanna粉丝的读书笔记,有种茅塞顿开 ...

  7. 【转载】Deep learning:十九(RBM简单理解)

    Deep learning:十九(RBM简单理解) 这篇博客主要用来简单介绍下RBM网络,因为deep learning中的一个重要网络结构DBN就可以由RBM网络叠加而成,所以对RBM的理解有利于我 ...

  8. 学习:双机热备、集群、负载均衡、SQL故障转移群集简单理解(转)

    双机热备.集群.负载均衡.SQL故障转移群集简单理解平常,大家常提到几个技术名词:双机热备.集群.负载均衡.SQL故障转移群集.这里,就我的理解,和大家简单探讨下,有不足或错误之处还请各位指出! 这些 ...

  9. 字符串匹配算法Java_如何简单理解字符串匹配算法?

    这篇文章来说说如何简单理解KMP,BM算法.之前看过一些文章说,KMP算法很难理解. 可我并不觉得. 我反而觉得它容易理解.平时我们写java代码的时候, 判断一个字符串是否存在包含另一个字符串都是直 ...

最新文章

  1. PCIe配置空间和PCI设备中的寄存器
  2. 蓝色版苹果iPhone 12开箱上手视频流出;谷歌回应司法部反垄断诉讼:存在严重漏洞;​Git 2.29 稳定版发布|极客头条
  3. java网络通信:异步非阻塞I/O (NIO)
  4. 自然语言生成任务,如文本摘要和图像标题的生成。seq2seq的模型原理
  5. 文本分析软件_读书笔记:伍多库卡茨质性文本分析:方法、实践与软件使用指南...
  6. 简述单片微型计算机屏蔽的作用,单片机原理及应用试题库 - 答案
  7. mac os 开启FTP Server
  8. 联想 android 5.1 root权限,联想a520一键root权限获取教程(图文)
  9. pooleddb mysql_使用dbutils的PooledDB连接池,操作数据库
  10. SQL server数据库增删改查练习
  11. 计算机三级考点一:宽带城域网的结构
  12. halcon识别斜着的车牌
  13. mysql ehcache_EhCache使用心得
  14. python 隐藏其他窗口_python控制窗口显示隐藏
  15. tinyMediaManager 群晖 docker
  16. cpuid limit_Max CPUID Valut Limit 请懂电脑的解答下 谢谢!
  17. 戴尔G3游戏本蓝屏现象频繁解决方案(最新篇)
  18. 无线降噪蓝牙耳机评测,南卡、JBL、OPPO、荣耀降噪蓝牙耳机推荐
  19. 小米笔记本和手机通过蓝牙传输文件
  20. springboot上传头像

热门文章

  1. 我们如何衡量一个微服务实施的成功
  2. Ubuntu ls可以查看到文件,图形界面却看不到
  3. 读书笔记 — Java高并发程序设计 — 第三章 — 锁
  4. Segmentation fault (core dumped)
  5. Microsoft Dynamics CRM server 2013   一般销售流程之 订单 简单介绍
  6. .Net下的签名与混淆
  7. HDU 3788 ZOJ问题
  8. 尝试为文件附加自动命名的数据库,但失败。已存在同名的数据库,或指定的文件无法打开或位于 UNC 共享目录中...
  9. directly to phd is good for laying a solid foundation for future career
  10. UNITY编辑器模式下static变量的坑