从前后端分离模式开始后,后端只返回给前端json数据,在实际开发中,为了降低开发人员之间的沟通成本,一般返回结果会定义成一个统一格式,具体的格式根据实际开发业务不同有所区别。从前端的角度思考,调用后端接口后如果成功了则拿到想要的数据或者对应的信息提示,如果不成功也应该有相应的信息提示。从这个角度出发,我们将返回结果设计为:
import com.example.assertdemo.constant.ResultCodeEnum;
import lombok.Data;
import java.io.Serializable;
/**
* @author LoneWalker
*/
@Data
public class ApiResult implements Serializable {
private static final long serialVersionUID = 411731814484355577L;
/**
* 状态码
*/
private int code;
/**
* 提示信息
*/
private String msg;
/**
* 相关数据
*/
private T data;
public String toString() {
return "ApiResult(code=" + this.getCode() + ", msg=" + this.getMsg() + ", data=" + this.getData() + ")";
}
/**
* 构造器 自定义响应码与提示信息
* @param code 响应码
* @param message 提示信息
*/
private ApiResult(int code,String message){
this.code = code;
this.msg = message;
}
/**
* 构造器 自定义响应码、提示信息、数据
* @param code 响应码
* @param message 提示信息
* @param data 返回数据
*/
private ApiResult(int code,String message,T data){
this(code,message);
this.data = data;
}
/**
* 成功构造器 无返回数据
*/
public static ApiResult success(){
return new ApiResult<>(ResultCodeEnum.SUCCESS.getCode(), ResultCodeEnum.SUCCESS.getMessage());
}
/**
* 成功构造器 自定义提示信息 无返回数据
* @param message 提示信息
*/
public static ApiResult success(String message){
return new ApiResult<>(ResultCodeEnum.SUCCESS.getCode(), message);
}
/**
* 成功构造器 有返回数据
*/
public static ApiResult success(T data){
return new ApiResult<>(ResultCodeEnum.SUCCESS.getCode(), ResultCodeEnum.SUCCESS.getMessage(),data);
}
/**
* 失败构造器 无返回数据
*/
public static ApiResult fail(){
return new ApiResult<>(ResultCodeEnum.FAIL.getCode(), ResultCodeEnum.FAIL.getMessage());
}
/**
* 失败构造器 自定义提示信息 无返回数据
* @param message 提示信息
*/
public static ApiResult fail(String message){
return new ApiResult<>(ResultCodeEnum.FAIL.getCode(), message);
}
/**
* 失败构造器 有返回数据
*/
public static ApiResult fail(T data){
return new ApiResult<>(ResultCodeEnum.FAIL.getCode(), ResultCodeEnum.FAIL.getMessage(),data);
}
}
除去基础的操作成功或失败,可以将状态码归类,例如请求参数问题归纳到1001-1999之间。
import lombok.Getter;
/**
* @author LoneWalker
*/
@Getter
public enum ResultCodeEnum{
/**
* success
*/
SUCCESS(0,"操作成功"),
/**
* fail
*/
FAIL(-1,"操作失败"),
/**
* 参数错误:1001-1999
*/
PARAM_IS_INVALID(1001,"参数无效"),
PARAM_TYPE_ERROR(1002,"参数类型错误"),
;
/**
* 状态码
*/
private final int code;
/**
* 提示信息
*/
private final String message;
ResultCodeEnum(Integer code, String message){
this.code = code;
this.message = message;
}
}
controller
import com.example.assertdemo.common.ApiResult;
import com.example.assertdemo.entity.Contract;
import com.example.assertdemo.req.AddContractReq;
import com.example.assertdemo.req.QueryContractReq;
import com.example.assertdemo.service.ContractService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
@RequestMapping("/contract/")
public class ContractController {
@Autowired
private ContractService contractService;
@PostMapping("add")
public ApiResult addContract(@RequestBody AddContractReq request) {
return contractService.addContract(request);
}
@PostMapping("list")
public ApiResult> listContract(@RequestBody QueryContractReq request) {
return contractService.listContract(request);
}
}
新增或查询参数类
import lombok.Data;
/**
* @author LoneWalker
* @date 2022/8/28
* @description
*/
@Data
public class AddContractReq {
/**
* 合同编号
*/
private String code;
/**
* 合同名称
*/
private String name;
/**
* 客户名称
*/
private String customer;
}
import lombok.Data;
/**
* @author LoneWalker
* @date 2022/8/28
* @description
*/
@Data
public class QueryContractReq {
/**
* 合同名称
*/
private String contractName;
/**
* 客户名称
*/
private String customer;
}
Service
import com.example.assertdemo.common.ApiResult;
import com.example.assertdemo.entity.Contract;
import com.example.assertdemo.req.AddContractReq;
import com.example.assertdemo.req.QueryContractReq;
import java.util.List;
public interface ContractService {
/**
* 添加合同信息
* @param request
* @return
*/
ApiResult addContract(AddContractReq request);
/**
* 合同列表数据
* @param request 查询参数
* @return
*/
ApiResult> listContract(QueryContractReq request);
}
impl
import com.example.assertdemo.common.ApiResult;
import com.example.assertdemo.entity.Contract;
import com.example.assertdemo.req.AddContractReq;
import com.example.assertdemo.req.QueryContractReq;
import com.example.assertdemo.service.ContractService;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
@Service("contractService")
public class ContractServiceImpl implements ContractService {
@Override
public ApiResult addContract(AddContractReq request) {
//存入数据库
return ApiResult.success();
}
@Override
public ApiResult> listContract(QueryContractReq request) {
//模拟数据
List list = new ArrayList<>();
Contract contractOne = new Contract(1L, "HT082801", "临床试验一期合同", "省立医院");
Contract contractTwo = new Contract(2L, "HT082802", "临床试验二期合同", "省立医院");
Contract contractThree = new Contract(3L, "HT082803", "临床试验三期合同", "省立医院");
list.add(contractOne);
list.add(contractTwo);
list.add(contractThree);
return ApiResult.success(list);
}
}
启动项目,新增一条数据
查询数据
以上都是接口调用成功的情况,当业务出现异常,按照我们的初衷,需要将业务异常结果组装成统一的信息返回给前端进行提示。
下一篇 代码优雅之道——断言 + Springboot统一异常处理