返回
SpringBoot实现统一异常处理的正确姿势
后端
2023-10-26 11:39:14
好的代码离不开对异常的处理,而恰到好处的异常处理,能让我们对异常的定位更加便捷、快速。SpringBoot作为一款优秀的微服务框架,其内置对异常的处理机制,能帮助我们开发高质量的程序。
实现步骤
- 定义统一响应对象类
首先,我们需要定义一个统一的响应对象类,该类将作为所有异常处理的响应结果。该类可以包含以下字段:
public class ApiResponse {
private int code;
private String message;
private Object data;
public ApiResponse(int code, String message, Object data) {
this.code = code;
this.message = message;
this.data = data;
}
// 省略getter和setter方法
}
- 定义业务异常枚举接口和实现
接着,我们需要定义一个业务异常枚举接口,该接口将包含所有可能发生的业务异常。每个异常枚举值都应该包含一个错误代码和一个错误信息。例如:
public interface BusinessExceptionEnum {
int getCode();
String getMessage();
}
public enum CommonBusinessExceptionEnum implements BusinessExceptionEnum {
// 系统错误
SYSTEM_ERROR(500, "系统错误"),
// 参数错误
PARAMETER_ERROR(400, "参数错误"),
// 业务错误
BUSINESS_ERROR(1000, "业务错误");
private int code;
private String message;
CommonBusinessExceptionEnum(int code, String message) {
this.code = code;
this.message = message;
}
@Override
public int getCode() {
return code;
}
@Override
public String getMessage() {
return message;
}
}
- 定义业务异常基类
然后,我们需要定义一个业务异常基类,该基类将继承自RuntimeException,并实现BusinessExceptionEnum接口。该基类将作为所有业务异常的父类,并提供一些公共的方法和属性。例如:
public abstract class BusinessException extends RuntimeException implements BusinessExceptionEnum {
private static final long serialVersionUID = 1L;
public BusinessException() {
super();
}
public BusinessException(String message) {
super(message);
}
public BusinessException(String message, Throwable cause) {
super(message, cause);
}
public BusinessException(Throwable cause) {
super(cause);
}
protected BusinessException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
@Override
public abstract int getCode();
@Override
public abstract String getMessage();
}
- 定义全局异常处理切面
接下来,我们需要定义一个全局异常处理切面,该切面将拦截所有未处理的异常,并将其转换为统一的响应对象。该切面可以如下所示实现:
@Aspect
@Component
public class GlobalExceptionHandler {
@Around("execution(* com.example.demo.*.*(..))")
public Object handleException(ProceedingJoinPoint joinPoint) throws Throwable {
try {
return joinPoint.proceed();
} catch (Throwable e) {
// 如果是业务异常,直接返回业务异常的响应对象
if (e instanceof BusinessException) {
BusinessException businessException = (BusinessException) e;
return new ApiResponse(businessException.getCode(), businessException.getMessage(), null);
}
// 如果是系统异常,返回系统异常的响应对象
return new ApiResponse(500, "系统错误", null);
}
}
}
- 测试和验证
最后,我们需要对统一异常处理进行测试和验证,以确保其正常工作。我们可以编写一些测试用例,来测试不同类型的异常是否能够被正确处理。例如:
@SpringBootTest
public class GlobalExceptionHandlerTest {
@Autowired
private GlobalExceptionHandler globalExceptionHandler;
@Test
public void testBusinessException() {
BusinessException businessException = new CommonBusinessExceptionEnum.BusinessError();
ApiResponse response = globalExceptionHandler.handleException(null, businessException);
Assertions.assertEquals(response.getCode(), 1000);
Assertions.assertEquals(response.getMessage(), "业务错误");
}
@Test
public void testSystemException() {
Exception exception = new Exception();
ApiResponse response = globalExceptionHandler.handleException(null, exception);
Assertions.assertEquals(response.getCode(), 500);
Assertions.assertEquals(response.getMessage(), "系统错误");
}
}
总结
通过以上步骤,我们就可以在SpringBoot中实现统一异常处理。统一异常处理可以使我们的代码更加健壮、易于维护,并且可以提高系统的可用性。