响应数据封装
为了使接口的返回结果数据更加规范化,便于接口测试和前端处理,需要以统一的格式来返回数据;
为了不在每一个接口里面,都写一段返回数据封装的代码,将数据封装的逻辑提取出来,使用面相切面原理(AOP),统一对数据进行封装。
如上,涉及到两个问题:
定义响应实体的数据结构;
响应数据统一封装;下面,我们分别来介绍这两个问题如何处理。
数据结构如下
{
"code": 401,
"data": null,
"msg": "需要登录后操作"
}
代码
package com.sangeng.domain;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.sangeng.enums.AppHttpCodeEnum;
import java.io.Serializable;
@JsonInclude(JsonInclude.Include.NON_NULL)
public class ResponseResult<T> implements Serializable {
private Integer code;
private String msg;
private T data;
public ResponseResult() {
this.code = AppHttpCodeEnum.SUCCESS.getCode();
this.msg = AppHttpCodeEnum.SUCCESS.getMsg();
}
public ResponseResult(Integer code, T data) {
this.code = code;
this.data = data;
}
public ResponseResult(Integer code, String msg, T data) {
this.code = code;
this.msg = msg;
this.data = data;
}
public ResponseResult(Integer code, String msg) {
this.code = code;
this.msg = msg;
}
public static ResponseResult errorResult(int code, String msg) {
ResponseResult result = new ResponseResult();
return result.error(code, msg);
}
public static ResponseResult okResult() {
ResponseResult result = new ResponseResult();
return result;
}
public static ResponseResult okResult(int code, String msg) {
ResponseResult result = new ResponseResult();
return result.ok(code, null, msg);
}
public static ResponseResult okResult(Object data) {
ResponseResult result = setAppHttpCodeEnum(AppHttpCodeEnum.SUCCESS,
AppHttpCodeEnum.SUCCESS.getMsg());
if (data != null) {
result.setData(data);
}
return result;
}
public static ResponseResult errorResult(AppHttpCodeEnum enums) {
return setAppHttpCodeEnum(enums, enums.getMsg());
}
public static ResponseResult errorResult(AppHttpCodeEnum enums, String msg) {
return setAppHttpCodeEnum(enums, msg);
}
public static ResponseResult setAppHttpCodeEnum(AppHttpCodeEnum enums) {
return okResult(enums.getCode(), enums.getMsg());
}
private static ResponseResult setAppHttpCodeEnum(AppHttpCodeEnum enums,
String msg) {
return okResult(enums.getCode(), msg);
}
public ResponseResult<?> error(Integer code, String msg) {
this.code = code;
this.msg = msg;
return this;
}
public ResponseResult<?> ok(Integer code, T data) {
this.code = code;
this.data = data;
return this;
}
public ResponseResult<?> ok(Integer code, T data, String msg) {
this.code = code;
this.data = data;
this.msg = msg;
return this;
}
public ResponseResult<?> ok(T data) {
this.data = data;
return this;
}
public Integer getCode() {
return code;
}
public void setCode(Integer code) {
this.code = code;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
}
使用
HTTP状态码
表示请求是否成功;最简单的模型是,当状态码为200时,表示成功;当状态码为 3xx,4xx,5xx 时,代表请求失败。HTTP的状态码,已经清晰的描述了请求的响应状态(成功/失败)。
复杂响应模型中, HTTP状态码
复杂模型中, HTTP状态码还包含请求成功的类型和失败的原因。
复杂模型中,请求成功的状态码及含义:
成功状态
这类状态码表示请求已成功被服务器接收、理解、并接受。常见的2xx状态码包括:
状态码 | 类别 | 含义 |
---|---|---|
200 | 成功 | 请求已成功处理。 |
201 | 成功 | 已创建。请求已被成功处理,并且服务器创建了新的资源。 |
202 | 成功 | 已接受。请求已被接受,但处理尚未完成。 |
204 | 成功 | 无内容。服务器成功处理了请求,但未返回任何内容。 |
重定向状态码
这类状态码表示为了完成请求,需要进一步的操作。通常,这些状态码会伴随着一个Location头,指向用户应访问的URL。常见的3xx状态码包括
状态码 | 类别 | 含义 |
---|---|---|
301 | 重定向 | 永久移动。请求的资源已被永久移动到新位置。 |
302 | 重定向 | 临时移动。请求的资源已被临时移动。 |
304 | 重定向 | 未修改。自从上次请求后,请求的资源未被修改。 |
客户端错误状态码
这类状态码表示请求中存在错误,防止了服务器对其进行处理。常见的4xx状态码包括:
状态码 | 类别 | 含义 |
---|---|---|
400 | 客户端错误 | 错误请求。由于语法错误或请求无效,服务器无法处理请求。 |
401 | 客户端错误 | 未授权。请求未通过身份验证。 |
403 | 客户端错误 | 禁止访问。服务器拒绝请求。 |
404 | 客户端错误 | 未找到。服务器找不到请求的资源。 |
服务器错误状态码
这类状态码表示服务器在尝试处理请求时发生了错误。常见的5xx状态码包括:
状态码 | 类别 | 含义 |
---|---|---|
500 | 服务器错误 | 内部服务器错误。服务器遇到了意外情况。 |
501 | 服务器错误 | 未实现。服务器不支持请求的功能。 |
503 | 服务器错误 | 服务不可用。服务器暂时无法处理请求。 |
此时我们可以封装一个枚举类用来存储这些常用的状态码
public enum HttpStatusCode {
// 信息性状态码
CONTINUE(100, "继续"),
// 成功状态码
OK(200, "成功"),
CREATED(201, "已创建"),
ACCEPTED(202, "已接受"),
NO_CONTENT(204, "无内容"),
// 重定向状态码
MOVED_PERMANENTLY(301, "永久移动"),
FOUND(302, "找到"),
NOT_MODIFIED(304, "未修改"),
// 客户端错误状态码
BAD_REQUEST(400, "错误请求"),
UNAUTHORIZED(401, "未授权"),
FORBIDDEN(403, "禁止访问"),
NOT_FOUND(404, "未找到"),
// 服务器错误状态码
INTERNAL_SERVER_ERROR(500, "内部服务器错误"),
NOT_IMPLEMENTED(501, "未实现"),
SERVICE_UNAVAILABLE(503, "服务不可用");
private final int code;
private final String description;
HttpStatusCode(int code, String description) {
this.code = code;
this.description = description;
}
public int getCode() {
return code;
}
public String getDescription() {
return description;
}
}