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.返回异常的标准结构