首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐

解读MyabtisPlus中的R类(通用响应包装类)

  • 25-03-03 14:23
  • 2419
  • 5780
blog.csdn.net

目录

  • 前言
  • 1. 概念
  • 2. 源码解读
  • 3. Demo

前言

大部分R类可以自已手写一个适配的,但MybatisPlus中有专门的R类,于是就使用封装好的类即可

1. 概念

通用R类是一种用于处理API响应的通用响应包装类。

概念含义作用示例用途
1.R类是一个泛型类,可以用于封装任意类型的API响应数据。

2.通过对响应进行包装,提供了一种一致的方式来表示成功、失败或异常情况。
1.R类的名称可能表示"Response",代表着它是用于处理响应的类。

2.通过包含业务错误码、结果集和描述信息等属性,提供了对API响应的全面描述。
1.封装响应: 提供了一种封装API响应的结构,包括成功和失败的情况。

2.统一格式: 定义了统一的响应格式,使得在不同的API请求中都能够使用相同的响应结构。

3.易于处理: 通过提供静态工厂方法和实用方法,简化了对响应的处理和判断。

4.异常处理: 通过serviceData方法,可以方便地处理服务间调用时的异常情况。

5.清晰的代码流: 使用ok方法使得代码中对成功响应的判断更加清晰,提高了代码的可读性。
1.在服务层封装的方法中,使用R类来包装成功或失败的响应,使得调用方能够清晰地了解操作的结果。

2.在Controller层中,根据R类的响应进行不同的处理,例如成功时显示数据,失败时返回错误信息。

总体而言,通用R类的设计旨在提供一种简单、灵活、一致且易于处理的方式来处理不同类型的API响应,使得代码更加清晰和可维护。

2. 源码解读

里头具体的一些方法类如下:

IErrorCode 类的接口

public interface IErrorCode {

    /**
     * 错误编码 -1、失败 0、成功
     */
    long getCode();

    /**
     * 错误描述
     */
    String getMsg();
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

ApiErrorCode实现类 (主要是code以及msg的属性类)

public enum ApiErrorCode implements IErrorCode {
    /**
     * 失败
     */
    FAILED(-1, "操作失败"),
    /**
     * 成功
     */
    SUCCESS(0, "执行成功");

    private final long code;
    private final String msg;

    ApiErrorCode(final long code, final String msg) {
        this.code = code;
        this.msg = msg;
    }

    public static ApiErrorCode fromCode(long code) {
        ApiErrorCode[] ecs = ApiErrorCode.values();
        for (ApiErrorCode ec : ecs) {
            if (ec.getCode() == code) {
                return ec;
            }
        }
        return SUCCESS;
    }

    @Override
    public long getCode() {
        return code;
    }

    @Override
    public String getMsg() {
        return msg;
    }

    @Override
    public String toString() {
        return String.format(" ErrorCode:{code=%s, msg=%s} ", code, msg);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43

再查看其源码:

package com.baomidou.mybatisplus.extension.api;

import java.io.Serializable;
import java.util.Optional;

import com.baomidou.mybatisplus.extension.enums.ApiErrorCode;
import com.baomidou.mybatisplus.extension.exceptions.ApiException;

import lombok.Data;
import lombok.experimental.Accessors;

/**
 * REST API 返回结果
 *
 * @author hubin
 * @since 2018-06-05
 */
@Data
@Accessors(chain = true)
public class R<T> implements Serializable {

    /**
	 * serialVersionUID
	 */
	private static final long serialVersionUID = 1L;
	
	/**
     * 业务错误码
     */
    private long code;
    /**
     * 结果集
     */
    private T data;
    /**
     * 描述
     */
    private String msg;

    public R() {
        // to do nothing
    }

    public R(IErrorCode errorCode) {
        errorCode = Optional.ofNullable(errorCode).orElse(ApiErrorCode.FAILED);
        this.code = errorCode.getCode();
        this.msg = errorCode.getMsg();
    }

    public static <T> R<T> ok(T data) {
        ApiErrorCode aec = ApiErrorCode.SUCCESS;
        if (data instanceof Boolean && Boolean.FALSE.equals(data)) {
            aec = ApiErrorCode.FAILED;
        }
        return restResult(data, aec);
    }

    public static <T> R<T> failed(String msg) {
        return restResult(null, ApiErrorCode.FAILED.getCode(), msg);
    }

    public static <T> R<T> failed(IErrorCode errorCode) {
        return restResult(null, errorCode);
    }

    public static <T> R<T> restResult(T data, IErrorCode errorCode) {
        return restResult(data, errorCode.getCode(), errorCode.getMsg());
    }

    private static <T> R<T> restResult(T data, long code, String msg) {
        R<T> apiResult = new R<>();
        apiResult.setCode(code);
        apiResult.setData(data);
        apiResult.setMsg(msg);
        return apiResult;
    }

    public boolean ok() {
        return ApiErrorCode.SUCCESS.getCode() == code;
    }

    /**
     * 服务间调用非业务正常,异常直接释放
     */
    public T serviceData() {
        if (!ok()) {
            throw new ApiException(this.msg);
        }
        return data;
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91

对应该源码的相关完整知识点可看我如下文章:

  1. spring中@Data注解详细解析
  2. java之序列化与反序列化的详细解析(全)
  3. 详解Java中@Accessors注解(全)

简易的解释如下:

  • @Data:Lombok注解,用于自动生成样板代码,如getter、setter、toString和equals。
  • @Accessors(chain = true):Lombok注解,用于启用流畅的setter方法(支持方法链)。

属性如下:

  • code:表示业务错误码的属性。
  • data:表示结果集的属性。
  • msg:表示描述信息的属性。
  1. 静态工厂方法:

提供了一些静态工厂方法用于创建R对象,例如ok和failed。

public static <T> R<T> ok(T data) {
    // 创建成功响应的工厂方法
}

public static <T> R<T> failed(String msg) {
    // 创建失败响应的工厂方法
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  1. 其他方法:
  • restResult方法用于创建R对象的实例。
  • ok方法用于判断响应是否成功。
  • serviceData方法用于在服务间调用时,处理非业务正常的情况。
public static <T> R<T> restResult(T data, IErrorCode errorCode) {
    // 创建R对象实例的方法
}

public boolean ok() {
    // 判断响应是否成功的方法
}

public T serviceData() {
    // 处理服务间调用时的方法
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

这个类的设计旨在提供一种简单而灵活的方式来处理不同类型的API响应,包括成功、失败和异常情况。

上述的源码比较简单,不做过多的解读= - =
请看下方demo辅助理解!

3. Demo

类似的Demo如下:

假设有一个用户服务,包含了一个方法用于获取用户信息:

public class UserService {

    public R<User> getUserById(Long userId) {
        // 模拟从数据库或其他服务中获取用户信息
        User user = userRepository.findById(userId);

        if (user != null) {
            // 用户存在,返回成功响应
            return R.ok(user);
        } else {
            // 用户不存在,返回失败响应
            return R.failed("User not found");
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

在这个例子中,UserService类中的getUserById方法使用了R类来封装API响应。如果用户存在,它会创建一个成功的R对象,否则创建一个失败的R对象。

然后,在调用这个服务的地方,可以这样处理响应:

public class UserController {

    private UserService userService;

    public void handleUserRequest(Long userId) {
        try {
            // 调用用户服务获取用户信息
            R<User> userResponse = userService.getUserById(userId);

            if (userResponse.ok()) {
                // 处理成功响应
                User user = userResponse.getData();
                System.out.println("User details: " + user);
            } else {
                // 处理失败响应
                System.out.println("Failed to get user: " + userResponse.getMsg());
            }
        } catch (ApiException e) {
            // 处理异常情况
            System.out.println("Error: " + e.getMessage());
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

在这个例子中,UserController类中的handleUserRequest方法处理了从UserService中获取用户信息的响应。

它检查响应是否成功,并根据情况执行相应的操作。异常情况也被捕获和处理,确保在服务调用中发生异常时能够进行适当的处理。这样的设计使得API响应的处理更加清晰和可控。

文章知识点与官方知识档案匹配,可进一步学习相关知识
Java技能树类和接口类和面向对象145194 人正在系统学习中
码农研究僧
微信公众号
1.框架等前沿技术 2.日常生活 3.技术交流
注:本文转载自blog.csdn.net的码农研究僧的文章"https://blog.csdn.net/weixin_47872288/article/details/135446929"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

未查询到任何数据!
回复评论:

分类栏目

后端 (14832) 前端 (14280) 移动开发 (3760) 编程语言 (3851) Java (3904) Python (3298) 人工智能 (10119) AIGC (2810) 大数据 (3499) 数据库 (3945) 数据结构与算法 (3757) 音视频 (2669) 云原生 (3145) 云平台 (2965) 前沿技术 (2993) 开源 (2160) 小程序 (2860) 运维 (2533) 服务器 (2698) 操作系统 (2325) 硬件开发 (2491) 嵌入式 (2955) 微软技术 (2769) 软件工程 (2056) 测试 (2865) 网络空间安全 (2948) 网络与通信 (2797) 用户体验设计 (2592) 学习和成长 (2593) 搜索 (2744) 开发工具 (7108) 游戏 (2829) HarmonyOS (2935) 区块链 (2782) 数学 (3112) 3C硬件 (2759) 资讯 (2909) Android (4709) iOS (1850) 代码人生 (3043) 阅读 (2841)

热门文章

101
推荐
关于我们 隐私政策 免责声明 联系我们
Copyright © 2020-2025 蚁人论坛 (iYenn.com) All Rights Reserved.
Scroll to Top