目录
👨💻 作者简介:程序员半夏 , 一名全栈程序员,擅长使用各种编程语言和框架,如JavaScript、React、Node.js、Java、Python、Django、MySQL等.专注于大前端与后端的硬核干货分享,同时是一个随缘更新的UP主. 你可以在各个平台找到我!
🏆 本文收录于专栏: SprinbBoot + Vue3 项目实战,从0到1,手把手实现一个个人博客网站!
————————————————————————
🔥 热门专栏:🥇 学透CSS: 全网阅读超百万,CSDN最强CSS专栏,精通CSS全属性,不做切图仔,从订阅本专栏开始!
🥇 SprinbBoot + Vue3 项目实战: 新鲜出炉的2023实战系列博客,配套视频,用心打磨,篇篇精品.持续更新,值得订阅!
前言
在实际开发中,前后端分离是常态,通常前后端通过标准化的JSON来交换数据。前端根据接口定义,以GET/POST/PUT/Delete等方式访问后端接口,后端可以通过@RequestBody
注解解析参数,Rest风格的传参方式可以使用@PathVariable
注解解析参数。后端在完成增删改查的功能后,一般会创建新的实体类,返回前端,并不会直接返回结果。
目前常见的返回形式如下:
{
code: Integer;(前端请求后端执行结果的状态码);
message: String;(前端请求后端执行结果的执行信息);
data: T; (后端完成请求获得的数据实体类);
}
示例
下图是CSDN某个接口的返回值:
下面是常见的code以及对应的message:
400: "请求参数不正确";
401: "账号未登录";
403: "没有操作权限";
404: "请求未找到";
定义常见Code状态码常量
代码
com/banxia/common/HttpCode.java
// 操作成功
public static final int SUCCESS = 200;
// 对象创建成功
public static final int CREATED = 201;
// 请求已经被接受
public static final int ACCEPTED = 202;
// 操作已经执行成功,但是没有返回数据
public static final int NO_CONTENT = 204;
// 资源已被移除
public static final int MOVED_PERM = 301;
// 重定向
public static final int SEE_OTHER = 303;
// 资源没有被修改
public static final int NOT_MODIFIED = 304;
// 参数列表错误(缺少,格式不匹配)
public static final int BAD_REQUEST = 400;
// 未授权
public static final int UNAUTHORIZED = 401;
// 访问受限,授权过期
public static final int FORBIDDEN = 403;
// 资源,服务未找到
public static final int NOT_FOUND = 404;
// 不允许的http方法
public static final int BAD_METHOD = 405;
//资源冲突,或者资源被锁
public static final int CONFLICT = 409;
// 不支持的数据,媒体类型
public static final int UNSUPPORTED_TYPE = 415;
// 系统内部错误
public static final int ERROR = 500;
注意-HTTP状态码与本文Code状态码的区别
HTTP状态码
HTTP状态码(英語:HTTP Status Code)是用以表示网页服务器超文本传输协议响应状态的3位数字代码。它由 RFC 2616 规范定义的。
所有状态码被分为五类,状态码的第一个数字代表了响应的五种状态之一。
- 1xx 消息
- 2xx 成功
- 3xx 重定向
- 5xx 服务器错误
- 4xx 客户端错误
简单来说,HTTP状态码是整个请求的一个状态标识。例如下图是在开发者工具下的截图。
本文Code状态码
本文的code状态时仅仅是本次请求的一个返回结果,是开发者根据本次后端操作的结果自定义的code。例如在数据库插入操作失败的时候捕获异常,就可以返回code-500。因为捕获了异常,整个请求是能够完整流转的。最终返回的http状态码就是200。
实现通用返回结果实体
1. 确定类及属性
根据前言中确定的解构,很容易得到下面的类结构。
com/banxia/common/CommonResult.java
public class CommonResult<T> implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 错误码
*/
private Integer code;
/**
* 返回数据
*/
private T data;
/**
* 错误消息
*/
private String message;
}
2. 定义success函数
success
的返回结果,既可以包含数据(例如查询),也可以不包含数据(例如删除)。且code状态码是固定的200。message是固定的操作成功。
public static <T> CommonResult<T> success(T data) {
CommonResult<T> result = new CommonResult<>();
result.code = HttpCode.SUCCESS;
result.data = data;
result.message = "操作成功";
return result;
}
public static <T> CommonResult<T> success() {
CommonResult<T> result = new CommonResult<>();
result.code = HttpCode.SUCCESS;
result.message = "操作成功";
return result;
}
注意
我们将success
定义为静态方法,这样做的好处是,我们可以使用import static
直接引入这个静态方法。
import static com.banxia.common.CommonResult.success;
3. 定义error函数
public static <T> CommonResult<T> error(Integer code, String message) {
CommonResult<T> result = new CommonResult<>();
result.code = code;
result.message = message;
return result;
}
public static <T> CommonResult<T> error(Integer code, String message,T data) {
CommonResult<T> result = new CommonResult<>();
result.code = code;
result.message = message;
result.data = data;
return result;
}
测试test接口
@RestController
@RequestMapping("/test")
public class TestController {
@GetMapping
public CommonResult<Object> test(){
return success();
}
}
后记
统一标准化的返回结果,通常是根据公司的实际业务来的。
例如:有的公司会将code和message对应封装
public ErrorCode(Integer code, String message) {
this.code = code;
this.msg = message;
}
ErrorCode BAD_REQUEST = new ErrorCode(400, "请求参数不正确");
还有的公司会根据data是否为空,判断返回结果有没有data。
public class Result extends HashMap<String, Object>
/** 状态码 */
public static final String CODE_TAG = "code";
/** 返回内容 */
public static final String MSG_TAG = "msg";
/** 数据对象 */
public static final String DATA_TAG = "data";
public Result(int code, String msg, Object data)
{
super.put(CODE_TAG, code);
super.put(MSG_TAG, msg);
if (data!=null)
{
super.put(DATA_TAG, data);
}
}
}