SpringBoot:SpringBoot统一响应和统一异常处理

一、前言

**  在开发Spring Boot应用时,处理响应结果和异常的方式对项目的可维护性、可扩展性和团队协作有着至关重要的影响。分散的响应结果和异常处理逻辑往往会导致代码冗余、难以理解和维护。因此,统一结果返回和统一异常处理是提升项目质量的关键策略之一。**

二、统一结果返回

  统一结果返回通常意味着为所有控制器方法定义一个标准的响应格式。这可以通过创建一个或多个响应实体类来实现,这些类包含了状态码、消息和数据等通用字段。控制器方法在处理完业务逻辑后,会填充这些字段并返回给客户端。

  接下来让我们一起看看在SpringBoot中如何实现统一结果返回。

1. 定义通用的响应对象

  创建一个通用响应对象,定义成功和失败的返回场景,并确保该通用返回对象在接口中得到使用。

java 复制代码
public class ResponseResult {

    private int code;

    private String message;

    private Object data;

    public static ResponseResult success(Object data) {
        ResponseResult responseResult = new ResponseResult();
        responseResult.setData(data);
        responseResult.setCode(ResultEnum.SUCCESS.code);
        return responseResult;
    }

    public static ResponseResult error(ResultEnum resultEnum) {
        return error(resultEnum, resultEnum.message);
    }

    public static ResponseResult error(ResultEnum resultEnum, String message) {
        ResponseResult responseResult = new ResponseResult();
        responseResult.setCode(resultEnum.code);
        responseResult.setMessage(message);
        return responseResult;
    }

    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public Object getData() {
        return data;
    }

    public void setData(Object data) {
        this.data = data;
    }
}

2. 定义接口响应状态码

  定义一组公共状态码是统一结果返回的核心关键之一。这种做法不仅提高了API的易用性和可维护性,还使得客户端能够更高效地解析和处理响应数据,同时也为API的开发者提供了一个清晰、一致的标准来遵循。

java 复制代码
public enum ResultEnum {

    SUCCESS(200 ,"请求处理成功"),
    SERVICE_ERROR(500, "服务器异常,请稍后重试");

    public final Integer code;

    public final String message;

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

3. 定义统一的成功和失败的处理方法

java 复制代码
public class ResponseResult {

    private int code;

    private String message;

    private Object data;

    public static ResponseResult success(Object data) {
        ResponseResult responseResult = new ResponseResult();
        responseResult.setData(data);
        responseResult.setCode(ResultEnum.SUCCESS.code);
        return responseResult;
    }

    public static ResponseResult error(ResultEnum resultEnum) {
        return error(resultEnum, resultEnum.message);
    }

    public static ResponseResult error(ResultEnum resultEnum, String message) {
        ResponseResult responseResult = new ResponseResult();
        responseResult.setCode(resultEnum.code);
        responseResult.setMessage(message);
        return responseResult;
    }

    public int getCode() {
        return code;
    }

    public void setCode(int code) {
        this.code = code;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public Object getData() {
        return data;
    }

    public void setData(Object data) {
        this.data = data;
    }
}

4. Controller统一响应结果

java 复制代码
@GetMapping("/testResult")
 public ResponseResult test() {
     // 模拟业务逻辑
     try {
         // 假设这里有一些业务逻辑
         return ResponseResult.success("success");
     } catch (Exception e) {
         // 捕获异常并返回错误信息
         return ResponseResult.error(ResultEnum.SERVICE_ERROR);
     }
 }

三、统一异常处理

  统一异常处理则是通过全局异常处理器来捕获并处理控制器中抛出的异常。这种方式可以避免在每个控制器方法中编写重复的异常处理代码,同时也使得异常处理逻辑更加集中和易于管理。

@RestControllerAdvice

  @RestControllerAdvice 是一个组合注解,它是 @ControllerAdvice 和 @ResponseBody 的结合体。它主要用于为控制器(Controller)层提供全局的配置,如异常处理、数据绑定、数据预处理等。由于它包含了 @ResponseBody,所以所有通过 @RestControllerAdvice 处理的方法都会默认将返回值写入HTTP响应体中,并设置合适的Content-Type。

@ExceptionHandle r

  @ExceptionHandler注解用于标记一个方法,该方法用于处理控制器中抛出的异常。当控制器中的方法抛出异常时,Spring会查找是否有@ExceptionHandler注解的方法能够处理该异常。如果有,则调用该方法,并返回其响应。

注意

java 复制代码
当使用@ControllerAdvice时,我们需要将@ResponseBody添加到异常处理方法上。
如果我们使用@RestControllerAdvice,就不需要添加。

1.定义业务异常类

  统一异常类可以帮助你更好地管理错误和异常,使得整个系统的错误处理更加一致和可预测。

java 复制代码
public class BusinessException extends RuntimeException{

    private final ResultEnum resultEnum;

    public BusinessException(ResultEnum resultEnum, String message) {
        super(message);
        this.resultEnum = resultEnum;
    }

    public BusinessException(ResultEnum resultEnum) {
        this(resultEnum, resultEnum.message);
    }


}

2. 全局异常处理器

java 复制代码
@RestControllerAdvice
public class GlobalExceptionHandler {

    @ExceptionHandler({BusinessException.class})
    public ResponseResult handleBusinessException(BusinessException businessException, HttpServletRequest request) {
        // 想处理的业务
        return ResponseResult.error(ResultEnum.SERVICE_ERROR, businessException.getMessage());
    }

    /**
     * 其他异常
     * @param e
     * @return
     */
    @ExceptionHandler(value = Exception.class)
    public ResponseResult handleOtherExceptions(Exception e) {
        // 这里可以根据不同的异常类型返回不同的状态码和消息
        // 但为了简单起见,这里只返回一个通用的错误信息
        return ResponseResult.error(ResultEnum.SERVICE_ERROR);
    }

}

3. 统一处理使用

java 复制代码
@GetMapping("/testException1")
    public ResponseResult test1() {
        if (true) {
            // 业务场景
            throw new BusinessException(ResultEnum.SERVICE_ERROR);
        }

        return ResponseResult.success("success");
    }

统一异常处理使用好处

**  代码复用**:避免了在多个地方编写相似的响应结果和异常处理代码。

**  易于维护**:当需要修改响应格式或异常处理逻辑时,只需在一个地方进行修改。

**  团队协作**:团队成员可以更容易地理解和遵循统一的编码规范。

**  扩展性**:如果需要添加新的响应类型或异常处理逻辑,只需在现有基础上进行扩展。

相关推荐
水深火乐8 分钟前
安全地生成验证码、密码和 Token
后端
小强198820 分钟前
SQL Server 慢查询怎么定位?一套从“卡”到“快”的完整排查流程
后端
水深火乐22 分钟前
interface和any
后端
步行cgn23 分钟前
MyBatis Error evaluating expression ‘ids‘. Return value (3) was not iterable 错误详
java·后端
神奇小汤圆26 分钟前
Spring Boot + LangChain4j实现RAG——从零搭建企业级知识库问答系统
后端
H_Peak30 分钟前
Python运算符与流程控制:if条件判断
后端
H_Peak32 分钟前
Python字符串操作:从基础到正则入门
后端
自进化Agent智能体33 分钟前
Hermes 子代理委派 —— 并行工作的艺术
后端
步行cgn35 分钟前
MyBatis 动态 SQL 中的 <foreach> 标签完全解析
后端
lhldsg40 分钟前
社区健身场地规划实战指南:从器材配置到智能化管理经验分享
java·开发语言·经验分享·小程序