SpringBoot使用万能的统一异常处理方法返回异常信息

前后端分离开发中,后端服务器有很多异常,而在业务层如果直接抛出异常信息对前端的信息展示非常不友好,所以此文介绍一种目前前后端分离开发中常用的统一异常处理方法。

1. 自定义错误状态码接口(CustomizeErrorCode)

/**
 * @author Jack
 * @date 2019-07-27-18:08
 */
public interface CustomizeErrorCode {
    /**
     * 获取错误状态码
     * @return 错误状态码
     */
    Integer getCode();

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

}

2. 枚举类型的错误状态码(MyCustomizeErrorCode)

这个类实现CustomizeErrorCode,必须实现它的方法

/**
 * @author Jack
 * @date 2019-07-27-18:07
 */
public enum MyCustomizeErrorCode implements CustomizeErrorCode {
    /**
     * 3005:"密码不正确!"
     */
    PASS_NOT_CORRECT(3005, "密码不正确!请重新尝试!"),
    /**
     * 3006:"尚未登录!"
     */
    NOT_LOGIN(3006, "尚未登录!"),
    /**
     * 2005:"没有找到这一条历史信息!有人侵入数据库强制删除了!"
     */
    INTRODUCTION_NOT_FOUND(2005, "没有找到这一条历史信息!有人侵入数据库强制删除了!"),
    /**
     * 404:没有找到对应的请求路径
     */
    PAGE_NOT_FOUND(404, "你要请求的页面好像暂时飘走了...要不试试请求其它页面?"),
    /**
     * 500:服务端异常
     */
    INTERNAL_SERVER_ERROR(500, "服务器冒烟了...要不等它降降温后再来访问?"),
    /**
     * 2001:未知异常
     */
    INTERNAL_SERVER_ERROR(2001, "未知异常,请联系管理员!"),

    private String message;
    private Integer code;

    @Override
    public Integer getCode() {
        return this.code;
    }

    @Override
    public String getMessage() {
        return this.message;
    }

    MyCustomizeErrorCode(Integer code, String message) {
        this.message = message;
        this.code = code;
    }

}

3. 自定义异常类(CustomizeException)

这个类继承RuntimeException类,有两个属性code和message,抛出该异常时返回前端的JSON信息只包含这2个字段,构造方法需要传入枚举类型的错误状态码,意思就是说如果要抛出异常,需要指定抛出自定义的哪一个异常信息。

/**
 * @author Jack
 * @date 2019-07-27-18:36
 */
public class CustomizeException extends RuntimeException {

    private Integer code;
    private String message;

    public CustomizeException(CustomizeErrorCode customizeErrorCode) {

        this.code = customizeErrorCode.getCode();
        this.message = customizeErrorCode.getMessage();

    }

    public Integer getCode() {
        return code;
    }

    @Override
    public String getMessage() {
        return message;
    }
}

4. 统一异常处理类(CustomizeExceptionHandler)

/**
 * @author Jack
 * @date 2019-07-27-18:34
 */
@ControllerAdvice
public class MyCustomizeExceptionHandler {

    @ExceptionHandler(RuntimeException.class)
    @ResponseBody
    @Override
    public ResultDTO handleCustomizeException(HttpServletRequest request, Throwable ex) {

        //获取错误状态码
        HttpStatus status = getStatus(request);
        //判断是否匹配自定义异常
        if (ex instanceof CustomizeException) {
            CustomizeException customizeException = (CustomizeException) ex;
            ResultDTO resultDTO = ResultDTO.errorOf(customizeException.getCode(), customizeException.getMessage());
            System.out.println(resultDTO.toString());
            return resultDTO;
        }
        //判断是否5xx类型异常
        if (status.is5xxServerError() || ex instanceof ParseException) {
            ResultDTO resultDTO = ResultDTO.errorOf(MyCustomizeErrorCode.INTERNAL_SERVER_ERROR);
            return resultDTO;
        }

        return ResultDTO.errorOf(MyCustomizeErrorCode.UNKNOWN_ERROR);

    }
}

5. 统一封装Json类(JsonResultUtil)

/**
 * @author Jack
 * @date 2019-06-27-17:00
 */
@Data
public class JsonResultUtil implements Serializable {

    private Integer code;
    private String msg;
    private Map<String, Object> extended = new HashMap<>();

    public static JsonResultUtil success(){
        return new JsonResultUtil(200, "处理成功");
    }

    public static JsonResultUtil fail(){return new JsonResultUtil(100, "处理失败!");}

    public static JsonResultUtil errorOf(CustomizeErrorCode errorCode){
        return errorOf(errorCode.getCode(), errorCode.getMessage());
    }

    public static JsonResultUtil errorOf(Integer code, String message) {
        return new JsonResultUtil(code, message);
    }

    public JsonResultUtil addObject(String key, Object value){
        this.extended.put(key, value);
        return this;
    }

    public JsonResultUtil(Integer code, String msg) {
        this.code = code;
        this.msg = msg;
    }
}

示例:

/**
 * @author Jack
 * @date 2019-07-28-14:08
 */
@Service
public class AdminIntroductionServiceimpl implements AdminIntroductionService {

    @Autowired
    IntroductionDao introductionDao;
    /**
     * 更新介绍内容
     */
    @Override
    public void updateIntroduction(Long introductionId, String introductionInfo) {

        Introduction dbIntroduction;
        try {
            dbIntroduction= introductionDao.findById(introductionId).get();
        }catch (Exception ex){
            //抛出自定义异常,该介绍内容不存在
            throw new CustomizeException(MyCustomizeErrorCode.INTRODUCTION_NOT_FOUND);
        }

        Date currentTime = DateUtil.getCurrentDateTime();
        dbHistory.setIntroductionEditTime(currentTime);
        dbHistory.setIntroductionInfo(introductionInfo);

        historyDao.save(dbHistory);

    }

}

Postman测试:

发布了50 篇原创文章 · 获赞 46 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_41949328/article/details/104512575