SpringBoot接口 - 如何优雅的对接口返回内容统一封装?
在以SpringBoot开发Restful接口时,统一返回方便前端进行开发和封装,以及出现时给出响应编码和信息。@pdai
RESTful API接口?
- 什么是 REST?
Representational State Transfer,翻译是“表现层状态转化”。可以总结为一句话:REST 是所有 Web 应用都应该遵守的架构设计指导原则。
面向资源是 REST 最明显的特征,对于同一个资源的一组不同的操作。资源是服务器上一个可命名的抽象概念,资源是以名词为核心来组织的,首先关注的是名词。REST 要求,必须通过统一的接口来对资源执行各种操作。对于每个资源只能执行一组有限的操作。
- 什么是 RESTful API?
符合 REST 设计标准的 API,即 RESTful API。REST 架构设计,遵循的各项标准和准则,就是 HTTP 协议的表现,换句话说,HTTP 协议就是属于 REST 架构的设计模式。比如,无状态,请求-响应。
Restful相关文档可以参考 https://restfulapi.net/
为什么要统一封装接口
现在大多数项目采用前后分离的模式进行开发,统一返回方便前端进行开发和封装,以及出现时给出响应编码和信息。
以查询某个用户接口而言,如果没有封装, 返回结果如下
{
"userId": 1,
"userName": "赵一"
}
如果封装了,返回正常的结果如下:
{
"timestamp": 11111111111,
"status": 200,
"message": "success",
"data": {
"userId": 1,
"userName": "赵一"
}
}
异常返回结果如下:
{
"timestamp": 11111111111,
"status": 10001,
"message": "User not exist",
"data": null
}
实现案例
如何实现上面的封装呢?
状态码封装
这里以常见的状态码为例,包含responseCode 和 description两个属性。
如果还有其它业务状态码,也可以放到这个类中。
/**
* @author pdai
*/
@Getter
@AllArgsConstructor
public enum ResponseStatus {
SUCCESS("200", "success"),
FAIL("500", "failed"),
HTTP_STATUS_200("200", "ok"),
HTTP_STATUS_400("400", "request error"),
HTTP_STATUS_401("401", "no authentication"),
HTTP_STATUS_403("403", "no authorities"),
HTTP_STATUS_500("500", "server error");
public static final List<ResponseStatus> HTTP_STATUS_ALL = Collections.unmodifiableList(
Arrays.asList(HTTP_STATUS_200, HTTP_STATUS_400, HTTP_STATUS_401, HTTP_STATUS_403, HTTP_STATUS_500
));
/**
* response code
*/
private final String responseCode;
/**
* description.
*/
private final String description;
}
返回内容封装
包含公共的接口返回时间,状态status, 消息message, 以及数据data。
考虑到数据的序列化(比如在网络上传输),这里data有时候还会extends Serializable。
@Data
@Builder
public class ResponseResult<T> {
/**
* response timestamp.
*/
private long timestamp;
/**
* response code, 200 -> OK.
*/
private String status;
/**
* response message.
*/
private String message;
/**
* response data.
*/
private T data;
/**
* response success result wrapper.
*
* @param <T> type of data class
* @return response result
*/
public static <T> ResponseResult<T> success() {
return success(null);
}
/**
* response success result wrapper.
*
* @param data response data
* @param <T> type of data class
* @return response result
*/
public static <T> ResponseResult<T> success(T data) {
return ResponseResult.<T>builder().data(data)
.message(ResponseStatus.SUCCESS.getDescription())
.status(ResponseStatus.SUCCESS.getResponseCode())
.timestamp(System.currentTimeMillis())
.build();
}
/**
* response error result wrapper.
*
* @param message error message
* @param <T> type of data class
* @return response result
*/
public static <T extends Serializable> ResponseResult<T> fail(String message) {
return fail(null, message);
}
/**
* response error result wrapper.
*
* @param data response data
* @param message error message
* @param <T> type of data class
* @return response result
*/
public static <T> ResponseResult<T> fail(T data, String message) {
return ResponseResult.<T>builder().data(data)
.message(message)
.status(ResponseStatus.FAIL.getResponseCode())
.timestamp(System.currentTimeMillis())
.build();
}
}
接口返回时调用
在接口返回时调用, 以用户接口为例
/**
* @author pdai
*/
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private IUserService userService;
/**
* @param user user param
* @return user
*/
@ApiOperation("Add/Edit User")
@PostMapping("add")
public ResponseResult<User> add(User user) {
if (user.getId()==null || !userService.exists(user.getId())) {
user.setCreateTime(LocalDateTime.now());
user.setUpdateTime(LocalDateTime.now());
userService.save(user);
} else {
user.setUpdateTime(LocalDateTime.now());
userService.update(user);
}
return ResponseResult.success(userService.find(user.getId()));
}
/**
* @return user list
*/
@ApiOperation("Query User One")
@GetMapping("edit/{userId}")
public ResponseResult<User> edit(@PathVariable("userId") Long userId) {
return ResponseResult.success(userService.find(userId));
}
}
示例源码
https://github.com/realpdai/tech-pdai-spring-demos
更多内容
告别碎片化学习,无套路一站式体系化学习后端开发: Java 全栈知识体系(https://pdai.tech)
SpringBoot接口 - 如何优雅的对接口返回内容统一封装?的更多相关文章
- SpringBoot接口 - 如何优雅的写Controller并统一异常处理?
SpringBoot接口如何对异常进行统一封装,并统一返回呢?以上文的参数校验为例,如何优雅的将参数校验的错误信息统一处理并封装返回呢?@pdai 为什么要优雅的处理异常 如果我们不统一的处理异常,经 ...
- SpringBoot接口 - 如何优雅的对参数进行校验?
在以SpringBoot开发Restful接口时, 对于接口的查询参数后台也是要进行校验的,同时还需要给出校验的返回信息放到上文我们统一封装的结构中.那么如何优雅的进行参数的统一校验呢? @pdai ...
- SpringBoot接口 - API接口有哪些不安全的因素?如何对接口进行签名?
在以SpringBoot开发后台API接口时,会存在哪些接口不安全的因素呢?通常如何去解决的呢?本文主要介绍API接口有不安全的因素以及常见的保证接口安全的方式,重点实践如何对接口进行签名.@pdai ...
- 2、SpringBoot接口Http协议开发实战8节课(1-6)
1.SpringBoot2.xHTTP请求配置讲解 简介:SpringBoot2.xHTTP请求注解讲解和简化注解配置技巧 1.@RestController and @RequestMapping是 ...
- 【接口】SpringBoot+接口开发(一)
一.接口的简单介绍 1.什么是接口:接口及服务: 2.接口的分类:(1)系统的内部接口;(2)第三方的外部接口; 3.简述接口原理图: 4.接口协议:是指客户端跟服务器之间或者接口与接口间进行的通讯时 ...
- SpringBoot接口 - 如何生成接口文档之非侵入方式(通过注释生成)Smart-Doc?
通过Swagger系列可以快速生成API文档,但是这种API文档生成是需要在接口上添加注解等,这表明这是一种侵入式方式: 那么有没有非侵入式方式呢, 比如通过注释生成文档? 本文主要介绍非侵入式的方式 ...
- 一个注解搞定SpringBoot接口定制属性加解密
前言 上个月公司另一个团队做的新项目上线后大体上运行稳定,但包括研发负责人在内的两个人在项目上线后立马就跳槽了,然后又交接给了我这个「垃圾回收人员」. 本周甲方另一个厂家的监控平台扫描到我们这个项目某 ...
- SpringBoot接口服务处理Whitelabel Error Page(转)
To switch it off you can set server.error.whitelabel.enabled=false http://stackoverflow.com/question ...
- Java基础学习笔记十二 类、抽象类、接口作为方法参数和返回值以及常用API
不同修饰符使用细节 常用来修饰类.方法.变量的修饰符 public 权限修饰符,公共访问, 类,方法,成员变量 protected 权限修饰符,受保护访问, 方法,成员变量 默认什么也不写 也是一种权 ...
随机推荐
- DDT数据驱动性能测试(一)
DDT数据驱动性能测试(一) 一.csv数据文件设置 1.使用场景:测试过程中需要使用手机号码等大量数据时,用random函数随机生成数字:也可以使用Excel拖动生成一批手机号,也有可以从数据库中导 ...
- windows 安装 kalfka 并快速启动
1.安装Java 环境 https://www.java.com/zh_CN/ 直接下载安装即可 (如果之前有配置过java环境 可以先跳过此步骤,但是如果运行的时候报错就需要把之前的jdk环境变量删 ...
- python学习-Day27
目录 今日内容详细 动态方法与静态方法 动态方法 绑定给对象的方法 绑定给类的方法 静态方法 继承 继承的含义 继承的目的 继承的基本使用 继承的本质 名字的查找顺序 不继承的情况下 单继承的情况下 ...
- XCTF练习题---MISC---掀桌子
XCTF练习题---MISC---掀桌子 flag:flag{hjzcydjzbjdcjkzkcugisdchjyjsbdfr} 解题步骤: 1.观察题目,发现没有附件,只有一串代码. 2.根据代码内 ...
- XCTF练习题---MISC---pdf
XCTF练习题---CRYPTO---混合编码解析 flag:flag{security_through_obscurity} 解题步骤: 1.观察题目,下载附件 2.根据题目提示,下载文件,发现是一 ...
- [AcWing 774] 最长单词
点击查看代码 #include<iostream> using namespace std; string str, res; int main() { while (cin >&g ...
- 3D打印CLI文件格式的读取
CLI 英文全称:COMMON LAYER INTERFACE 中文名称:通用层接口. 推荐从官方网址看一下其完整的内容: (https://www.hmilch.net/downloads/cli_ ...
- 审计 Linux 系统的操作行为的 5 种方案对比
点击上方"开源Linux",选择"设为星标" 回复"学习"获取独家整理的学习资料! 很多时候我们为了安全审计或者故障跟踪排错,可能会记录分析 ...
- 不再空谈AI,从打造一台智能无人机开始
对于大多数无人机爱好者来说,能自己从头开始组装一台无人机,之后加入AI算法,能够航拍,可以目标跟踪,是心中的梦想. 并且,亲自从零开始完成复杂系统,这是掌握核心技术的必经之路. 开课吧特邀北京航空航天 ...
- JZ008和大于等于target的最短数组
title: 长度最小的子数组 题目描述 题目链接:长度最小的子数组.剑指offer008 解题思路 简单滑动窗口题目,需要知道: 窗口左指针移动条件:窗口内总和 ≥ target 即可以不断移动窗口 ...