当前位置:   article > 正文

springboot 自定义异常的实现_springboot 自定义异常 http 200

springboot 自定义异常 http 200


使用场景

前后端分离的项目,后端在处理过程需要给前端返回数据结果,但我们发现,在正常情况下只能返回200状态码,在异常情况下只能返回500状态码。显然这不满足我们的需求!


正常情况数据返回

spring提供的了ResponseEntity<T> 实体类来给前端返回相应的状态码

代码如下:

 @PostMapping("/save")
    public ResponseEntity<Long> saveItem(@RequestParam("id") Long id){
    
      return ResponseEntity.status(HttpStatus.NO_CONTENT).body(itemService.saveItem(id));
    }
  • 1
  • 2
  • 3
  • 4
  • 5

HttpStatus 枚举类

      status():设置状态码
      body(): 设置响应内容
     
      常用正确情况状态码:
         HttpStatus.OK: 200,用于查询成功
         HttpStatus.CREATED: 201,用于添加成功
         HttpStatus.NO_CONTENT:204,用于删除或修改成功
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

异常情况下数据返回

分析:
因为这里所有异常的状态码都是500,我们希望错误的状态码更细致一些,换句话来说,就是我们希望能够自己指定异常时的状态码。而RuntimeException异常又无法自定义状态码,只有自己定义一个异常类了。

一、自定义异常

  • 继承 RuntimeException 设置响应码和错误信息
/**
 * 自定义异常类
 */
@Getter
public class MyException extends RuntimeException{
    private Integer status;//状态码
    
    public MyException(Integer status,String message){
        super(message);
        this.status = status;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

设置测试 :

  • 如果 id 是1 就抛出自定义异常
@Service
public class ItemService {
    
    public Long saveItem(Long id){
        // 模拟添加操作,如果id为1抛异常
        if(id.equals(1L)){
            throw new MyException(501, "Id不能为1!");
        }
        return id;
    }
}   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

但是我们发现 : spring并不认识我们的异常类 ,依旧当RuntimeException异常进行处理

二、 自定义异常拦截器

我们需要一个异常拦截器 去告诉 spring 我们的异常类

@ControllerAdvice 声明这是一个异常拦截器
@ExceptionHandler(MyException.class) 声明需要捕获的异常类型

/**
 * 全局异常处理类
 */
@ControllerAdvice
public class MyExceptionController {

    /**
     * 处理异常方法
     */
    @ExceptionHandler(MyException.class) //声明需要捕获的异常类型
    @ResponseBody // 把返回值转换为json格式
    public ResponseEntity<MyException> handlerException(MyException e){
        return ResponseEntity.status(e.getStatus()).body(e);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

但是我们发现:

  • 返回的异常信息有我们需要的信息,但是也有大量冗余的的信息 在这里插入图片描述

三、 异常结果集类

将我们需要的信息进行封装


/**
 * 封装异常结果信息
 */
@Getter
public class ExceptionResult {
    private Integer status;
    private String message;

    public ExceptionResult(LyException e){
        this.status = e.getStatus();
        this.message = e.getMessage();
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

四、 改造异常拦截器

将body返回的 替换成我们的异常结果集

/**
 * 全局异常处理类
 */
@ControllerAdvice
public class MyExceptionController {

    /**
     * 异常处理方法
     */
    @ExceptionHandler(value = MyException.class) // 捕获LyException异常
    @ResponseBody // 转换为json格式
    public ResponseEntity<ExceptionResult> resolveException(LyException e){
        return ResponseEntity.status(e.getStatus()).body(new ExceptionResult(e));
    }

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

五、 自定义枚举类 : 模仿ResponseEntity

@Getter
public enum ExceptionEnum {
    INVALID_FILE_TYPE(400, "无效的文件类型!"),
    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, "回调签名有误!"),

    private int status;
    private String message;

    ExceptionEnum(int status, String message) {
        this.status = status;
        this.message = message;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

六、改造自定义异常类

/**
 * 自定义异常类
 */
@Getter
public class MyException extends RuntimeException{
    private Integer status;//状态码

    public MyException(Integer status,String message){
        super(message);
        this.status = status;
    }

    public MyException(ExceptionEnum exceptionEnum){
        super(exceptionEnum.getMessage());
        this.status = exceptionEnum.getStatus();
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

七、最终的效果

throw new MyException(ExceptionEnum.INVALID_FILE_TYPE);

@Service
public class ItemService {
    
    public Long saveItem(Long id){
        // 模拟添加操作,如果id为1抛异常
        if(id.equals(1L)){
            throw new MyException(ExceptionEnum.INVALID_FILE_TYPE);
        }
        return id;
    }

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/程序语言诗人/article/detail/62655
推荐阅读
相关标签
  

闽ICP备14008679号