SpringBoot实现自定义异常+全局异常统一处理

目录

前言

一、使用教程

1.自定义异常类。

2.全局统一处理类

3.ResultVO类

4.StatusCodeEnum 枚举类

二、 结束语


前言

        在SpringBoot中,实现自定义异常和全局异常统一处理是确保应用程序稳定性和用户体验的关键。通过定义自定义异常类,我们可以为应用程序中的特定错误提供更具描述性的错误信息。而全局异常统一处理机制,能够确保无论异常发生在何处,都会得到恰当的处理,避免异常的泄露和错误的传播。

一、使用教程

1.自定义异常类。

@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;
	}
}

2.全局统一处理类

       为适应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("参数格式异常");
	}
}

3.ResultVO类

        用于封装返回给前端的数据传输类

@Data
@Builder
public class ResultVO<T> {

	private Boolean flag;

	private Integer code;

	private String message;

	private T data;

	public static <T> ResultVO<T> ok(){
		return resultVO(true, StatusCodeEnum.SUCCESS.getCode(), StatusCodeEnum.SUCCESS.getDesc(),null);
	}

	public static <T> ResultVO<T> ok(T data){
		return resultVO(true, StatusCodeEnum.SUCCESS.getCode(), StatusCodeEnum.SUCCESS.getDesc(),data);
	}

	public static <T> ResultVO<T> ok(String message){
		return resultVO(true,message);
	}

	public static <T> ResultVO<T> fail(){
		return resultVO(false, StatusCodeEnum.FAIL.getCode(), StatusCodeEnum.FAIL.getDesc(),null);
	}

	public static <T> ResultVO<T> fail(T data){
		return resultVO(false, StatusCodeEnum.FAIL.getCode(), StatusCodeEnum.FAIL.getDesc(),data);
	}

	public static <T> ResultVO<T> fail(String message){
		return resultVO(false,message);
	}

	public static <T> ResultVO<T> fail(Integer code,String message){
		return resultVO(false,code,message,null);
	}

	private static <T> ResultVO<T> resultVO(Boolean flag,String message){
		return ResultVO.<T>builder()
				.flag(flag)
				.code(flag ? StatusCodeEnum.SUCCESS.getCode(): StatusCodeEnum.FAIL.getCode())
				.message(message)
				.build();
	}

	private static <T> ResultVO<T> resultVO(Boolean flag,Integer code,String message,T data){
		return ResultVO.<T>builder()
				.flag(flag)
				.code(code)
				.message(message)
				.data(data).build();
	}
}

4.StatusCodeEnum 枚举类

        使用枚举类避免不必要的冗余。

@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或者其他接口测试工具进行异常测试,可以通过测试结果来调整返回的提示内容。

        最后希望大家多多支持新人哦~

  • 9
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
Spring Boot中,可以通过创建自定义异常类来实现自定义异常。以下是一个示例: ```java // 自定义异常类 public class CustomException extends RuntimeException { private String errorCode; private String errorMessage; public CustomException(String errorCode, String errorMessage) { this.errorCode = errorCode; this.errorMessage = errorMessage; } public String getErrorCode() { return errorCode; } public String getErrorMessage() { return errorMessage; } } // 异常处理类 @ControllerAdvice public class CustomExceptionHandler { @ExceptionHandler(CustomException.class) public ResponseEntity<ErrorResponse> handleCustomException(CustomException ex) { ErrorResponse errorResponse = new ErrorResponse(ex.getErrorCode(), ex.getErrorMessage()); return new ResponseEntity<>(errorResponse, HttpStatus.INTERNAL_SERVER_ERROR); } } // 错误响应类 public class ErrorResponse { private String errorCode; private String errorMessage; public ErrorResponse(String errorCode, String errorMessage) { this.errorCode = errorCode; this.errorMessage = errorMessage; } public String getErrorCode() { return errorCode; } public String getErrorMessage() { return errorMessage; } } ``` 在上面的示例中,我们首先创建了一个自定义异常类`CustomException`,该类继承自`RuntimeException`。然后,我们创建了一个异常处理类`CustomExceptionHandler`,使用`@ControllerAdvice`注解将其标记为全局异常处理类。在`CustomExceptionHandler`中,我们使用`@ExceptionHandler`注解来指定处理`CustomException`异常的方法,并返回自定义的错误响应对象`ErrorResponse`。最后,我们创建了一个`ErrorResponse`类,用于封装错误码和错误信息。 通过以上步骤,我们就可以在Spring Boot自定义异常并进行统一异常处理了。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

爱生活,更爱技术

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值