异常:异常统一管理器 <进阶版>
1.异常谁处理?
不应该把异常抛给调用方(用户)、对应的前端,弊端:
- ×可能暴露内部的处理逻辑
- ×调用方不会处理异常
catch自己的异常:
-
成功进入方法体:×每一个controller类都手动做一个catch,处理繁琐!
-
进不了方法体:×捕获不到!
异常统一管理: -
不应该把所有异常都catch,而是都打印到日志里(后端会自己打出,前端需要设置)
-
√不用每个都写catch
-
√能拦截所有想拦截的异常
2. 异常发生2类情况(客户端/服务端)
2.1 客户端
2.1.1 客户端:正常传参
正常传参–进入controller类的方法体中,方法中逻辑返回JsonResponse(4种状态)
- 背景:
后端 返回给 前端 数据类型不一:boolean、集合等 ==》后端 向前端返回数据 必须统一:返回值(状态码,信息(状态码辅助解释),真正返回数据值(泛型))
- 状态码(针对前端发来的参数)
SUCCESS(200,"请求成功"),
ERROR(500,"请求失败"),
AUTH(401,"用户未登录或登陆超时"),
PERMISSION(403,"无此操作权限");
2.1.2 客户端:传参异常 —不进入方法体
- 服务端无法捕获异常对象,因此也不能给调用方法的用户一个处理(=告诉调用人属于什么错误,怎么处理)后的反馈。
- 用户:傻傻等。后端:给不了。无解
2.2 服务端(运行异常)
后端代码在运行时错误=服务端错误。
- 发生错误后没有被后端处理就直接报给前端控制台。
- 前端没有收到【展示到页面上的】反聩=没有错因提示页面(控制台有)
点击地址详情:
3. 前端必展现,处理后的异常提示----请求有反馈
只要有异常,无论前端传来参数异常(客户端异常),或者单纯后端异常(服务器异常)。后端都必须给前端【页面】展示出异常提示页面
4. springboot的controller类方法异常统一处理
4.1 @RestControllerAdvice+@ExceptionHandler
- advice:切面
4.1.1 @RestControllerAdvice属性—指定包(范围)
缩小拦截controller类的范围(只拦截自己写的类)
@RestControllerAdvice("com.cindy")
public class DefaultException {}
4.1.2 @ExceptionHandler属性----指定异常类型
- @ExceptionHandler(BusinessException.class)若指定:只拦截BusinessException这种异常类型
- @ExceptionHandler 若不指定:以标签下的方法的参数为准(传什么异常,拦截什么)
@ExceptionHandler(BusinessException.class)
ResultJson defaultExceptionHandler(BusinessException exception){}
4.1.3 拦截优先级 ----最小范围(子类)
报错提示:满足的最小范围(子类)的异常,与顺序无关
4.1.4 拦截所有
注意:不应该把所有异常都catch,而是都打印到日志里。有选择性catch。
@RestControllerAdvice --------包不指定
public class DefaultException {
@ExceptionHandler
ResultJson defaultExceptionHandler(Exception exception){
--------最大的异常类型Exception
}