设计通用返回类BaseResponse

设计通用返回类BaseResponse、自定义状态码ErrorCode、返回工具类ResultUtils

通用返回类是对业务异常信息的补充

  • 账号、密码信息输入有误,之前用的-1来代表异常,现在就可以以ResultUtil.error()的形式来返回

注意这里是业务异常,通常我们比较熟悉的状态码有这个4xx(404,405)…这一类的它们通常所包含的面太广了,如果只是像信息输入错误的情况,我们完全可以是自定义状态码和信息来说明的,这样也便于维护。

这个error()的形式是什么呢?

在用接口文档发送数据并得到返回值,这个返回值的形式也就是我们设计的BaseResponse。

// 成功
{
    "code": 0 // 业务状态码
    "data": {
        "name": "smile"
    },
	"message": "ok"
}

// 错误
{
    "code": 50001 // 业务状态码
    "data": null
	"message": "用户操作异常、xxx"
}

注意一点就是如果我们封装返回值类型的这个BaseResponse(通常还会经过ResultUtil来封装),写错了可能会导致SpringMVC无法解析出这个格式数据,从而引发406

BaseResponse包含哪些信息呢?

可以参考市面上做的这个返回值类型,它们包含下面这三个

属性名描述数据类型
code状态码int
data数据泛型 T
message消息String
description(可选)描述String

BaseResponse-common

通用返回类


/**
 * 通用返回类
 */
@Data
public class BaseResponse<T> implements Serializable {

    private int code;

    private T data;

    private String message;

    private String description;

    public BaseResponse(int code, T data, String message, String description) {
        this.code = code;
        this.data = data;
        this.message = message;
        this.description = description;
    }

    public BaseResponse(int code, T data, String message) {
        this(code, data, message, "");
    }

    public BaseResponse(int code, T data) {
        this(code, data, "", "");
    }

    public BaseResponse(ErrorCode errorCode) {
        this(errorCode.getCode(), null, errorCode.getMessage(), errorCode.getDescription());
    }
}

通用返回类就是覆盖这个所有的返回类型,所以用的泛型T,它是在原有基础上进行增强,新添了状态码和message

this() 是在构造器内部调用另外一个构造器,简化了写法。这里设置多个构造器类型也是为了丰富这个形参的传入

其实通俗来说,写这样一个BaseResponse类就可以进行封装返回型类,只不过比较麻烦的一点是,我们需要先将返回的值用一个对象接受,再将这个对象放置到Base Response的构造函数中

return UserService.userLogin(userAccount,userPassword);

//使用通用返回类

User user = UserService.userLogin(userAccount,userPassword);
return BaseResponse(0,user,"ok")

这样写其实挺麻烦的,所以通常会设计一个返回工具类(ResultUtils)来进行封装。

这样再返回时就可以再简化为

User user = UserService.userLogin(userAccount,userPassword);
return ResultUtils.success(user);

ResultUtils-utils

首先我们需要明白需要封装哪几种情况?

主要就分为两类

  • 成功-success
  • 失败-error
方法签名描述返回类型
success(T data)data - 成功时需要返回的数据BaseResponse<T>
error(ErrorCode errorCode)errorCode - 失败的错误代码BaseResponse
error(int code, String message)code - 失败的状态码
message - 失败的消息
BaseResponse
error(ErrorCode errorCode, String message)errorCode - 失败的错误代码
message - 失败的消息
BaseResponse

成功比较好理解,成功是能直接拿到方法处理逻辑的数据,code和message也都是固定

  • code-0
  • message-ok
public static <T> BaseResponse<T> success(T data) {
        return new BaseResponse<>(0, data, "ok");
    }

失败就比较复杂,失败顾名思义就是拿不到处理的结果,所以data都为null,所以最主要就是code、message

    public static BaseResponse error(int code, String message, String description) {
        return new BaseResponse(code, null, message, description);
    }

前面我们所说的业务异常,就是可以由我们自己定义errorcode、message来表示,这里我们可以使用一个ErrorCode的枚举类来列举业务中可能出现的异常(类似于throws由我们主动抛出)

ErrorCode-common

枚举类的写法是定义属性、构造方法,然后列举结构体

  • code
  • message
  • description(可选)
/**
 *
 * 错误码
 */


public enum ErrorCode {

    SUCCESS(0, "ok", ""),
    PARAMS_ERROR(40000, "请求参数错误", ""),
    NULL_ERROR(40001, "请求数据为空", ""),
    NOT_LOGIN(40100, "未登录", ""),
    NO_AUTH(40101, "无权限", ""),
    SYSTEM_ERROR(50000, "系统内部异常", "");

    private final int code;

    /**
     * 状态码信息
     */
    private final String message;

    /**
     * 状态码描述(详情)
     */
    private final String description;


    ErrorCode(int code, String message, String description) {
        this.code = code;
        this.message = message;
        this.description = description;
    }
        public int getCode() {
        return code;
    }

    public String getMessage() {
        return message;
    }

    public String getDescription() {
        return description;
    }
}

回顾一下我们做了哪些事情,首先是定义BaseResponse,它是在包装原有数据的基础上添加了code、message

之后为了方便直接返回包装的返回值类型(success情况),我们添加了ResultUtils类,目前只封装了BaseResponse(0,data,“ok”)-success这种情况,后面我们还会封装失败的类型

然后我们定义了错误状态码ErrorCode,这是一个枚举类,列举了业务中可以抛出的异常,后续我们将会以此为基础搭配最开始的BaseResponse的构造函数来封装失败的情况。

完善BaseResponse

ErrorCode中我们定义的code也要包含到BaseResponse这个范畴中,所以我们可以将ErrorCode作为枚举类对象传入,以拿到ErrorCode定义的信息。

    public BaseResponse(ErrorCode errorCode) {
        this(errorCode.getCode(), null, errorCode.getMessage(), errorCode.getDescription());
    }

这里是拿到ErrorCode中定义的异常信息,对应的需要先在ErrorCode中定义getter方法才能拿到message、code

完善ResultUtils

ResultUtils就是在BaseResponse进一步的拓展,同样的我们需要将刚刚拿到ErrorCode类型的BaseResponse进行封装

    public static BaseResponse error(ErrorCode errorCode) {
        return new BaseResponse<>(errorCode);
    }

这里实际上是做了简化,当然正常的写法是:

    public static BaseResponse error(ErrorCode errorCode) {
        return new BaseResponse<>(errorCode.getCode(), null, errorCode.getMessage(),errorCode.getDescription());
    }

对应的用法就是可直接传入ErrorCode定义的枚举值

return ResultUtils.error(ErrorCode.xxx)

当然我们是可以丰富这里的情况:

  • 只拿到ErrorCode中的code,而message由我们自己定义
    public static BaseResponse error(ErrorCode errorCode, String Message) {
        return new BaseResponse(errorCode.getCode(), Message);
    }

完整代码:

/**
 * 返回工具类
 *
 * @author yupi
 */
public class ResultUtils {

    /**
     * 成功
     *
     * @param data
     * @param <T>
     * @return
     */
    public static <T> BaseResponse<T> success(T data) {
        return new BaseResponse<>(0, data, "ok");
    }

    /**
     * 失败
     *
     * @param errorCode
     * @return
     */
    public static BaseResponse error(ErrorCode errorCode) {
        return new BaseResponse<>(errorCode);
    }

    /**
     * 失败
     *
     * @param code
     * @param message
     * @param description
     * @return
     */
    public static BaseResponse error(int code, String message, String description) {
        return new BaseResponse(code, null, message, description);
    }

    /**
     * 失败
     *
     * @param errorCode
     * @return
     */
    public static BaseResponse error(ErrorCode errorCode, String message, String description) {
        return new BaseResponse(errorCode.getCode(), null, message, description);
    }

    /**
     * 失败
     *
     * @param errorCode
     * @return
     */
    public static BaseResponse error(ErrorCode errorCode, String description) {
        return new BaseResponse(errorCode.getCode(), errorCode.getMessage(), description);
    }
}
  • 22
    点赞
  • 41
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值