使用@ExceptionHandler进行异常的统一捕获与返回

在应用中,我们力求做到优雅的捕获异常,并返回统一的格式给前端。下面是一种解决方案,步骤如下:

 

1.创建公共返回体

/**
* @author hesh
* @date 2019/1/23
* @des 公共返回类
*/
@Data
public class CommHttpResult {

    private String status;//success,fail

    private Object data;//返回的json数据,或通用错误码格式


    public static CommHttpResult create(Object data) {
        return create("success",data);
    }

    public  static CommHttpResult create(String status, Object data) {
        CommHttpResult commHttpResult = new CommHttpResult();
        commHttpResult.setStatus(status);
        commHttpResult.setData(data);
        return commHttpResult;
    }
}

2.创建公共异常操作接口

/**
* @author hesh
* @date 2019/1/23
* @des 公共错误接口
*/
public interface CommError {

    /**
     * 获取错误码
     * @return
     */
    int getErrCode();

    /**
     * 获取错误信息
     * @return
     */
    String getErrMsg();

    /**
     * 动态设置错误信息,并返回错误实体类
     * @param errMsg
     * @return
     */
    CommError setErrMsg(String errMsg);
}

3.创建自定义业务异常

/**
* @author hesh
* @date 2019/1/24
* @des 通用业务异常类
* 设计模式-->包装器业务异常类实现,使得异常或者错误枚举都可以设置错误信息
*/
public class BusinessException extends Exception implements CommError{

    private CommError commError;

    /**
     * 直接接收BusinessErrorEnum的传参用于构造业务异常
     * @param commError
     */
    public BusinessException(CommError commError){
        super();//继承父类的异常初始化方法
        this.commError = commError;
    }

    /**
     * 接收自定义errMsg的方式构造业务异常
     * @param commError
     * @param errMsg
     */
    public BusinessException(CommError commError,String errMsg){
        super();
        this.commError = commError;
        this.commError.setErrMsg(errMsg);
    }


    @Override
    public int getErrCode() {
        return this.commError.getErrCode();
    }

    @Override
    public String getErrMsg() {
        return this.commError.getErrMsg();
    }

    @Override
    public CommError setErrMsg(String errMsg) {
        this.commError.setErrMsg(errMsg);
        return this;
    }
}

4.创建错误枚举类

/**
* @author hesh
* @date 2019/1/23
* @des 通用业务错误枚举类
*/

public enum BusinessErrorEnum implements CommError{
    //通用错误类型100000开头
    PARAM_INVALID(100001,"参数不合法"),//可动态更改msg的内容
    UNKNOWN(100002,"未知错误"),

    //20000开头为用户信息相关错误定义
    USER_NOT_EXIST(20001,"用户不存在"),
    USER_LOGIN_FAIL(20002,"用户账号或密码不正确"),
    USER_NOT_LOGIN(20003,"用户未登录"),

    //30000开头为交易信息相关错误定义
    STOCK_NOT_ENOUGH(30001,"库存不足"),
    ;


    private int errCode;

    private String errMsg;

    BusinessErrorEnum(int errCode, String errMsg) {
        this.errCode = errCode;
        this.errMsg = errMsg;
    }

    @Override
    public int getErrCode() {
        return this.errCode;
    }

    @Override
    public String getErrMsg() {
        return this.errMsg;
    }

    @Override
    public CommError setErrMsg(String errMsg) {
        this.errMsg = errMsg;
        return this;
    }
}

5.使用@ExceptionHandler捕获controller抛出的异常

/**
* @author hesh
* @date 2019/1/24
* @des Controller的基类,用于处理公共逻辑
*/
@Slf4j
//@ControllerAdvice //对所有的controller类进行拦截处理
public class BaseController {

    @ExceptionHandler//异常捕获与处理
    @ResponseStatus(HttpStatus.OK)//使http返回的状态码是200
    @ResponseBody//使之返回json格式数据
    public Object handleException(HttpServletRequest request,Exception ex){
        log.error("统一异常捕获,莫紧张--{}" ,ExceptionUtils.getStackTrace(ex));
        //定义一个map,在json解析时,会自动按key-value把值读出来
        Map<String,Object> responseData = new HashMap<>();
        if (ex instanceof BusinessException){
            BusinessException businessException = (BusinessException) ex;
            responseData.put("errCode",businessException.getErrCode());
            responseData.put("errMsg",businessException.getErrMsg());
        }else {
            responseData.put("errCode", BusinessErrorEnum.UNKNOWN.getErrCode());
            responseData.put("errMsg", BusinessErrorEnum.UNKNOWN.getErrMsg());
        }

        return CommHttpResult.create("fail",responseData);
    }

}

6.具体应用例子

1.用户不存在异常
if (userModel==null){
    throw new BusinessException(BusinessErrorEnum.USER_NOT_EXIST);
}


2.验证码有误异常--修改返回的枚举的msg内容
if (!StringUtils.equals(otpcode,inSessionOtpCode)){
    throw new BusinessException(BusinessErrorEnum.PARAM_INVALID,"验证码有误");
}

throw new BusinessException(BusinessErrorEnum.PARAM_INVALID,"该账号已被注册!");

等等

 

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值