自定义全局异常处理机制

2023年2月21日07:59:32

1.自定义异常的信息 枚举 ,将所用到的异常信息列出,统一管理,有异常添加到此枚举中即可

/**
 * 枚举:将可能选项一一的列出来 本质就是多例。
 * 比如:红绿灯:三种情况:红黄绿
 */
@Getter
public enum  ExceptionEnums {

    //列举不同情况  每种情况使用逗号分开
    OK(200, "操作成功!"),
    
    INVALID_PARAM_ERROR(400, "无效的请求参数!"),
    INVALID_PHONE_NUMBER(400, "无效的手机号码"),
    INVALID_VERIFY_CODE(400, "验证码错误!"),
    INVALID_USERNAME_PASSWORD(400, "无效的用户名和密码!"),
    INVALID_SERVER_ID_SECRET(400, "无效的服务id和密钥!"),
    INVALID_NOTIFY_PARAM(400, "回调参数有误!"),
    INVALID_NOTIFY_SIGN(400, "回调签名有误!"),
    
    SPEC_NOT_FOUND(400, "规格不存在!"),
    APPLICATION_NOT_FOUND(400, "应用不存在!"),

    DATA_TRANSFER_ERROR(500, "数据转换异常!"),
    INSERT_OPERATION_FAIL(500, "新增操作失败!"),
    UPDATE_OPERATION_FAIL(500, "更新操作失败!"),
    DELETE_OPERATION_FAIL(500, "删除操作失败!"),
    FILE_UPLOAD_ERROR(500, "文件上传失败!"),
    DIRECTORY_WRITER_ERROR(500, "目录写入失败!"),
    FILE_WRITER_ERROR(500, "文件写入失败!"),
    SEND_MESSAGE_ERROR(500, "短信发送失败!"),
    INVALID_ORDER_STATUS(500, "订单状态不正确!"),

    UNAUTHORIZED(401, "登录失效或未登录!");

    ;

    //提供属性
    private int status; //状态码
    private String message; //提示消息


    //提供属性私有构造 枚举类型通过私有有参构造注入值
    ExceptionEnums(int status, String message) {
        this.status = status;
        this.message = message;
    }
}

2.自定义异常的类,从异常 枚举 列表中读取异常信息

/**
 * 自定义异常类:包含http状态码,提示信息(父类中RuntimeException已经有message属性)
 */
@Data
public class LyException extends RuntimeException{

    //提供http状态码属性,动态设置
    private int status;

    //ExceptionEnums中包含 装填码 以及提示消息
    //public LyException(ExceptionEnums enums) {
    //    this.status = enums.getStatus();
    //}

    public LyException(ExceptionEnums enums) {
        super(enums.getMessage());
        this.status = enums.getStatus();
    }
}

3.统一异常处理机制,拦截所有异常信息

/**
 * 作用:controllerAdvice是SPringMVC提供异常处理机制:
 * 捕获所有项目模块controller产生的异常信息,将异常信息做定制给前端返回结果
 */
@ControllerAdvice
@ResponseBody
public class BasicExceptionHandler {

    /*
    //处理对应的异常类型:RuntimeException  ,没有封装完成的,指定状态码的异常信息
    @ExceptionHandler(RuntimeException.class)
    public ResponseEntity<String> error(RuntimeException e){
        return ResponseEntity.status(400).body(e.getMessage());
    }
    */ 
    
    /**
     * 处理其他自定义异常
     * 最后改良:将返回数据String改为自定义的ExceptionResult
     */
    @ExceptionHandler(LyException.class)
    public ResponseEntity<ExceptionResult> error(LyException e){
        return ResponseEntity.status(e.getStatus()).body(new ExceptionResult(e));
    }
}

4.自定义,异常返回的显示格式,以及显示的信息,更加规范化


@Getter
public class ExceptionResult {
    private int status;
    private String message;
    private String timestamp;

    //定义异常返回的显示格式,以及显示信息
    public ExceptionResult(LyException e) {
        this.status = e.getStatus();
        this.message = e.getMessage();
        //来源于 jodatime 工具包  也可自己设置
        this.timestamp = DateTime.now().toString("yyyy-MM-dd HH:mm:ss");
    }
}

5.代码中使用演示 , 业务中可能出现异常的地方,抛出自定义的异常,参数为自定义的枚举,也就是可能发生异常的状态码,以及异常信息

@RestController
public class ItemController {

    @Autowired
    private ItemService itemService;

    /**
     * ResponseEntity是SpringMVC提供请求响应对象
     * status:http响应状态码 返回状态码200 说明请求成功  如果其他状态码 说明请求失败
     * body:响应数据
     * 如果不使用ResponseEntity,一般我们会在项目中提供自定义结果对象 Result code:状态码
     */
    @PostMapping("/item")
    public ResponseEntity<Item> saveItem(@RequestBody Item item){
        //判断商品价格是否为空
        if(item.getPrice()==null){
            //给前端提示错误信息  RuntimeException 状态码是固定 500 想状态码程序员控制
            //throw new RuntimeException("商品价格为!!");
            //ExceptionEnums.PRICE_IS_NULL 枚举类型中包括价格不能为空的状态码 以及提示消息
            throw new LyException(ExceptionEnums.PRICE_IS_NULL);
        }
        if(item.getName()==null){
            throw new LyException(ExceptionEnums.NAME_IS_NULL);
        }
        Item item1 = itemService.save(item);
        return ResponseEntity.ok(item1);
    }
}

6.返回异常的标准结构
自定义全局异常处理机制

  • 作者:爱穿衬衫的张某某
  • 原文链接:https://blog.csdn.net/weixin_46649054/article/details/117757757
    更新时间:2023年2月21日07:59:32 ,共 3015 字。