В повседневной разработке элегантный API должен предоставлять простые и четкие значения ответов, и тогда вы сможете примерно определить проблему на основе кода состояния. Здесь мы в основном организуем коды состояния HTTP и пользовательские коды состояния.
1. Код состояния HTTP
Когда браузер посещает веб-страницу, браузер браузера отправляет запрос на сервер, на котором расположена веб-страница. Прежде чем браузер получит и отобразит веб-страницу, сервер, на котором расположена веб-страница, вернет заголовок сервера, содержащий код состояния HTTP, в ответ на запрос браузера.
Общие коды состояния 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;
}
}
复制代码
Код состояния и информация будут соответствовать друг другу, что упрощает обслуживание. Таким образом, после того, как внешние коллеги получат возвращаемое значение, они могут узнать, что, вероятно, связано с ошибкой, на основе кода состояния, а затем могут быстро найти ее в соответствии с описанием информации, связанной с сообщением.
3.3, вернуть тело данных
json, существуют разные тела json в зависимости от бизнеса, вы можете создать класс возвращаемого тела. Результат
@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);
}
}
复制代码
Ссылка на результат: