如何编写优雅的统一返回结果类与统一异常处理类

2023-12-16 19:33:27

在这里插入图片描述

如何编写优雅的统一返回结果类

? 在前后端分离开发过程中,前端人员和后端人员要进行配合来共同完成一个开发任务,我们会将接口返回的数据封装成Json数据格式,一般我们会将所有接口的数据格式统一, 使前端(iOS Android, Web)对数据的操作更一致、轻松。一般情况下,统一返回数据格式没有固定的格式,只要能描述清楚返回的数据状态以及要返回的具体数据就可以。但是一般会包含状态码、返回消息、数据这几部分内容。

系统要求返回的基本数据格式如下:

列表:

{
  "code": 200,
  "message": "成功",
  "data": [
    {
      "id": 2,
      "roleName": "系统管理员"
    }
  ],
  "ok": true
}

分页:

{
  "code": 200,
  "message": "成功",
  "data": {
    "records": [
      {
        "id": 2,
        "roleName": "系统管理员"
      },
      {
        "id": 3,
        "name": "普通管理员"
      }
    ],
    "total": 10,
    "size": 3,
    "current": 1,
    "orders": [],
    "hitCount": false,
    "searchCount": true,
    "pages": 2
  },
  "ok": true
}

没有返回数据:

{
  "code": 200,
  "message": "成功",
  "data": null,
  "ok": true
}

失败:

{
  "code": 201,
  "message": "失败",
  "data": null,
  "ok": false
}

1、创建统一返回结果状态信息类

import lombok.Getter;
/**
 * 统一返回结果状态信息类
 *
 */
@Getter
public enum ResultCodeEnum {

    SUCCESS(200,"成功"),
    FAIL(201, "失败"),
    SERVICE_ERROR(2012, "服务异常"),
    DATA_ERROR(204, "数据异常"),
    ILLEGAL_REQUEST(205, "非法请求"),
    REPEAT_SUBMIT(206, "重复提交"),

    LOGIN_AUTH(208, "未登陆"),
    PERMISSION(209, "没有权限"),

    private Integer code;

    private String message;

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

2、创建统一返回结果类

import lombok.Data;

@Data
public class Result<T> {

        // 状态码
    private Integer code;
    // 信息
    private String message;
    // 数据
    private T data;

    // 构造私有化
    private Result() { }

    // 设置数据,返回对象的方法
    public static<T> Result<T> build(T data,ResultCodeEnum resultCodeEnum) {
        // 创建Resullt对象,设置值,返回对象
        Result<T> result = new Result<>();
        // 判断返回结果中是否需要数据
        if(data != null) {
            //设置数据到result对象
            result.setData(data);
        }
        // 设置其他值
        result.setCode(resultCodeEnum.getCode());
        result.setMessage(resultCodeEnum.getMessage());
        //返回设置值之后的对象
        return result;
    }

    // 设置数据,返回对象的方法
    public static<T> Result<T> build(T data, Integer code, String message) {
        // 创建Resullt对象,设置值,返回对象
        Result<T> result = new Result<>();
        // 判断返回结果中是否需要数据
        if(data != null) {
            //设置数据到result对象
            result.setData(data);
        }
        // 设置其他值
        result.setCode(code);
        result.setMessage(message);
        //返回设置值之后的对象
        return result;
    }

    // 成功的方法
    public static<T> Result<T> ok(T data) {
        Result<T> result = build(data, ResultCodeEnum.SUCCESS);
        return result;
    }
    public static<T> Result<T> ok() {
        Result<T> result = build(null, ResultCodeEnum.SUCCESS);
        return result;
    }

    //失败的方法
    public static<T> Result<T> fail(T data) {
        return build(data,ResultCodeEnum.FAIL);
    }
}

3、在Controller中使用

@Api(tags = "首页模块")
@RestController
public class IndexController {

    @ApiImplicitParam(name = "name",value = "姓名",required = true)
    @ApiOperation(value = "问好接口")
    @GetMapping("/sayHi")
    public Result sayHi(@RequestParam(value = "name")String name){
        return Result.ok("Hi:"+name);
    }
}

如何打造优雅的统一异常处理类

? 系统在运行过程中如果出现了异常,默认会直接返回异常信息,比如500错误提示。但是我们想让异常结果也显示为统一的返回结果对象,并且统一处理系统的异常信息,那么需要进行统一异常处理。

1、全局异常处理

import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

@ControllerAdvice
// AOP 面向切面 不改变源代码 增强现功能 
public class GlobalExceptionHandler {

    @ExceptionHandler(Exception.class)
    @ResponseBody
    public Result error(Exception e){
        e.printStackTrace();
        return Result.fail();
    }
}

2、自定义异常处理

import lombok.Data;

@Data
public class XxxException extends RuntimeException{

    //异常状态码
    private Integer code;

    /**
     * 通过状态码和错误消息创建异常对象
     * @param message
     * @param code
     */
    public XxxException(String message, Integer code) {
        super(message);
        this.code = code;
    }

    /**
     * 接收枚举类型对象
     * @param resultCodeEnum
     */
    public XxxException(ResultCodeEnum resultCodeEnum) {
        super(resultCodeEnum.getMessage());
        this.code = resultCodeEnum.getCode();
    }
}

3、在GlobalExceptionHandler添加方法

import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

@ControllerAdvice
// AOP 面向切面 不改变源代码 增强现功能 
public class GlobalExceptionHandler {

    @ExceptionHandler(Exception.class) //异常处理器
    @ResponseBody //返回JSON数据
    public Result error(Exception e) {
        e.printStackTrace();
        return Result.fail(SERVICE_ERROR);
    }

    /**
     * 自定义异常处理
     * @param e
     * @return
     */
    @ExceptionHandler(XxxException.class)
    @ResponseBody
    public Result error(XxxException e) {
        return Result.build(null,e.getCode(),e.getMessage());
    }
}

文章来源:https://blog.csdn.net/qq_51808107/article/details/135036288
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。