首页 > 技术文章 > 全局处理异常-入门实例

WonderfulU 2019-07-25 17:23 原文

小结:

第一步: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");
    }
}

  

 

推荐阅读