目录
前言
一、使用教程
1.自定义异常类。
2.全局统一处理类
3.ResultVO类
4.StatusCodeEnum 枚举类
二、 结束语
在SpringBoot中,实现自定义异常和全局异常统一处理是确保应用程序稳定性和用户体验的关键。通过定义自定义异常类,我们可以为应用程序中的特定错误提供更具描述性的错误信息。而全局异常统一处理机制,能够确保无论异常发生在何处,都会得到恰当的处理,避免异常的泄露和错误的传播。
@Getter
@AllArgsConstructor
public class BusinessException extends RuntimeException implements Serializable{
private Integer code= StatusCodeEnum.FAIL.getCode();
private String reason;
public BusinessException(StatusCodeEnum statusCodeEnum){
this.code = statusCodeEnum.getCode();
this.reason = statusCodeEnum.getDesc();
}
public BusinessException(String cause){
this.reason = cause;
}
}
为适应springboot的restFul风格不同的请求和考虑到项目的健壮性,对不同请求的异常制订出了不同的异常处理逻辑。
@Slf4j
@RestControllerAdvice
public class GlobalExceptionHandler implements Serializable {
@ExceptionHandler(BusinessException.class)
public ResultVO> exception(BusinessException e){
return ResultVO.fail(e.getCode(),e.getReason());
}
/**
* 处理Post请求中 使用@requestBody 验证路径中请求实体校验失败后抛出的异常
*/
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResultVO> exception(MethodArgumentNotValidException e){
String error = e.getBindingResult().getAllErrors().stream()
.map(DefaultMessageSourceResolvable::getDefaultMessage)
.collect(Collectors.joining());
log.error("{}",error);
return ResultVO.fail(error);
}
/**
* 处理Get请求中 使用@Valid 验证路径中请求实体校验失败后抛出的异常
*/
@ExceptionHandler(BindException.class)
@ResponseBody
public ResultVO> BindExceptionHandler(BindException e) {
String message = e.getBindingResult().getAllErrors().stream().map(DefaultMessageSourceResolvable::getDefaultMessage).collect(Collectors.joining());
return ResultVO.fail(message);
}
/**
* 处理请求参数格式错误 @RequestParam上validate失败后抛出的异常是ConstraintViolationException
*/
@ExceptionHandler(ConstraintViolationException.class)
@ResponseBody
public ResultVO> ConstraintViolationExceptionHandler(ConstraintViolationException e) {
String message = e.getConstraintViolations().stream().map(ConstraintViolation::getMessage).collect(Collectors.joining());
return ResultVO.fail(message);
}
/**
* 参数格式异常
*/
@ExceptionHandler(HttpMessageNotReadableException.class)
@ResponseBody
public ResultVO> HttpMessageNotReadableExceptionHandler(HttpMessageNotReadableException e) {
return ResultVO.fail("参数格式异常");
}
}
用于封装返回给前端的数据传输类
@Data
@Builder
public class ResultVO {
private Boolean flag;
private Integer code;
private String message;
private T data;
public static ResultVO ok(){
return resultVO(true, StatusCodeEnum.SUCCESS.getCode(), StatusCodeEnum.SUCCESS.getDesc(),null);
}
public static ResultVO ok(T data){
return resultVO(true, StatusCodeEnum.SUCCESS.getCode(), StatusCodeEnum.SUCCESS.getDesc(),data);
}
public static ResultVO ok(String message){
return resultVO(true,message);
}
public static ResultVO fail(){
return resultVO(false, StatusCodeEnum.FAIL.getCode(), StatusCodeEnum.FAIL.getDesc(),null);
}
public static ResultVO fail(T data){
return resultVO(false, StatusCodeEnum.FAIL.getCode(), StatusCodeEnum.FAIL.getDesc(),data);
}
public static ResultVO fail(String message){
return resultVO(false,message);
}
public static ResultVO fail(Integer code,String message){
return resultVO(false,code,message,null);
}
private static ResultVO resultVO(Boolean flag,String message){
return ResultVO.builder()
.flag(flag)
.code(flag ? StatusCodeEnum.SUCCESS.getCode(): StatusCodeEnum.FAIL.getCode())
.message(message)
.build();
}
private static ResultVO resultVO(Boolean flag,Integer code,String message,T data){
return ResultVO.builder()
.flag(flag)
.code(code)
.message(message)
.data(data).build();
}
}
使用枚举类避免不必要的冗余。
@AllArgsConstructor
@Getter
public enum StatusCodeEnum {
EMAIL_ARGUMENTS_FAIL(4004,"请检查邮箱格式"),
MOBILE_ARGUMENTS_FAIL(4005,"请检查手机号格式"),
INVALID_PARAMETERS(4006,"参数异常"),
ATTACK_LOCK(-5001,"警告!恶意访问"),
BLACKLIST(-5002,"恶意操作!账号被禁止"),
SUCCESS(20000,"操作成功"),
LOGIN_FAILED(40001,"登入失败"),
ACCOUNT_EXIST(40003,"账户已存在"),
FAIL(50001,"操作失败"),
ERROR(50000,"系统异常");
private Integer code;
private String desc;
}
配置完以上的所需要的类后,可以通过postman或者其他接口测试工具进行异常测试,可以通过测试结果来调整返回的提示内容。
最后希望大家多多支持新人哦~