SpringBoot系列(二):如何构建统一的消息响应模型


作者: 修罗debug
版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。

摘要:对于“构建统一的消息响应模型”,相信各位小伙伴在开发项目的过程中多少都有所遇见过,要知道,一个糟糕的接口响应信息的规定,对于协作开发或者接口调用方的小伙伴而言将是一个小灾难,本文将介绍一种简洁的,可用于前后端接口交互 以及 服务与服务之间进行调用时的统一消息响应模型。

内容:接着上一篇文章的内容,本文我们将继续以所搭建的标准的、企业级的Spring Boot项目为奠基,介绍分享前后端接口交互、服务与服务之间接口交互时如何规定一个统一的、标准的接口响应模型。

其实,这个统一的接口消息响应模型也没有那么高大上,其实就是参考了HTTP协议的“响应模型”而设计的一款统一消息响应模型:状态码Code、状态码描述信息Msg、响应数据Data,其对应的源代码如下所示:

public class BaseResponse<T> {
private Integer code;
private String msg;
private T data;

public BaseResponse(Integer code, String msg) {
this.code = code;
this.msg = msg;
}
public BaseResponse(StatusCode statusCode) {
this.code = statusCode.getCode();
this.msg = statusCode.getMsg();
}
public BaseResponse(Integer code, String msg, T data) {
this.code = code;
this.msg = msg;
this.data = data;
}

//省去getter setter方法
}


除此之外,众所周知,我们在前端对后端相应的接口发起请求时,一般会得到相应的响应状态码,比如大家比较熟悉的200(OK)、404(Not Found)、405(Method Not Allowed)、502(Bad Gateway)、401(Unauthorized)等等,关于其他的、详细的响应状态码列表,大家可以来此看个够:https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Status

观察这些状态码,会发现其实就是由两个字段信息组成,即Code跟Msg,因此,为了开发的方便,我们定义了包含这两个字段的枚举类StatusCode,其源代码如下所示:

/**
* 通用状态码
*/
public enum StatusCode {
Success(0,"成功"),
Fail(-1,"失败"),
InvalidParams(201,"非法的参数!"),
InvalidGrantType(202,"非法的授权类型");

private Integer code;
private String msg;

StatusCode(Integer code, String msg) {
this.code = code;
this.msg = msg;
}

//此处省略getter、setter方法
}


BaseResponse跟StatusCode相应文件的存储位置如下图所示:  



BaseResponse 加 StatusCode结合使用,可以说是风云合璧、天下无敌啊!在开发项目接口的功能方法时,如果是需要返回相应的数据列表而不是跳转页面的话,则可以采用BaseResponse作为通用的返回格式。下面就来举个栗子吧!

在server模块建立一个BaseController,然后开发两个请求对应的功能方法,如下所示:

/**
* @Author:debug (SteadyJack)
* @Date: 2019/8/24 16:07
**/
@RestController
@RequestMapping("base")
public class BaseController {

@Autowired
private IBaseService baseService;

/**
* 获取基本的信息一
* @param name
* @return
*/
@RequestMapping(value = "/info",method = RequestMethod.GET)
public BaseResponse info(String name){
BaseResponse response=new BaseResponse(StatusCode.Success);
try {
response.setData(name);
}catch (Exception e){
response=new BaseResponse(StatusCode.Fail.getCode(),e.getMessage());
}
return response;
}

/**
*交互获取基本的信息二
* @param id
* @return
*/
@RequestMapping(value = "/item",method = RequestMethod.GET)
public BaseResponse item(@RequestParam(required = false,defaultValue = "1") Integer id){
BaseResponse response=new BaseResponse(StatusCode.Success);
try {
response.setData(baseService.getItem(id));
}catch (Exception e){
response=new BaseResponse(StatusCode.Fail.getCode(),e.getMessage());
}
return response;
}
}


其中,baseService.getItem()方法的功能在于根据“主键id”获取商品的详情,其接口定义的方法代码如下所示:  

public interface IBaseService {
Item getItem(Integer id) throws Exception;
}


对应的实现类的代码如下所示:  

/**
* @Author:debug (SteadyJack)
* @Date: 2019/8/24 17:18
**/
@Service
public class BaseServiceImpl implements IBaseService{
@Autowired
private ItemMapper itemMapper;

@Override
public Item getItem(Integer id) throws Exception {
return itemMapper.selectByPrimaryKey(id);
}
}

itemMapper的代码就不贴了,各位小伙伴可以在文末将代码check下来,看一下就知道了!

下面将整个项目跑起来,然后在postman或者浏览器分别发起如下的请求,将得到相应的不同的结果。

(1)首先是:http://localhost:8081/technology/base/info?name=程序员实战基地 点击Enter键即可发起请求,得到的消息响应结果如下所示:













(2)然后是发起:http://localhost:8081/technology/base/item?id=2 点击Enter键即可发起请求,得到的消息响应结果如下所示:  



当前端开发者或者其他的接口调用者调用此接口,并得到这样的消息响应模型时,我相信对于他们而言处理起来时比较方面的,因为它们可以根据这样的数据格式定义统一的类进行接收并进行解析!

从另外的协调开发的层面来讲,这其实也有利于团队的高效开发、以及项目中代码的管理和维护!即作为接口的开发者,只需要定义好响应状态码并一股脑的把相应的数据都塞入 data 进去就可以了!其他的就是“接口请求方”的事情了。


补充:

1、本文涉及到的相关的源代码可以到此地址,check出来进行查看学习:

https://gitee.com/steadyjack/SpringBootTechnology

2、关注一下Debug的技术微信公众号呗,最新的技术文章、技术课程以及技术专栏将会第一时间在公众号发布哦!