解读MyabtisPlus中的R类(通用响应包装类)
2024-01-09 16:11:44
前言
大部分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();
}
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);
}
}
再查看其源码:
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;
}
}
对应该源码的相关完整知识点可看我如下文章:
简易的解释如下:
@Data
:Lombok注解,用于自动生成样板代码,如getter、setter、toString和equals。@Accessors(chain = true)
:Lombok注解,用于启用流畅的setter方法(支持方法链)。
属性如下:
- code:表示业务错误码的属性。
- data:表示结果集的属性。
- msg:表示描述信息的属性。
- 静态工厂方法:
提供了一些静态工厂方法用于创建R对象,例如ok和failed。
public static <T> R<T> ok(T data) {
// 创建成功响应的工厂方法
}
public static <T> R<T> failed(String msg) {
// 创建失败响应的工厂方法
}
- 其他方法:
- restResult方法用于创建R对象的实例。
- ok方法用于判断响应是否成功。
- serviceData方法用于在服务间调用时,处理非业务正常的情况。
public static <T> R<T> restResult(T data, IErrorCode errorCode) {
// 创建R对象实例的方法
}
public boolean ok() {
// 判断响应是否成功的方法
}
public T serviceData() {
// 处理服务间调用时的方法
}
这个类的设计旨在提供一种简单而灵活的方式来处理不同类型的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");
}
}
}
在这个例子中,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());
}
}
}
在这个例子中,UserController类中的handleUserRequest方法处理了从UserService中获取用户信息的响应。
它检查响应是否成功,并根据情况执行相应的操作。异常情况也被捕获和处理,确保在服务调用中发生异常时能够进行适当的处理。这样的设计使得API响应的处理更加清晰和可控。
文章来源:https://blog.csdn.net/weixin_47872288/article/details/135446929
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!