在日常开发中,一个优雅的API,必须提供简单明了的响应值,然后根据状态码就可以大概知道问题的所在。这里主要整理一下HTTP状态码和自定义状态码。
1、HTTP状态码
当浏览者访问一个网页时,浏览者的浏览器会向网页所在服务器发出请求。当浏览器接收并显示网页前,此网页所在的服务器会返回一个包含 HTTP 状态码的信息头(server header)用以响应浏览器的请求。
常见的HTTP状态码有:
200-请求成功。
301-资源(网页等)被永久转移到其它URL。
403-服务器拒绝访问。验证身份通过了,但是资源没有权限进行操作。
404-请求资源(网页等)不存在。
500-内部服务器错误。
504-网关超时。服务器作为网关或代理,但是没有及时从上游服务器收到请求。
2、HTTP状态码分类
HTTP状态码可以分为5类:消息响应、成功响应、重定向、客户端错误、服务器错误。
3、自定义响应状态码规范
后端返回给前端一般使用json格式,定义如下:
{
#返回状态码
Code:integer,
#返回信息描述
message:string,
#返回值
data:object
}
复制代码
3.1、返回接口
public interface IResultStatus {
/**
* 状态码
* @return
*/
Integer errorCode();
/**
* 异常信息
* @return
*/
String errorMsg();
}
复制代码
3.2、状态码枚举:
public enum ResultStatus implements IResultStatus {
/**
* 状态码及对应信息
*/
//成功状态码
SUCCESS(0, "执行成功"),
//参数错误:1001~1999
PARAM_IS_INVALID(1001, "参数无效"),
PARAM_IS_BLANK(1002, "参数为空"),
PARAM_TYPE_BIND_ERROR(1003, "参数类型错误"),
//用户错误:2001~2999
USER_LOGIN_ERROR(2001, "账号不存在或密码错误"),
USER_ACCOUNT_FORBIDDEN(2002, "账户已被禁用"),
USER_NOT_EXIST(2003, "用户不存在");
private int errorCode;
private String errorMsg;
ResultStatus(int errorCode, String errorMsg) {
this.errorCode = errorCode;
this.errorMsg = errorMsg;
}
@Override
public Integer errorCode() {
return errorCode;
}
@Override
public String errorMsg() {
return errorMsg;
}
}
复制代码
状态码和信息就会一一对应,比较好维护。这样前端同事在得到返回值后,根据状态码就可以知道,大概是什么错误,再根据message相关的信息描述,可以快速定位。
3.3、返回数据体
json格式,根据不同的业务有不同的json体,可以设计一个返回体类Result
@Data
public class Result<T> {
private Integer code;
private String message;
private Object data;
public Result(ResultStatus restStatus, Object data) {
this.code = restStatus.errorCode();
this.message = restStatus.errorMsg();
this.data = data;
}
/**
* 业务成功返回业务代码和描述信息
*/
public static Result<Void> success() {
return new Result<Void>(ResultStatus.SUCCESS, null);
}
/**
* 业务成功返回业务代码,描述和返回的参数
*/
public static <T> Result<T> success(T data) {
return new Result<T>(ResultStatus.SUCCESS, data);
}
/**
* 业务成功返回业务代码,描述和返回的参数
*/
public static <T> Result<T> success(ResultStatus resultStatus, T data) {
if (resultStatus == null) {
return success(data);
}
return new Result<T>(resultStatus, data);
}
/**
* 业务异常返回业务代码和描述信息
*/
public static <T> Result<T> failure() {
return new Result<T>(ResultStatus.PARAM_TYPE_BIND_ERROR, null);
}
/**
* 业务异常返回业务代码,描述和返回的参数
*/
public static <T> Result<T> failure(ResultStatus resultStatus) {
return failure(resultStatus, null);
}
/**
* 业务异常返回业务代码,描述和返回的参数
*/
public static <T> Result<T> failure(ResultStatus resultStatus, T data) {
if (resultStatus == null) {
return new Result<T>(ResultStatus.PARAM_IS_INVALID, null);
}
return new Result<T>(resultStatus, data);
}
}
复制代码
3.4、返回体测试
@RestController
@RequestMapping("/api/demo2")
public class Demo2Controller {
private static final HashMap<String, Object> INFO;
static {
INFO = new HashMap<>();
INFO.put("name", "张三");
INFO.put("age", "25");
}
@GetMapping("/getInfo")
public Map<String, Object> getInfo() {
return INFO;
}
@GetMapping("/getInfoResult")
public Result<Map<String, Object>> getInfoResult() {
return Result.success(INFO);
}
}
复制代码
结果参考: