【SpringBoot Web框架实战教程】04 SpringBoot 规范统一输出 json

不积跬步,无以至千里;不积小流,无以成江海。大家好,我是闲鹤,微信:xxh_1459,十多年开发、架构经验,先后在华为、迅雷服役过,也在高校从事教学3年;目前已创业了7年多,主要从事物联网/车联网相关领域和业务。喜欢交友、骑行、写毛笔字、弹吉他、折腾硬件和写代码。


导读

这是一系列关于 SpringBoot Web框架实战 的教程,从项目的创建,到一个完整的 web 框架(包括异常处理、拦截器、context 上下文等);从0开始,到一个可以直接运用在生产环境中的web框架,所有源码均开源。


正文

我们写的 Spring Boot 这一系列文章,是以最终开发一个web api项目为目标,根据开发所需,逐步来学习和撰写的。比如:

  • 第一篇 使用 pom 方式创建 SpringBoot 第一个项目,这篇介绍了如何以最简单的方式运行了一个 Spring Boot 项目;

  • 第二篇 Spring Boot 返回 JSON,描述了如何返回 json 格式数据;

  • 第三篇 Sping Boot 获取 http 请求参数,介绍了如何使用 Spring Boot 获取 api 请求接口的参数;

由于我们的目标是开发一个提供 api json 接口访问的 web server,一般情况下,对于统一对外的 api json 接口,都有一定的格式规范,比如类似以下格式:

{code: 200,msg: "success",data: {}
}

所以,这篇,我们先把一个基本的 Rest api 框架的统一规范输出给设计好。

创建返回的数据结构

我们以上面的格式为我们所需要的返回数据格式,可以看出,这里基本有3个字段:

字段类型含义
codeInt返回码
msgString文本描述
dataObject/Array返回的具体数据
  • code:可以定义为一系列常量

  • msg:为 code 对应的具体的描述,如果需要兼容其他语种的话,可以增加对其他语种的支持,这里我们先仅处理中文

  • data:为具体的返回数据,它的类型可以为对象,也可以为列表,在设计时,我们可以采用泛型来处理

我们把这个数据结构,定义为bean,所以我们先在我们项目中创建 beans 包,然后在该包里创建 RtData.java:

package com.jdz.beans;public class RtData<T> {private Integer code;private String msg;private T data;public RtData() {this.code = ErrType.SUCCESS;this.msg = ErrType.getDesc(this.code);this.data = (T) new Object();}public Integer getCode() {return code;}public void setCode(Integer code) {this.code = code;this.msg = ErrType.getDesc(this.code);}public String getMsg() {return msg;}public T getData() {return data;}public void setData(T data) {this.data = data;}
}

说明 在构造函数中,对 code 取默认值 msg 的值是取决于 code 值的,所以 msg 不对外进行 setter

code 为常量,并且需要与 msg 进行映射,因此我们定义 ErrType 类型:

package com.jdz.beans;import java.util.HashMap;
import java.util.Map;public class ErrType {public static final Integer SUCCESS                 =       200;    // 成功public static final Integer ERR_PARAMS              =       100;    // 参数错误public static final Integer ERR_ACCESS              =       101;    // 访问失败public static final Integer ERR_NOT_PRIVILEGE       =       102;    // 没有权限public static final Integer ERR_INNER               =       400;    // 内部错误private static final Map<Integer, String> descMap = new HashMap<Integer, String>(){{put(SUCCESS,                        "成功");put(ERR_PARAMS,                     "参数错误");put(ERR_ACCESS,                     "访问失败");put(ERR_NOT_PRIVILEGE,              "没有权限");put(ERR_INNER,                      "内部错误");}};public static String getDesc(Integer code) {String res = descMap.get(code);return res == null ? "未定义" : res;}
}

说明: 常量类型定义为 public 可以直接对外访问 code 对应的 msg ,通过 getDesc 方法获取

controller 类改写

由于我们每个 controller 返回的方式都是一致的,所以我们把返回的方法抽象出来,定义一个 controller 基类,即:

package com.jdz.controllers;import com.jdz.beans.RtData;public class BaseController {/*** 默认返回值*/public <T> RtData<T> rtJson() {return new RtData<>();}/*** 定义 code 返回值*/public <T> RtData<T> rtJson(Integer code) {RtData<T> rtData = new RtData<>();rtData.setCode(code);return rtData;}/*** 定义 data 返回值*/public <T> RtData<T> rtJson(T data) {RtData<T> rtData = new RtData<>();rtData.setData(data);return rtData;}/*** 定义 code 和 data 返回值*/public <T> RtData<T> rtJson(Integer code, T data) {RtData<T> rtData = new RtData<>();rtData.setCode(code);rtData.setData(data);return rtData;}
}

再定义我们具体的 controller 类:

package com.jdz.controllers;import com.jdz.beans.RtData;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import java.util.ArrayList;
import java.util.List;@RestController
public class IndexController extends BaseController {@RequestMapping("/index")public RtData<String> index() {return rtJson();}@RequestMapping("/list")public RtData<List<Integer>> list() {List<Integer> l = new ArrayList<>();for(int i = 0; i < 10; i++) l.add(i);return rtJson(l);}
}

访问: http://localhost:8080/index 返回:

{code: 200,data: { },msg: "成功"
}

访问:http://localhost:8080/list 返回:

{code: 200,data: [0,1,2,3,4,5,6,7,8,9],msg: "成功"
}

整个目录结构:

javaapp
├─pom.xml
├─src
|  ├─main
|  |  ├─java
|  |  |  ├─com
|  |  |  |  ├─jdz
|  |  |  |  |  ├─App.java
|  |  |  |  |  ├─controllers
|  |  |  |  |  |      ├─BaseController.java
|  |  |  |  |  |      └IndexController.java
|  |  |  |  |  ├─config
|  |  |  |  |  |   └MyFastJsonConfig.java
|  |  |  |  |  ├─beans
|  |  |  |  |  |   ├─ErrType.java
|  |  |  |  |  |   └RtData.java

后面我们所有的项目,都以这个为模板,在这个基础上进行开发迭代。

系列文章
【SpringBoot Web框架实战】01 使用 pom 方式创建 SpringBoot 第一个项目
【SpringBoot Web框架实战教程】02 SpringBoot 返回 JSON
【SpringBoot Web框架实战教程】03 SpingBoot 获取 http 请求参数


近期文章
# 车联网
【自动化运维】不要相信人,把所有的东西都交给机器去处理
从华为无线网络框架说Dispatch服务
百万级物联网框架设计
高并发服务器之泄峰
 

# 硬件
stm32驱动直流电机实现启动/加速/减速/倒车/停车等功能
stm32 定时器输出比较(OC)与PWM的理解和应用
stm32 定时器中断
STM32 外部中断的理解

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/36385.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

台灯的功能作用有哪些?分享好用的护眼灯!看完就知道台灯怎么选

在当今时代&#xff0c;学生们长时间地沉浸于平板、手机、电脑等电子设备中&#xff0c;这些设备的屏幕往往伴随着频闪和蓝光辐射&#xff0c;这无疑对视力健康构成了潜在威胁。家长们日益关注孩子的护眼养眼问题&#xff0c;因为视力疲劳和眼部疾病不仅会降低个体的生活质量&a…

已解决:macOS Navicat保存密码失败(Failed to save password Error code: -34018),错误代码34018

Navicat 16 包括 Navicat15诸多版本都存在着问题&#xff0c;还要我去搞什么钥匙串访问&#xff0c;真麻烦&#xff01; Failed to save password Error code: -34018别搞那些有的没的方案&#xff01;就是TNT没 PJ 完美才导致这个问题出现&#xff0c;现在换了个PJ好的16.3.7版…

哈希表 | 哈希查找 | 哈希函数 | 数据结构 | 大话数据结构 | Java

&#x1f64b;大家好&#xff01;我是毛毛张! &#x1f308;个人首页&#xff1a; 神马都会亿点点的毛毛张 &#x1f4cc;毛毛张今天分享的内容&#x1f586;是数据结构中的哈希表&#xff0c;毛毛张主要是依据《大话数据结构&#x1f4d6;》的内容来进行整理&#xff0c;不…

上午写的博客,下午就上了bing首页,惊不惊喜,意不意外

今天上午写了一篇《用免费的“山水博客”来管理你的离线文章》的博客&#xff0c;没想到下午在必应就搜到了&#xff0c;而且还是首页第四个。 不由的让人感概&#xff0c;以前写了那么多的博客&#xff0c;想将排名排前点&#xff0c;在网上找了不少秘籍&#xff0c;都没成功&…

节点名称和节点句柄什么关系?

节点名称&#xff08;Node Name&#xff09;和节点句柄&#xff08;NodeHandle&#xff09;在ROS&#xff08;Robot Operating System&#xff09;中都是重要的概念&#xff0c;它们之间的关系可以归纳如下&#xff1a; 定义和用途&#xff1a; 节点名称&#xff1a;每个ROS节…

计算机视觉全系列实战教程 (实战):图像锐化操作(并手写锐化操作)

文章目录 前言1、什么是图像锐化2、如何进行图像锐化1.图像预处理2.定义锐化卷积核3.对图像进行卷积操作&#xff08;实现图像锐化&#xff09; 总结 前言 提示&#xff1a;本文主要通过手写图像锐化算法来理解图像像素的遍历&#xff1a; 我们知道图像的高斯模糊的在实践中是…

神经网络学习笔记9-简单的反向传播和线性回归

tensor在pytorch中是一个非常重要的类型 假如需要计算梯度&#xff0c;就将tensor中 requires_grad设为true loss是一个张量&#xff0c;在做运算时构建运算图&#xff0c;因此不要直接进行&#xff0c;会将将梯度存入w&#xff0c;当反向传播完成 后&#xff0c;该计算图会…

计算机的错误计算(十四)

摘要 解读 GPU和CPU计算上的精度差异&#xff1a;GPU 的 3个输出的相对误差分别高达 62.5%、50%、62.5%。 例1. 计算下列两个矩阵的乘积&#xff1a; 显然&#xff0c;其结果为第一列&#xff1a; 这个结果是准确的。 例2. 已知上面 3 个矩阵是由下面代码产生或输出&…

奔驰汽车的通信如此固若金汤的原因

随着摄像系统、距离控制、航线保持等功能以及制动辅助系统、制动力分配系统、车身侧倾干预与缓解系统等功能的飞速发展,汽车的系统功能之间已经不再独立,而是呈现互相合作的关系,各功能之间的无缝集成更是各大整车厂追求的目标。俗话说,外练筋骨皮,内练一口气,有了各式安…

HexPlane代码复现(十几分钟就复现成功的一篇论文代码!!!!!)

https://caoang327.github.io/HexPlane/ 一、 python setup.py develop命令用不了了 running develop /home/uriky/anaconda3/envs/hexplane/lib/python3.8/site-packages/setuptools/command/easy_install.py:144: EasyInstallDeprecationWarning: easy_install command is d…

【vueUse库Network模块各函数简介及使用方法】

vueUse库是一个专门为Vue打造的工具库,提供了丰富的功能,包括监听页面元素的各种行为以及调用浏览器提供的各种能力等。其中的Browser模块包含了一些实用的函数,以下是这些函数的简介和使用方法: vueUse库Sensors模块各函数简介及使用方法 vueUseNetwork函数1. useEventSo…

ISO 50001能源管理体系:激活绿色动能和共塑可持续发展

在当今全球化加速和工业化水平不断提高的背景下&#xff0c;能源消费呈现出前所未有的增长趋势。然而&#xff0c;能源资源的有限性、能源价格的波动以及能源消费对环境造成的影响&#xff0c;尤其是温室气体排放导致的全球气候变化问题&#xff0c;已经成为全球关注的焦点。为…

怎么在必应bing上投放搜索广告?

搜索引擎已成为企业获取潜在客户、提升品牌曝光度的关键平台&#xff0c;微软必应&#xff08;Bing&#xff09;以其庞大的用户基数、精准的定位能力以及与微软生态系统的深度整合&#xff0c;为企业提供了极具价值的广告投放渠道。云衔科技助力企业实现必应bing广告的精准投放…

透视HTTP协议 下载

透视HTTP协议 下载 01-时势与英雄:HTTP的前世今生.mp3 02-HTTP是什么?HTTP又不是什么? .mp3 03-HTTP世界全览(上):与HTTP相关的各种概念.mp3 04-HTTP世界全览(下):与HTTP相关的各种协议.mp3 05-常说的"四层"和"七层"到底是什么?“五层""六…

Spark SQL----Hive表

Spark SQL----Hive表 一、指定Hive表的存储格式二、与不同版本的Hive Metastore交互 Spark SQL还支持读取和写入存储在Apache Hive中的数据。然而&#xff0c;由于Hive有大量的依赖项&#xff0c;这些依赖项不包括在默认的Spark发布版中。如果在类路径上可以找到Hive依赖项&…

私接路由器导致部分终端(电脑、手机等)无法上网问题分析

【1】私接路由器场景 某公司办公网可以上互联网&#xff0c;网络终端通过公司路由器上的DHCP服务器自动获取IP地址&#xff0c;对终端设备接入没有做Mac地址绑定等策略限制&#xff0c;交换机也没有划分vlan。员工张三所在办公室网口太少或者WiFi信号差&#xff0c;私自找了一台…

前端实现 海浪(波浪)进度条效果(支持自定义长度;调节速度,2s缓冲结束)

实现海浪进度条 文章目录 实现海浪进度条效果图如下(投入使用的版本)背景和过程一、调试和探索过程(下面都会给出来对应代码)二、类似Element-plus的进度条样式1. CSS的样式如下2. HTML结构如下 二、电涌效果的进度条如下1. CSS的样式如下2. HTML的结构如下:3. JavaScript代码如…

推荐两款电脑文件处理工具,强大到你不舍得卸载

EasyFileCount EasyFileCount是一款基于Java开发的多功能文件管理工具&#xff0c;旨在帮助用户更轻松地管理和优化他们的文件存储。以下是EasyFileCount的主要功能和特点&#xff1a; 查看文件夹大小&#xff1a;用户可以快速统计和查看文件夹的总大小&#xff0c;实时显示各…

40.设计HOOK引擎的好处

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 上一个内容&#xff1a;39.右键弹出菜单管理游戏列表 以 39.右键弹出菜单管理游戏列表 它的代码为基础进行修改 效果图&#xff1a; 实现步骤&#xff1a; 首…

【海思Hi3403V100】多目拼接相机套板硬件规划方案

海思Hi3403V100 是专业超高清智能网络摄像头 SoC。该芯片最高支持四路 sensor 输入&#xff0c;支持最高 4K60fps 的 ISP 图像处理能力&#xff0c;支持 3F 、WDR、多级降噪、六轴防抖、硬件拼接、多光谱融合等多种传统图像增强和处理算法&#xff0c;支持通过AI 算法对输入图像…