全局处理异常-入门实例
小结:
第一步:RunException 异常固定状态码500, 提供自定义异常
第二步:自定义异常:需要手动设置状态码,提示消息,提供枚举类型 ExceptinEnum
第三步:抛出LyException(ExceptionEnum e) ,在common项目提供提供类(加@ControllerAdice)统一处理controller层抛出异常
第四步:返回结果方便前端获取异常结果,提供ExceptionResult 将ExceptionResult 返回
controller
@RestController @RequestMapping("/product") public class ProductController { @PostMapping public Product save(Product product){ //如果价格为null,给前端返回结果 if(product.getPrice() == null){ throw new LyException(ExceptionEnum.PRICE_NOT_NULL); } product.setId(12); return product; } }
common-->exceptions
/** * 自定义异常 */ @Getter//就可以给BasicException提供status public class LyException extends RuntimeException { //定义返回状态码 private int status; public LyException(ExceptionEnum exceptionEnum) { super(exceptionEnum.getMessage()); this.status = exceptionEnum.getStatus(); } public LyException(ExceptionEnum exceptionEnum, Throwable cause) { super(exceptionEnum.getMessage(), cause); this.status = exceptionEnum.getStatus(); } }
common-->advice springmvc处理,只要是controller层抛出的异常,全部统一处理
/** * 只要是controller层抛出的异常,全部统一处理 */ @ControllerAdvice//处理controller层增强 @Slf4j public class BasicExceptionAdvice { /** * ResponseEntity<T>:返回响应对象,包括响应的头信息,响应的数据等等 * @param e * @return */ @ExceptionHandler(RuntimeException.class)//指定处理什么类型的异常 public ResponseEntity<String> handleException(RuntimeException e) { // 我们暂定返回状态码为400, 然后从异常中获取友好提示信息 return ResponseEntity.status(400).body(e.getMessage()); } /** * 处理自定义异常(状态码,提示消息) * @param e * @return */ @ExceptionHandler(LyException.class) public ResponseEntity<ExceptionResult> LyException(LyException e){ ExceptionResult exceptionResult = new ExceptionResult(e); return ResponseEntity.status(e.getStatus()).body(exceptionResult); } }
common-->enums
/** * 异常 状态码 提示消息 枚举类型 */ @Getter public enum ExceptionEnum { //一定在最上方定义选择项 OK(200, "操作成功!"), PRICE_NOT_NULL(400, "价格不能为空"), ERROR(400, "操作失败!"), OTHERS(500, "其他异常"), 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, "回调签名有误!"), CATEGORY_NOT_FOUND(404, "商品分类不存在!"), BRAND_NOT_FOUND(404, "品牌不存在!"), SPEC_NOT_FOUND(404, "规格不存在!"), GOODS_NOT_FOUND(404, "商品不存在!"), CARTS_NOT_FOUND(404, "购物车不存在!"), APPLICATION_NOT_FOUND(404, "应用不存在!"), ORDER_NOT_FOUND(404, "订单不存在!"), ORDER_DETAIL_NOT_FOUND(404, "订单数据不存在!"), 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; //提供私有构造 ExceptionEnum(int status, String message) { this.status = status; this.message = message; } }
common-->vo
/** * 捕获到异常后,将对象转成json返回 */ @Getter public class ExceptionResult { private int status; private String message; private String timestamp; /** * 封装返回异常状态码,提示消息 * @param e */ public ExceptionResult(LyException e) { this.status=e.getStatus(); this.message=e.getMessage(); this.timestamp= DateTime.now().toString("yyyy-MM-dd hh:mm:ss"); } }