项目中简单的异常处理流程(附代码)

2022-08-20 08:15:49

异常介绍

  • 异常有编译期异常(Exception)和运行期(RuntimeException)异常

  • 运行期异常可以解决也可以不解决。
    如果我们不处理,会抛给JVM处理,JVM的默认处理方式,是打印异常信息,并终止虚拟机
    自己处理,用try,catch 处理,try里放的是有可能会出现问题的代码,捕捉异常时,多个异常可以并列,如果这些异常之间有继承关系,那么大的异常要放在后面。

  • 编译期异常必须解决,编译期的异常出现在编译期,异常不处理,程序无法执行
    处理方式:
    1.throw向上抛出,谁调用,谁处理
    2.自己用try catch处理
    3.一般我们在finally里面做一些善后处理,释放内存,不管有没有异常,finally里面都会执行

    异常处理流程图(按自己理解画的 , 有不对的地方欢迎评论 , 及时修改)

在这里插入图片描述
代码实现

1.首先说明一下异常处理的流程 , 在开发过程中 , 出现异常之后 , 一般都会统一处理, 所有 从dao层开始 , 如果出现异常 , 逐级向上抛.最后有springmvc统一处理

场景预设

我们预设这样一个场景,假如我们做新增商品item,需要接收下面的参数

	price:价格(不能为空)

	name:名称

@RestController
@RequestMapping("item")
public class ItemController {

    @Autowired
    private ItemService itemService;

    @PostMapping("save")
    public ResponseEntity<Item> save(Item item) {
        if (item.getPrice() == null) {
//            return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(null);
            throw new MyException(ExceptionEnum.INSERT_OPERATION_FAIL);
        }
        Item result = itemService.saveItem(item);
        return ResponseEntity.status(HttpStatus.CREATED).body(result);
    }

}

假设我们用户增加商品时 , 价格没有写 . 此时就应该响应给客户 , 价格没有写 , 停止后续的操作;

为了使我们给页面返回的异常结果更加规范 , 通常情况下, 我们会统一对异常进行捕捉

/**
 * 统一异常处理类
 */
@ControllerAdvice //默认情况下,会拦截所有加了@Controller的类
public class BasicExceptionAdvice {

    //对无法预知的异常进行统一处理
    @ExceptionHandler(Exception.class) 
    public ResponseEntity<String> handleException(RuntimeException e){
        return ResponseEntity.status(500).body(e.getMessage());
    }
	
    //捕捉自定义异常进行处理
    @ExceptionHandler(LyException.class)
    public ResponseEntity<ExceptionResult> handleLyException(LyException e){
        return ResponseEntity.status(e.getStatus()).body(new ExceptionResult(e));
    }

}

此时,我们需要定义一个自定义异常类 , 专门用来处理业务中的异常信息 , 并作出响应

@Getter
public class MyException extends RuntimeException {

    private int status;//响应的状态码

    //提供构造方法
    public MyException(ExceptionEnum em) {
        super(em.getMessage());
        this.status = em.getStatus();
    }
    
    //提供构造方法
    public MyException(ExceptionEnum em, Throwable cause) {
        super(em.getMessage(), cause);
        this.status = em.getStatus();
    }
}

自定义异常枚举(简单的几条, 一般公司会提前规定好)

@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;
    }
}

自定义异常结果

@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();
        this.timestamp = DateTime.now().toString("yyyy-MM-dd HH:mm:ss");
    }
}

以后,我们无论controller还是service层的业务处理,出现异常情况,都抛出自定义异常,方便统一处理。

  • 作者:刘强i
  • 原文链接:https://blog.csdn.net/Sx_Ll_Qiang/article/details/101458656
    更新时间:2022-08-20 08:15:49