SpringBoot 更优雅的实现全局异常捕获处理

(1)定义 @EnableGlobalExceptionHandler 注解,用来控制是否启用全局异常捕获处理

/**
 * @author chenyusheng 
 * @create 2023/6/28 9:56
 * @description 是否启用全局异常捕获处理
 */
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface EnableGlobalExceptionHandler {
}
(2)自定义 ServiceException 异常类

/**
 * @author chenyusheng
 * @create 2023/6/28 9:56
 * @description 自定义异常类
 */
@Data
@EqualsAndHashCode(callSuper = false)
@JsonInclude(value = JsonInclude.Include.NON_EMPTY)
public class ServiceException extends RuntimeException {

    private static final long serialVersionUID = 4224174066989416792L;

    private final Integer code;

    private Object data;

    /**
     * 自定义 code+message+data 异常
     *
     * @param code
     * @param message
     */
    public ServiceException(Integer code, String message, Object data) {
        // 使用父类的 message 字段
        super(message);
        // 设置错误码
        this.code = code;
        // 设置额外内容
        this.data = data;
    }

    /**
     * 自定义 code+message 异常
     *
     * @param code
     * @param message
     */
    public ServiceException(Integer code, String message) {
        this(code, message, null);
    }

    /**
     * ServiceExceptionEnum 通用枚举异常,使用自定义 message
     *
     * @param statusCode
     * @param message
     */
    public ServiceException(StatusCode statusCode, String message) {
        this(statusCode.getCode(), message);
    }

    /**
     * ServiceExceptionEnum 通用枚举异常,使用自定义 message, data
     *
     * @param statusCode
     * @param message
     * @param data
     */
    public ServiceException(StatusCode statusCode, String message, Object data) {
        this(statusCode.getCode(), message, data);
    }

    /**
     * ServiceExceptionEnum 通用枚举异常,使用默认 message
     *
     * @param statusCode
     */
    public ServiceException(StatusCode statusCode) {
        this(statusCode.getCode(), statusCode.getMessage());
    }

}

/**
 * @author chenyusheng
 * @create 2023/6/28 9:56
 * @description 服务状态码 接口
 */
public interface StatusCode {

    /**
     * 获取业务码
     *
     * @return 业务码
     */
    Integer getCode();

    /**
     * 获取业务描述
     *
     * @return 业务描述
     */
    String getMessage();
}

/**
 * @author chenyusheng
 * @create 2023/6/28 9:56
 * @description 自定义服务状态码枚举,这里仅提供一些基于 HttpStatus 状态码的提示;针对具体应用可以通过实现 StatusCode 接口,自定义一套系统状态码提示。
 */
public enum StatusCodeEnum implements StatusCode {

    /**
     * 200:执行成功
     */
    OK(HttpStatus.OK.value(), "执行成功"),

    /**
     * 400:客户端请求语法错误
     */
    BAD_REQUEST(HttpStatus.BAD_REQUEST.value(), "客户端请求语法错误"),

    /**
     * 401:认证失败
     */
    UNAUTHORIZED(HttpStatus.UNAUTHORIZED.value(), "认证失败"),

    /**
     * 403:权限不足
     */
    FORBIDDEN(HttpStatus.FORBIDDEN.value(), "权限不足"),

    /**
     * 404:请求资源不存在
     */
    NOT_FOUND(HttpStatus.NOT_FOUND.value(), "请求资源不存在"),

    /**
     * 500:服务器内部错误
     */
    INTERNAL_SERVER_ERROR(HttpStatus.INTERNAL_SERVER_ERROR.value(), "服务器内部错误"),

    /**
     * 502:网关异常
     */
    BAD_GATEWAY(HttpStatus.BAD_GATEWAY.value(), "网关异常"),

    /**
     * 503:服务器当前无法处理请求
     */
    SERVICE_UNAVAILABLE(HttpStatus.SERVICE_UNAVAILABLE.value(), "服务器当前无法处理请求"),

    /**
     * 429:请求太多,达到限制
     */
    TOO_MANY_REQUESTS(HttpStatus.TOO_MANY_REQUESTS.value(), "请求太多,达到限制");

    /**
     * 异常码
     */
    private final Integer code;

    /**
     * 异常消息
     */
    private final String message;

    StatusCodeEnum(Integer code, String message) {
        this.code = code;
        this.message = message;
    }

    /**
     * 获取业务码
     *
     * @return 业务码
     */
    @Override
    public Integer getCode() {
        return code;
    }

    /**
     * 获取业务描述
     *
     * @return 业务描述
     */
    @Override
    public String getMessage() {
        return message;
    }
}
(3)定义 CommonResult<T> 通用结果包装类

/**
 * @param <T>
 * @author chenyusheng
 * @create 2023/6/28 9:56
 * @description 通用结果包装类
 */
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@JsonInclude(JsonInclude.Include.NON_NULL)
@ApiModel("公共接口返回包装类")
public class CommonResult<T> {

    public static final Integer CODE_SUCCESS = StatusCodeEnum.OK.getCode();

    /**
     * 状态码
     */
    @ApiModelProperty("状态码")
    private Integer code;

    /**
     * 消息提示
     */
    @ApiModelProperty("消息提示")
    private String message;

    /**
     * 返回数据
     */
    @ApiModelProperty("返回数据")
    private T data;

    /**
     * 失败
     *
     * @param code    状态码
     * @param message 消息提示
     */
    public static <T> CommonResult<T> error(Integer code, String message) {
        return CommonResult.error(code, message, null);
    }

    /**
     * 失败
     *
     * @param code    状态码
     * @param message 消息提示
     * @param data    返回数据
     * @param <T>
     */
    public static <T> CommonResult<T> error(Integer code, String message, T data) {
        return CommonResult.<T>builder()
                .code(code)
                .message(StringUtils.isNotBlank(message) ? message : "执行异常")
                .data(data)
                .build();
    }

    /**
     * 成功
     *
     * @param data
     * @param <T>
     * @return
     */
    public static <T> CommonResult<T> success(T data) {
        return CommonResult.success("执行成功!", data);
    }

    /**
     * 成功
     *
     * @param data
     * @param <T>
     * @return
     */
    public static <T> CommonResult<T> success(String message, T data) {
        return CommonResult.success(CODE_SUCCESS, message, data);
    }

    /**
     * 成功
     *
     * @param code
     * @param message
     * @param data
     * @param <T>
     * @return
     */
    public static <T> CommonResult<T> success(Integer code, String message, T data) {
        return CommonResult.<T>builder()
                .code(code)
                .message(StringUtils.isNotBlank(message) ? message : "执行成功")
                .data(data)
                .build();
    }
}
(4)自定义GlobalExceptionHandler 全局异常处理类

/**
 * @author chenyusheng
 * @create 2023/6/28 9:56
 * @description 全局异常处理
 */
@Slf4j
@RestControllerAdvice(annotations = {EnableGlobalExceptionHandler.class})
@SuppressWarnings("all")
public class GlobalExceptionHandler {

    /**
     * 处理 ServiceException 自定义异常
     *
     * @param req HttpServletRequest
     * @param ex  ServiceException
     * @return CommonResult
     */
    @ExceptionHandler(value = ServiceException.class)
    public CommonResult serviceExceptionHandler(HttpServletRequest req, ServiceException ex) {
        log.debug("ServiceException自定义异常:", ex);
        return CommonResult.error(ex.getCode(), ex.getMessage(), ex.getData());
    }

    /**
     * 处理 MissingServletRequestParameterException 异常
     *
     * @param req HttpServletRequest
     * @param ex  MissingServletRequestParameterException
     * @return CommonResult
     */
    @ExceptionHandler(value = MissingServletRequestParameterException.class)
    public CommonResult missingServletRequestParameterExceptionHandler(HttpServletRequest req, MissingServletRequestParameterException ex) {
        log.error("缺少请求参数异常:", ex);
        return CommonResult.error(StatusCodeEnum.BAD_REQUEST.getCode(), ex.getMessage());
    }

    /**
     * 处理其它 MethodArgumentNotValidException 参数校验异常
     *
     * @param req HttpServletRequest
     * @param ex  MethodArgumentNotValidException
     * @return
     */
    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    public CommonResult methodArgumentNotValidExceptionHandler(HttpServletRequest req, MethodArgumentNotValidException ex) {
        log.error("方法参数无效异常:", ex);
        return CommonResult.error(StatusCodeEnum.BAD_REQUEST.getCode(), Objects.requireNonNull(ex.getBindingResult().getFieldError()).getField() + " : " + ex.getBindingResult().getFieldError().getDefaultMessage());
    }

    /**
     * 处理其它 Exception 异常
     *
     * @param req HttpServletRequest
     * @param ex  Exception
     * @return
     */
    @ExceptionHandler(value = Exception.class)
    public CommonResult exceptionHandler(HttpServletRequest req, Exception ex) {
        log.error("Exception异常:", ex);
        return CommonResult.error(StatusCodeEnum.INTERNAL_SERVER_ERROR.getCode(), ex.getMessage());
    }
}
(5)在主程序使用 @EnableGlobalExceptionHandler 显示启动即可;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
在 Spring Boot 中,可以通过实现一个全局异常处理器来捕获应用程序中的异常,并对异常进行统一处理实现一个全局异常处理器的步骤如下: 1. 创建一个异常处理器类,用于处理应用程序中的异常。 ```java @ControllerAdvice public class GlobalExceptionHandler { @ExceptionHandler(Exception.class) public ResponseEntity<ErrorResponse> handleException(Exception ex) { ErrorResponse errorResponse = new ErrorResponse("500", ex.getMessage()); return new ResponseEntity<>(errorResponse, HttpStatus.INTERNAL_SERVER_ERROR); } } ``` 2. 在异常处理器类上加上 @ControllerAdvice 注解,表示这是一个全局异常处理器。 3. 在异常处理器类中定义异常处理方法,使用 @ExceptionHandler 注解指定要处理异常类型。在异常处理方法中,可以处理异常并返回一个自定义的错误响应实体。 4. 在异常处理方法中使用 ResponseEntity 类来封装错误响应实体,并指定 HTTP 状态码。这里示例使用了 500 状态码。 5. 配置 Spring Boot 应用,使其能够扫描到异常处理器类。可以在启动类上加上 @ComponentScan 注解来指定扫描路径。 ```java @SpringBootApplication @ComponentScan(basePackages = "com.example.demo") public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } } ``` 以上就是在 Spring Boot 中实现全局异常处理的步骤。通过实现全局异常处理器,可以有效地统一处理应用程序中的异常

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值