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

本文介绍了如何在SpringBoot项目中创建自定义异常类,如BusinessException,以及如何通过GlobalExceptionHandler进行全局异常统一处理,包括各种异常类型的捕获和ResultVO类的使用,以提升应用的稳定性和用户体验。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

前言

一、使用教程

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

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

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

爱生活,更爱技术

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

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

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

打赏作者

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

抵扣说明:

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

余额充值