如何自定义异常类
为什么要使用自定义异常类?
在 Java 中,自定义异常是指用户根据自己的需求创建的异常类。Java 提供了一些预定义的异常类,如 NullPointerException
、ArrayIndexOutOfBoundsException
等,但有时这些预定义的异常类并不能完全满足我们的需求。在这种情况下,我们可以通过创建自定义异常类来表示特定的异常情况。
自定义异常类通常继承自 Exception
类或 RuntimeException
类,以及它们的子类,并根据需要添加相应的构造方法和其他方法以满足特定的异常处理需求,自定义异常类可以包含额外的属性和方法,以提供更多的信息和功能。
使用自定义异常类时,通常的做法是在方法中使用 throw
语句来抛出自定义异常,然后使用全局异常进行捕获
自定义异常类的好处在于,它使得代码更加可读和可维护,通过使用自定义异常类,我们可以更好地描述和处理特定的异常情况,并提供更详细的错误信息。
展示一个我的自定义异常类,这个异常类主要是处理Web请求期间出现参数校验、访问数据库、调用服务发生错误时抛出
public class BusinessException extends RuntimeException {
/**
* 错误码
*/
private final int code;
public BusinessException(int code, String message) {
super(message);
this.code = code;
}
public BusinessException(ErrorCode errorCode) {
super(errorCode.getMessage());
this.code = errorCode.getCode();
}
public BusinessException(ErrorCode errorCode, String message) {
super(message);
this.code = errorCode.getCode();
}
public int getCode() {
return code;
}
}
/**
* 自定义错误码
* @author <a href="https://github.com/Hardork">老山羊</a>
*/
public enum ErrorCode {
SUCCESS(0, "ok"),
PARAMS_ERROR(40000, "请求参数错误"),
NOT_LOGIN_ERROR(40100, "未登录"),
NO_AUTH_ERROR(40101, "无权限"),
NOT_FOUND_ERROR(40400, "请求数据不存在"),
TOO_MANY_REQUEST(42300, "请求频繁"),
FORBIDDEN_ERROR(40300, "禁止访问"),
SYSTEM_ERROR(50000, "系统内部异常"),
OPERATION_ERROR(50001, "操作失败");
/**
* 状态码
*/
private final int code;
/**
* 信息
*/
private final String message;
ErrorCode(int code, String message) {
this.code = code;
this.message = message;
}
public int getCode() {
return code;
}
public String getMessage() {
return message;
}
}
-
定义一个名为
BusinessException
的类,并且这个类继承了RuntimeException
,指定这个类是个运行时异常类 -
code
:错误码 -
message
: 异常信息
如何优雅的使用自定义异常类?
假如你是在SpringBoot项目中使用自定义异常类,可以写一个全局自定义异常处理器
/**
* 全局异常处理器
*
* @author <a href="https://github.com/Hardork">老山羊</a>
* @RestControllerAdvice:这个注解用于定义一个全局的Spring MVC控制器异常处理器。它结合了@ControllerAdvice和 *@ResponseBody,允许编写异常处理器直接将数据返回到响应的主体中
*/
@RestControllerAdvice
@Slf4j
public class GlobalExceptionHandler {
/**
*@ExceptionHandler(BusinessException.class)是一个用于标识异常处理方法的注解,它指示该方法处理特定类型(BusinessException)的异常。当在Controller中抛出BusinessException或其子类的异常时,Spring框架会调用被此注解标记的方法来处理该异常。
*/
@ExceptionHandler(BusinessException.class)
public BaseResponse<?> businessExceptionHandler(BusinessException e) {
log.error("BusinessException", e);
return ResultUtils.error(e.getCode(), e.getMessage());
}
/**
*当抛出的异常是RuntimeException类时触发
*/
@ExceptionHandler(RuntimeException.class)
public BaseResponse<?> runtimeExceptionHandler(RuntimeException e) {
log.error("RuntimeException", e);
return ResultUtils.error(ErrorCode.SYSTEM_ERROR, "系统错误");
}
}
ResultUtils
是响应返回工具类
/**
* 返回工具类
*
* @author <a href="https://github.com/Hardork">老山羊</a>
*
*/
public class ResultUtils {
/**
* 成功
*
* @param data
* @param <T>
* @return
*/
public static <T> BaseResponse<T> success(T data) {
return new BaseResponse<>(0, data, "ok");
}
/**
* 失败
*
* @param errorCode
* @return
*/
public static BaseResponse error(ErrorCode errorCode) {
return new BaseResponse<>(errorCode);
}
/**
* 失败
*
* @param code
* @param message
* @return
*/
public static BaseResponse error(int code, String message) {
return new BaseResponse(code, null, message);
}
/**
* 失败
*
* @param errorCode
* @return
*/
public static BaseResponse error(ErrorCode errorCode, String message) {
return new BaseResponse(errorCode.getCode(), null, message);
}
}
/**
* 通用返回类
*
* @param <T>
* @author <a href="https://github.com/Hardork">老山羊</a>
*
*/
@Data
public class BaseResponse<T> implements Serializable {
private int code;
private T data;
private String message;
public BaseResponse(int code, T data, String message) {
this.code = code;
this.data = data;
this.message = message;
}
public BaseResponse(int code, T data) {
this(code, data, "");
}
public BaseResponse(ErrorCode errorCode) {
this(errorCode.getCode(), null, errorCode.getMessage());
}
}
测试自定义返回类
@RestController
@CrossOrigin
public class TestController {
@GetMapping("/exception")
public BaseResponse<Integer> testException(@RequestParam("id") Long id) {
if (id < 0) {
throw new BusinessException(ErrorCode.PARAMS_ERROR);
}
return ResultUtils.success(1);
}
}
- 如果id < 0,就抛出自定义异常
- 可以看到当id = -1时,系统抛出了自定义异常,并被全局异常处理器拦截处理了