简介
在Spring Boot
项目中实现统一的异常处理是一种常见的做法,这有助于保持代码的整洁并提供一致的错误响应格式。Spring Boot
中的统一异常处理是一种机制,用于集中管理和格式化应用程序中抛出的所有异常。这种机制可以提高程序的健壮性和用户体验,同时简化开发过程。
统一异常处理的一些主要作用:
- 一致性:
保证了在不同地方发生的异常都能以相同的方式被处理和响应。
用户或客户端接收到的错误信息和格式保持一致,有助于问题定位。 - 错误信息定制:
可以根据需要定制错误信息,包括HTTP状态码、错误代码和描述等。
这样可以更好地向用户解释发生了什么问题,并提供可能的解决方法。 - 日志记录:
在捕获异常后,可以根据异常类型和级别记录到日志文件中,便于后续分析和调试。
日志记录可以帮助追踪问题发生的时间点、环境和上下文。 - 资源释放:
在某些情况下,可以在异常处理过程中释放资源或者进行清理工作,确保系统稳定运行。 - API 文档化:
对于对外提供的 API,可以通过异常处理来定义预期的错误情况,这有助于生成清晰的 API 文档。 - 安全性:
可以避免敏感信息泄露给客户端,例如数据库查询语句、内部类名等。
可以返回更泛化的错误信息,而不是具体的异常堆栈跟踪。 - 性能优化:
通过合理设计异常处理逻辑,可以减少不必要的资源消耗和调用链路,从而提升整体性能。
实现
1.创建自定义异常类
根据项目场景创建一些自定义异常类 extends
RuntimeException
WarnException
警告类异常
@Data
public class WarnException extends RuntimeException{
public WarnException(String msg){
super(msg);
}
}
返回告警信息,
日志记录WARN
级别日志,且不打印堆栈
异常概要信息不会落库
UserException
用户业务类异常
@Data
public class UserException extends RuntimeException {
public UserException(String msg) {
super(msg);
}
@Override
public String toString() {
return getClass().getName() + StringConstant.COLON +this.getMessage();
}
}
返回告警信息,
日志记录ERROR
级别日志,且打印堆栈
异常概要信息落库
StringConstant.COLON = ":"
PlatformException
系统内部异常
@Data
public class PlatformException extends RuntimeException {
public PlatformException(String msg) {
super(msg);
}
@Override
public String toString() {
return getClass().getName() + StringConstant.COLON +this.getMessage();
}
}
返回告警信息,
日志记录ERROR
级别日志,且打印堆栈
异常概要信息落库
StringConstant.COLON = ":"
2.创建全局异常处理器
定义一个带有 @ControllerAdvice
注解的类,并在其中声明一个或多个带有 @ExceptionHandler
注解的方法来处理特定类型的异常
ZKExceptionHandler
统一异常处理类
@ControllerAdvice
@Slf4j
public class ZKExceptionHandler {
@Autowired
private AlarmMsgService alarmMsgService;
@ExceptionHandler(value = Exception.class)
@ResponseBody
public <T> MsgData<T> handleException(Exception e) {
//预期内告警类异常不计入数据库;日志不记录堆栈
if (e instanceof WarnException) {
WarnException warnException = (WarnException) e;
log.warn(warnException.getMessage());
return MsgData.fill(warnException.getMessage());
}
String msg = e.getMessage();
String exceptionName = e.getClass().getName();
String stackTrace = ExceptionUtils.getStackTrace(e);
//用户异常
if (e instanceof UserException) {
alarmMsgService.saveUserAlarmMsg(msg, AlarmLevelEnum.ALARM, exceptionName, stackTrace);
log.error("UserException", e);
return MsgData.fill(msg);
}
//平台类异常
if (e instanceof PlatformException) {
alarmMsgService.savePlatformAlarmMsg(msg, AlarmLevelEnum.ALARM, exceptionName, stackTrace);
log.error("PlatformException", e);
return MsgData.fill(msg);
}
//其他异常
alarmMsgService.saveOtherAlarmMsg("系统异常", AlarmLevelEnum.ALARM, exceptionName, stackTrace);
log.error("OtherException", e);
return MsgData.fill(msg);
}
}
alarmMsgService
为异常概要信息入库操作,可自定义替换为自己的数据库操作
这里会对三种自定义异常分别进行处理,用于达到信息返回及记录预期
对于其他异常也会进行兜底记录及处理
MsgData
返回实体类
@Data
public class MsgData<T> {
private int status;
private String errorCode;
private String msg;
private T data;
public static <T> MsgData<T> success() {
return success(null);
}
public static <T> MsgData<T> success(T data) {
return success(null, data);
}
public static <T> MsgData<T> success(String msg) {
return success(msg, null);
}
public static <T> MsgData<T> success(String msg, T data) {
return success(HttpCodeConstant.SUCCESS, msg, data);
}
public static <T> MsgData<T> success(int status, String msg, T data) {
MsgData<T> msgData = new MsgData<>();
msgData.setStatus(status);
msgData.setMsg(msg);
msgData.setData(data);
return msgData;
}
public static <T> MsgData<T> fill(String msg) {
return fill(null, msg);
}
public static <T> MsgData<T> fill(String errorCode, String msg) {
return fill(HttpCodeConstant.ERROR, errorCode, msg, null);
}
public static <T> MsgData<T> fill(int status, String errorCode, String msg, T data) {
MsgData<T> msgData = new MsgData<>();
msgData.setStatus(status);
msgData.setErrorCode(errorCode);
msgData.setMsg(msg);
msgData.setData(data);
return msgData;
}
}
HttpCodeConstant.SUCCESS = 200
HttpCodeConstant.ERROR = 500
使用
通过throw
不同的Exception
进行区分不同的异常
// 警告类异常
throw new WarnException("测试WARN告警");
// 用户业务类异常
throw new UserException("测试用户告警");
// 平台系统类异常
throw new PlatformException("测试平台告警");
// 其他异常
throw new RuntimeException("测试系统告警");
结束
标签:return,SpringBoot,MsgData,String,msg,异常,public,统一 From: https://www.cnblogs.com/zktww/p/18361699