使用枚举类简单封装一个SpringBoot3 的全局异常处理
- 使用
@RestControllerAdvice
和@ExceptionHandler
处理全局异常
最终效果图
返回的信息包括了
- 1.五位的异常码
- 2.错误信息
- 3.无错误返回的数据
- 4.操作是否成功
异常处理核心代码
ErrorCodeEnum.java
(包含了异常状态码, 和异常错误信息)
这个类的作用就是统一管理系统中可能出现的所有异常
异常分为三大类
- 用户异常
- 系统异常
- 第三方异常
用异常状态码的第一位来区分是哪一种异常,每一种异常之间的步长设置为100,这样的好处就是异常多了,不容易混乱
package com.wzh.exception.core.common.constant;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
*
* 错误码枚举类
* 错误码设置为5位, 错误产生来源 + 四位数字编号
* 产生来源 分为 A / B / C
* A: 错误来源于用户 (参数错误, 或者密码错误...)
* B: 错误来源于逻辑 (比如系统执行超时, 系统执行错误...)
* C: 错误来源于第三方 (比如阿里云短信错误)
*
* @author wzh
* @date 2023-06-07 20:31
*/
@Getter
@AllArgsConstructor
public enum ErrorCodeEnum {
/* 正确执行返回 */
OK("00000","ok"),
/* 用户一级宏观错误 */
USER_ERROR("A0001","用户错误"),
/* 用户二级宏观错误 注册错误 */
USER_REGISTER_ERROR("A0100","用户注册错误"),
/* 用户注册参数错误 */
USER_REGISTER_PARAM_ERROR("A0101","用户注册参数错误"),
USER_PARAM_ERROR("A0200","用户请求参数错误"),
/**
* ......其他用户错误
*/
/*系统一级错误*/
SYSTEM_ERROR("B0001","系统错误");
/* 错误码 */
private final String code;
/* 错误描述信息 */
private final String message;
}
RestResp
(返回给客户端的信息,封装了一下, 添加了异常返回信息)
这个类包括了成功,和不成功, 统一封装返回结果集
package com.wzh.exception.core.common.resp;
import com.wzh.exception.core.common.constant.ErrorCodeEnum;
import lombok.Getter;
import java.util.Objects;
/**
* @author wzh
* @date 2023-06-07 20:23
*/
@Getter
public class RestResp<T> {
/*响应码*/
private String code;
/*响应信息*/
private String message;
/*响应数据*/
private T data;
private RestResp(){
this.code = ErrorCodeEnum.OK.getCode();
this.message = ErrorCodeEnum.OK.getMessage();
}
/* 传入错误枚举类 */
private RestResp(ErrorCodeEnum errorCode){
this.code = errorCode.getCode();
this.message = errorCode.getMessage();
}
private RestResp(T data){
this();
this.data = data;
}
/*业务处理成功,无数据返回*/
public static RestResp<Void> ok(){
return new RestResp<>();
}
/*业务处理成功有数据返回*/
public static <T> RestResp<T> ok(T data){
return new RestResp<T>(data);
}
/*业务处理失败*/
public static RestResp<Void> fail(ErrorCodeEnum errorCode){
return new RestResp<>(errorCode);
}
/*系统错误*/
public static RestResp<Void> error(){
return new RestResp<>(ErrorCodeEnum.SYSTEM_ERROR);
}
/* 判断是否成功 */
public boolean isOk(){
return Objects.equals(this.code,ErrorCodeEnum.OK.getCode());
}
}
BusinessException.java
继承自RuntimeException
, 自定义异常类, 传入错误码枚举类
package com.wzh.exception.core.common.exception;
import com.wzh.exception.core.common.constant.ErrorCodeEnum;
import lombok.Data;
import lombok.EqualsAndHashCode;
/**
* @author wzh
* @date 2023-06-07 20:51
*/
@Data
@EqualsAndHashCode(callSuper = true)
public class BusinessException extends RuntimeException{
private final ErrorCodeEnum errorCodeEnum;
public BusinessException(ErrorCodeEnum errorCodeEnum){
super(errorCodeEnum.getMessage(),null,false,false);
this.errorCodeEnum = errorCodeEnum;
}
}
CommonExceptionHandler.java
全局异常捕获
- 1.捕获参数绑定异常
- 2.捕获系统异常
- 3.捕获自己抛出的异常
package com.wzh.exception.core.common.exception;
import com.wzh.exception.core.common.constant.ErrorCodeEnum;
import com.wzh.exception.core.common.resp.RestResp;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
/**
*
* 通用异常处理器
*
* @author wzh
* @date 2023-06-07 20:54
*/
@Slf4j
@RestControllerAdvice
public class CommonExceptionHandler {
/*
* 处理参数校验参数异常
*/
@ExceptionHandler(BindException.class)
public RestResp<Void> handlerBindException(BindException e){
log.error(e.getMessage());
return RestResp.fail(ErrorCodeEnum.USER_PARAM_ERROR);
}
/**
* 处理业务异常
*/
@ExceptionHandler(BusinessException.class)
public RestResp<Void> handlerException(BusinessException e){
log.error(e.getMessage(),e);
System.out.println(e.getErrorCodeEnum().getMessage());
return RestResp.fail(e.getErrorCodeEnum());
}
/**
* 处理系统异常
*/
@ExceptionHandler(Exception.class)
public RestResp<Void> handlerException(Exception e){
log.error(e.getMessage(),e);
return RestResp.error();
}
}
UserController.java
测试类
package com.wzh.exception.controller;
import com.wzh.exception.core.common.constant.ErrorCodeEnum;
import com.wzh.exception.core.common.exception.BusinessException;
import com.wzh.exception.core.common.resp.RestResp;
import com.wzh.exception.core.constant.ApiRouterConstants;
import com.wzh.exception.dao.entity.User;
import com.wzh.exception.service.UserService;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* @author wzh
* @date 2023-06-07 20:11
*/
@RestController
@RequestMapping(ApiRouterConstants.API_URL_FRONT_USER_PREFIX)
@RequiredArgsConstructor
public class UserController {
private final UserService userService;
@GetMapping("/list")
public RestResp<List<User>> getUserList(){
int ok = 1;
/* ...处理用户逻辑*/
//发现用户错误
if(ok == 0){
throw new BusinessException(ErrorCodeEnum.USER_ERROR);
}
try{
int a = 1 / 1;
}catch (Exception e){
/*发现系统执行出错, 抛出系统错误*/
RestResp.error();
}
User user = null;
if(user == null){
/*查询User不存在, 抛出用户错误*/
throw new BusinessException(ErrorCodeEnum.USER_ERROR);
}
return null;
}
}
代码地址:https://gitee.com/nclg/exception