1. 概述
在项目中,将response返回信息的格式进行统一封装,不仅有利于与前端统一处理接口的返回,而且具备良好的可读性。通常情况下项目中采用JSON(JavaScript Object Notation)序列化数据再进行传输,统一格式的response也就包含三部分信息:
- 状态码:定义了成功、失败的标志,还可以包含一些内部定义的状态码,如对应用户名不存在时应该返回的状态码。注意此状态码与HTTP状态码无关。
- 提示信息:以一段字符串补充说明状态码的具体信息。如果允许,前端还可以直接将该字段信息反馈给用户。
- 携带信息:这部分是response中的关键,包含了用户正在希望请求的信息。特别的是,如果请求失败时,该部分通常为null或被隐藏。
2. 统一返回状态码及对应提示信息
使用一个枚举类型定义状态码及其对应的提示信息,方便扩展。
/**
* API 统一返回状态码
*/
public enum ResultCode {
/* 成功状态码 */
SUCCESS(0, "Request is successful"),
FAIL(1, "Request is failed"),
TOKEN_INVALID(40001, "Token is null or invalid"),
ACCESS_DENIED(40003, "Access denied"),
FAIL4DELETE(50001, "Delete failed"),
FAIL4UPDATE(50002, "Update failed");
private Integer code;
private String message;
ResultCode(Integer code, String message){
this.code = code;
this.message = message;
}
public Integer code(){
return this.code;
}
public String message(){
return this.message;
}
}
3. 统一封装response
使用一个RestResponse类封装reponse信息,其包含三个成员变量:code
、message
和data
,以及在不同情况下调用的构造方法。
package me.ifight.model.common;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
@ApiModel(description = "返回结果")
public class RestResponse {
@ApiModelProperty("状态码 0:成功")
private int code;
@ApiModelProperty("消息")
private String message;
@ApiModelProperty("返回数据")
private Object data;
public RestResponse(){
}
public static RestResponse succuess(){
RestResponse restResponse = new RestResponse();
restResponse.setResultCode(ResultCode.SUCCESS);
return restResponse;
}
public static RestResponse succuess(Object data){
RestResponse restResponse = new RestResponse();
restResponse.setResultCode(ResultCode.SUCCESS);
restResponse.setData(data);
return restResponse;
}
public static RestResponse fail() {
RestResponse restResponse = new RestResponse();
restResponse.setResultCode(ResultCode.FAIL);
return restResponse;
}
public static RestResponse fail(ResultCode resultCode) {
RestResponse restResponse = new RestResponse();
restResponse.setResultCode(resultCode);
return restResponse;
}
public static RestResponse fail(String message) {
RestResponse restResponse = new RestResponse();
restResponse.setCode(ResultCode.FAIL.code());
restResponse.setMessage(message);
return restResponse;
}
public static RestResponse fail(Integer code, String message) {
RestResponse restResponse = new RestResponse();
restResponse.setCode(code);
restResponse.setMessage(message);
return restResponse;
}
public static RestResponse fail(ResultCode resultCode, Object data) {
RestResponse restResponse = new RestResponse();
restResponse.setResultCode(resultCode);
restResponse.setData(data);
return restResponse;
}
private void setResultCode(ResultCode resultCode){
this.code = resultCode.code();
this.message = resultCode.message();
}
public void setData(Object data){
this.data = data;
}
public Object getData(){
return data;
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public String getMessage() {
return message;
}
public void setMessage(String message){
this.message = message;
}
}
4. 应用场景
下面是一个简单的查询用户信息的接口:
@GetMapping("/queryUserById")
@ApiOperation("根据ID查找用户信息")
@ApiImplicitParam(name = "id", value = "用户主键id", required = true, dataType = "int")
public RestResponse queryUserById(int id){
logger.info("#queryUserId, id:" + id);
UserVO userVO = userService.queryUserById(id);
if(userVO != null){
return RestResponse.succuess(userVO);
}else{
return RestResponse.fail("Not Found the ID");
}
}
如果查询成功将会返回如下信息:
{
"code":0,
"message":"Request is successful",
"data":{
"username":"admin",
"age":"20"
}
}
查询失败
{
"code":1,
"message":"Request is failed",
"data":null
}
有不合理之处,请留言指正,谢谢
更新1
业务定义的状态码最好不要与HTTP状态码相同,因此修改了ResultCode
枚举类的错误码
-- 2019-01-17