专栏首页生如夏花的个人博客springboot项目自定义统一异常处理

springboot项目自定义统一异常处理

什么是异常

异常指的是在程序运行过程中发生的异常事件,通常是由外部问题(如硬件错误、输入错误)所导致的。在Java等面向对象的编程语言中异常属于对象

java 中的异常

java中Exception是所有异常的父类, 在运行时发生的异常叫运行时异常用RuntimeException类表示 运行时异常就是需要我们在程序中捕获并且处理的异常 好的异常处理能帮助我们更好的定位错误发生的原因

异常处理流程

1、在服务层抛出自定义异常类型及不可预知异常类型。 上图中BusinessException为系统的自定义异常类型,程序中在代码显示抛出该异常,此类异常是程序员可预知 的。另一部分是系统无法预知的异常,如:数据库无法连接,服务器宕机等场景下所抛出的异常,此类异常是程序员无 法预知的异常。

2、应用层接收到服务层抛出异常继续向上抛出,应用层自己也可以抛出自定义异常类型及不可预知异常类型。 3、统一异常处理器捕获到异常进行解析。 判断如果为自定义异常则直接取出错误代码及错误信息,因为程序员在抛出自定义异常时已将错误代码和异常信息 指定。 如果为不可预知的异常则统一定义为99999异常代码。 4、统一异常处理器将异常信息格式为前端要求的格式响应给前端。 服务端统一将异常信息封装在下边的Json格式中返回:

{
"errCode": "000000",
"errMessage": "错误说明" 
}

大部分springboot项目异常处理都适用此流程 注:这里的99999异常代码不强制使用该代码,可以自定义,流程上的所有异常代码都可以自定义,但是还是建议按照http协议来指定,比如200是成功,自定义的代码前端如果使用框架那就很可能会认为这是错误的,即使是对的!

springboot自定义异常处理

使用到了lombok,需要在项目中引入lombok依赖

自定义业务异常类
public class BusinessException extends RuntimeException {

	
	private static final long serialVersionUID = 5565760508056698922L;
	
	private ErrorCode errorCode;

	public BusinessException(ErrorCode errorCode) {
		super();
		this.errorCode = errorCode;
	}
	
	public BusinessException() {
		super();
	}

	public BusinessException(String arg0, Throwable arg1, boolean arg2, boolean arg3) {
		super(arg0, arg1, arg2, arg3);
	}
	
	public BusinessException(ErrorCode errorCode, String arg0, Throwable arg1, boolean arg2, boolean arg3) {
		super(arg0, arg1, arg2, arg3);
		this.errorCode = errorCode;
	}

	public BusinessException(String arg0, Throwable arg1) {
		super(arg0, arg1);
	}
	
	public BusinessException(ErrorCode errorCode, String arg0, Throwable arg1) {
		super(arg0, arg1);
		this.errorCode = errorCode;
	}

	public BusinessException(String arg0) {
		super(arg0);
	}
	
	public BusinessException(ErrorCode errorCode, String arg0) {
		super(arg0);
		this.errorCode = errorCode;
	}

	public BusinessException(Throwable arg0) {
		super(arg0);
	}
	
	public BusinessException(ErrorCode errorCode, Throwable arg0) {
		super(arg0);
		this.errorCode = errorCode;
	}

	public ErrorCode getErrorCode() {
		return errorCode;
	}

	public void setErrorCode(ErrorCode errorCode) {
		this.errorCode = errorCode;
	}
	
}
自定义业务异常处理器
@Data
public class RestErrorResponse {
    private String errCode;
    private String errMessage;

    public RestErrorResponse(String errCode, String errMessage) {
        this.errCode = errCode;
        this.errMessage = errMessage;
    }
}
定义全局异常处理器

全局异常处理器使用ControllerAdvice注解实现,ControllerAdvice是SpringMVC3.2提供的注解,用 ControllerAdvice可以方便实现对Controller面向切面编程 ControllerAdvice和ExceptionHandler注解实现全局异常处理

@ControllerAdvice
public class GlobalExceptionHandler {

    private static final Logger LOGGER = LoggerFactory.getLogger(GlobalExceptionHandler.class);

    //捕获异常
    @ExceptionHandler(value = Exception.class)
    @ResponseBody
    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)//返回500状态码
    public RestErrorResponse processExcetion(HttpServletRequest request, HttpServletResponse response, Exception e){
        //异常处理
        //系统自定义异常取出errCode和errMessage
        if (e instanceof BusinessException){
            //控制台打印
            LOGGER.info(e.getMessage(),e);
            //解析系统自定义异常
            BusinessException businessException = (BusinessException) e;
            ErrorCode errorCode = businessException.getErrorCode();
            //错误代码
            int code = errorCode.getCode();
            //错误信息
            String desc = errorCode.getDesc();
            return new RestErrorResponse(String.valueOf(code),desc);
        }
        //非自定义异常类型,定义为99999系统未知错误
        LOGGER.error("系统异常:",e);
        return new RestErrorResponse(String.valueOf(CommonErrorCode.UNKNOWN.getCode()),CommonErrorCode.UNKNOWN.getDesc());
    }
}
定义异常编码类

新建错误接口ErrorCode

public interface ErrorCode {

    int getCode();

    String getDesc();

}

枚举类型的异常编码类实现ErrorCode接口

/**
 * 异常编码
 */
public enum CommonErrorCode implements ErrorCode {

	公用异常编码 //
	E_100101(100101,"传入参数与接口不匹配"),
	E_100102(100102,"验证码错误"),
	E_100103(100103,"验证码为空"),
	E_100104(100104,"查询结果为空"),
	E_100105(100105,"ID格式不正确或超出Long存储范围"),
	E_100106(100106,"上传错误"),
	E_100107(100107,"发送验证码错误"),
	E_100108(100108,"传入对象为空"),
	E_100109(100109,"手机号格式不正确"),
	E_100110(100110,"用户名为空"),
	E_100111(100111,"密码为空"),
	E_100112(100112,"手机号为空"),
	E_100113(100113,"手机号已存在"),
	E_100114(100114,"用户名已存在"),
	E_100115(100115,"密码不正确"),


	E_NO_AUTHORITY(999997,"没有访问权限"),
	CUSTOM(999998,"自定义异常"),
	/**
	 * 未知错误
	 */
	UNKNOWN(999999,"未知错误");


	private int code;
	private String desc;

	public int getCode() {
		return code;
	}

	public String getDesc() {
		return desc;
	}

	private CommonErrorCode(int code, String desc) {
		this.code = code;
		this.desc = desc;
	}


	public static CommonErrorCode setErrorCode(int code) {
       for (CommonErrorCode errorCode : CommonErrorCode.values()) {
           if (errorCode.getCode()==code) {
               return errorCode;
           }
       }
	       return null;
	}
}

注:异常代码应该根据业务需要自定义

异常处理使用

在需要抛出异常的地方throw即可

try {
          //......
        }catch (Exception e){
           //......
           //抛出自定义异常
            throw new BusinessException(CommonErrorCode.E_100102);
        }

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Swagger

    访问swagger-ui,http://localhost:8080/swagger-ui.html

    许喜朝
  • http请求get与post的区别

    他们最直接的区别就是get请求将数据放在url中传输,而post请求是将数据放在request body中传输

    许喜朝
  • java和node.js使用md5算法实现对数据的加密与加盐操作

    密码在数据库当中是如何存储的?明文还是密文? 很显然做为一家负责人的公司密码应该采用密文在数据库中存储 这样做即使数据库被攻破密码采用了加密也不会得到泄露

    许喜朝
  • 第四十五章:基于SpringBoot 设计业务逻辑异常统一处理

    恒宇少年
  • Java单体应用 - 架构模式 - 03.设计模式-06.适配器模式

    原文地址:http://www.work100.net/training/monolithic-architecture-design-patterns-ada...

    光束云
  • Java 操作 ElasticSearch,so easy!

    松哥原创的 Spring Boot 视频教程已经杀青,感兴趣的小伙伴戳这里-->Spring Boot+Vue+微人事视频教程

    江南一点雨
  • loadrunner 脚本开发-web_custom_request函数详细介绍

    int web_custom_request(const char *RequestName, ,

    授客
  • Java包含两种异常checked异常和unchecked异常

    参考链接: Java中的已检查与未检查异常| checked或unchecked异常

    用户7886150
  • 为什么基于接口而非实现编程?有必要为每个类都定义接口吗?

    “基于接口而非实现编程”这条原则的英文描述是:“Program to an interface, not an implementation”。我们理解这条原则...

    码农架构
  • Python 3.7 + HttpRunner 初探

    一天,你的领导要你对某上游供应商接口做测试,你一听,接口测试,用什么做好呢 ? Postman ? Jmeter ? balabala。。。优秀的你,肯定想到了...

    muntainyang

扫码关注云+社区

领取腾讯云代金券