spring boot 做网站/免费推广有哪些
统一的标准数据格式好处
SpringBoot返回统一的标准数据格式主要有以下几点好处:
-
增强接口的可读性和可维护性,使得前端开发人员能够更加清晰地理解接口返回的数据结构,从而提高开发效率。
-
降低前后端耦合度,当后端需要修改返回数据结构时,只需要调整统一的数据格式,而不用修改大量的前端代码。
-
有利于统一异常处理,对于出错时的返回数据格式也是一致的,便于前端统一处理错误信息。
-
当接口版本的升级和兼容时,可以通过统一的数据格式进行向下兼容或者向上兼容,减少接口变更带来的影响
格式不同的痛楚
一般情况下,SpringBoot
服务的返回格式有如下几种:
第一种:返回String
@GetMapping("/hello")
public String getStr() {return "hello";
}
此时调用接口获取到的返回值是这样:
hello
第二种:返回自定义对象
@GetMapping("/aniaml")
public Aniaml getAniaml(){Aniaml aniaml = new Aniaml(1,"pig");return aniaml;
}
此时调用接口获取到的返回值是这样:
{"id": 1,"name": "pig"
}
第三种:接口异常
@GetMapping("/error")
public int error(){int i = 10/0;return i;
}
此时调用接口获取到的返回值是这样:
{"timestamp": "2021-07-08T08:05:15.423+00:00","status": 500,"error": "Internal Server Error","path": "/error"
}
看了上边的几种情况,不难发现,一个接口在不同情况下,返回的数据格式竟然截然不同?那作为API的使用方估计就要骂娘了。此时,返回统一的标准数据格式就显得很有必要。
标准格式
一个标准的返回格式应包含以下三部分:
-
Status(状态):由后端统一定义各种返回结果的状态码。
-
Message(描述):描述本次接口调用的结果信息。
-
Data(数据):包含本次返回的具体数据内容。
{"status":"100","message":"操作成功","data":"hello"
}
当然了这并不是绝对的,在有了主要的字段后,可以按需加入其他扩展值,比如我们就在返回对象中添加了接口调用时间timestamp
等。
定义返回对象
@Data
public class ResultData<T> {private int status;private String message;private T data;private long timestamp ;public ResultData (){this.timestamp = System.currentTimeMillis();}public static <T> ResultData<T> success(T data) {ResultData<T> resultData = new ResultData<>();resultData.setStatus(ReturnCode.RC100.getCode());resultData.setMessage(ReturnCode.RC100.getMessage());resultData.setData(data);return resultData;}public static <T> ResultData<T> fail(int code, String message) {ResultData<T> resultData = new ResultData<>();resultData.setStatus(code);resultData.setMessage(message);return resultData;}}
定义状态码
public enum ReturnCode {/**操作成功**/RC100(100,"操作成功"),/**操作失败**/RC999(999,"操作失败"),/**服务限流**/RC200(200,"服务开启限流保护,请稍后再试!"),/**服务降级**/RC201(201,"服务开启降级保护,请稍后再试!"),/**热点参数限流**/RC202(202,"热点参数限流,请稍后再试!"),/**系统规则不满足**/RC203(203,"系统规则不满足要求,请稍后再试!"),/**授权规则不通过**/RC204(204,"授权规则不通过,请稍后再试!"),/**access_denied**/RC403(403,"无访问权限,请联系管理员授予权限"),/**access_denied**/RC401(401,"匿名用户访问无权限资源时的异常"),/**服务异常**/RC500(500,"系统异常,请稍后重试"),CLIENT_AUTHENTICATION_FAILED(1001,"客户端认证失败"),USERNAME_OR_PASSWORD_ERROR(1002,"用户名或密码错误"),UNSUPPORTED_GRANT_TYPE(1003, "不支持的认证模式");/**自定义状态码**/private final int code;/**自定义描述**/private final String message;ReturnCode(int code, String message){this.code = code;this.message = message;}public int getCode() {return code;}public String getMessage() {return message;}
}
统一返回格式
经过上边我们定义的数据格式,再次调用API,在Controller
层通过ResultData.success()
对返回结果进行包装后返回给前端。
@GetMapping("/hello")
public String getStr() {return ResultData.success("hello");
}
此时调用接口获取到的返回值已经是标准的格式,符合我们预期的效果。
{"status": 100,"message": "hello","data": null,"timestamp": 1625736481648
}
最大的弊端就是我们后面每写一个接口都需要调用ResultData.success()
这行代码对结果进行包装,重复劳动,浪费体力;而且还很容易被其他老鸟给嘲笑。所以呢我们需要对代码进行优化,目标就是不要每个接口都手工制定ResultData
返回值。
高级实现方式
要优化这段代码很简单,我们只需要借助SpringBoot提供的ResponseBodyAdvice
即可。
“
ResponseBodyAdvice的作用:拦截Controller方法的返回值,统一处理返回值/响应体,一般用来统一返回格式,加解密,签名等等。
”
先来看下ResponseBodyAdvice
的源码:
public interface ResponseBodyAdvice<T> {/*** 是否支持advice功能* true 支持,false 不支持*/boolean supports(MethodParameter var1, Class<? extends HttpMessageConverter<?>> var2);/*** 对返回的数据进行处理*/@NullableT beforeBodyWrite(@Nullable T var1, MethodParameter var2, MediaType var3, Class<? extends HttpMessageConverter<?>> var4, ServerHttpRequest var5, ServerHttpResponse var6);
}
我们只需要编写一个具体实现类即可
/*** @author jam* @date 2021/7/8 10:10 上午*/
@RestControllerAdvice
public class ResponseAdvice implements ResponseBodyAdvice<Object> {@Autowiredprivate ObjectMapper objectMapper;@Overridepublic boolean supports(MethodParameter methodParameter, Class<? extends HttpMessageConverter<?>> aClass) {return true;}@SneakyThrows@Overridepublic Object beforeBodyWrite(Object o, MethodParameter methodParameter, MediaType mediaType, Class<? extends HttpMessageConverter<?>> aClass, ServerHttpRequest serverHttpRequest, ServerHttpResponse serverHttpResponse) {if(o instanceof String){return objectMapper.writeValueAsString(ResultData.success(o));} return ResultData.success(o);}
}
需要注意两个地方:@RestControllerAdvice
注解
@RestControllerAdvice
是@RestController
注解的增强,可以实现三个方面的功能:
-
全局异常处理
-
全局数据绑定
-
全局数据预处理
- String类型判断
if(o instanceof String){return objectMapper.writeValueAsString(ResultData.success(o));
}
这段代码一定要加,如果Controller直接返回String的话,SpringBoot是直接返回,故我们需要手动转换成json。
经过上面的处理我们就再也不需要通过ResultData.success()
来进行转换了,直接返回原始数据格式,SpringBoot自动帮我们实现包装类的封装。
@GetMapping("/hello")
public String getStr(){return "hello";
}
此时我们调用接口返回的数据结果为:
@GetMapping("/hello")
public String getStr(){return "hello";
}
是不是感觉很完美,别急,还有个问题在等着你呢。
接口异常问题
此时有个问题,由于我们没对Controller的异常进行处理,当我们调用的方法一旦出现异常,就会出现问题,比如下面这个接口:
@GetMapping("/wrong")
public int error(){int i = 9/0;return i;
}
相关文章:

Spring Boot接口返回统一格式
统一的标准数据格式好处 SpringBoot返回统一的标准数据格式主要有以下几点好处: 增强接口的可读性和可维护性,使得前端开发人员能够更加清晰地理解接口返回的数据结构,从而提高开发效率。 降低前后端耦合度,当后端需要修改返回数…...

Flink如何基于数据版本使用最新离线数据
业务场景 假设批量有一张商户表,表字段中有商户名称和商户分类两个字段。 批量需要将最新的商户名称和分类的映射关系推到hbase供实时使用。 原实现方案 a.原方案内容 为解决批量晚批问题,批量推送hbase表时一份数据产生两类rowkey:T-1和…...

软件开发中的常用性能指标
大家好!我是今越。在软件开发中我们经常会遇到一些性能指标,下面就带大家一起来看看。 QPS Queries Per Second,每秒查询率,一台服务器每秒能够响应的查询次数。它是对一个特定的查询服务器在规定时间内所处理流量多少的衡量标准…...

cmakelist使用总结
支持能编译成在不同系统上运行程序的方法 我们代码就一份,但有时需要编译成arm32,有时需要编译成x86_64,或更多 1、首先先将代码定义一个名称: #将所有的源文件列为一个集合,集合名字叫做SRC_LISTS set(SRC_LISTS main.cpp A.cpp…...

准备阶段 Unity优化总纲
Unity优化总纲 我们在学习优化课程之前要预先做好准备功能 例如最主要是的接收到一个优化的任务,应该怎么做,其次怎么做,最后怎么做。 也要学习一些专业工具以及专业术语 了解游戏运行机制,在排查期间思路会更清晰 1.优化目的…...

ubuntu防火墙(三)——firewalld使用与讲解
本文是Linux下,用ufw实现端口关闭、流量控制(二) firewalld使用方式 firewalld 是一个动态管理防火墙的工具,主要用于 Linux 系统(包括 Ubuntu 和 CentOS 等)。它提供了一个基于区域(zones)和服务&#x…...

zookeeper 搭建集群
基础的java 环境先安好,选择3台虚拟机 ip 不一样 机器应为奇数个 zookeeper 奇数个节点实际上是(2*n-1) 比偶数台机器少一台解决成本,并且能够满足 zookeeper 集群过半选举leader 的规则 # 3台虚拟机 将zookeeper 解压到服务器上 #在 conf/ 目录下 找到zoo_s…...

Java——异常机制(下)
1 异常处理之(捕获异常) (一般处理运行时异常) (try-catch-finally子句) (finally一般用于文件最后关闭) (catch捕获的子类在前父类在后——>不然父类在前面都让父类捕获掉了,会报错) (Exception是父类放在最后,如果前面没有捕获到,就…...

centos 手动安装libcurl4-openssl-dev库
下载源代码 curl downloadshttps://curl.se/download/ 选择需要下载的版本,我下载的是8.11.0 解压 tar -zxvf curl-8.11.0 查看安装命令 查找INSTALL.md,一般在docs文件夹下 –prefix :指定安装路径(默认安装在/usr/local&…...

JS学习(1)(基本概念与作用、与HTML、CSS区别)
目录 一、JavaScript是什么? (1)基本介绍 (2)简称:JS? 二、JavaScript的作用。 三、HTML、CSS、JS之间的关系。 (1)html、css。 (2)JavaScript。 …...

代码随想录算法训练营day50|动态规划12
不同的子序列 给定一个字符串 s 和一个字符串 t ,计算在 s 的子序列中 t 出现的个数。、 编辑距离中的删除元素,其实就是直接变数字,其只删除原来的较长的数组里的元素 递推模拟,使用s的最后一个元素匹配,或者删除…...

JavaWeb学习(2)(Cookie原理(超详细)、HTTP无状态)
目录 一、HTTP无状态。 (1)"记住我"? (2)HTTP无状态。 (3)信息存储客户端中。如何处理? 1、loaclStorage与sessionStorage。 2、Cookie。 二、Cookie。 (1&…...

java抽象类
目录 一.抽象类 1.什么是抽象类 2.抽象类特点 (1)抽象类不能直接实例化对象 (2)可以包含抽象方法和具体方法 (3)可以有构造方法 (4)抽象类必须被继承,并且继承后子类要重写父类中的抽象方法,否则子类也是抽象类,必须要使用 abstract 修…...

minio集群部署–linux环境
原文地址:minio集群部署–linux环境 – 无敌牛 欢迎参观我的个人博客:无敌牛 – 技术/著作/典籍/分享等 第一步:安装 有rpm、deb、和二进制文件安装方式。参考文档在:MinIO Object Storage for Linux — MinIO Object Storage …...

在vue3里使用scss实现简单的换肤功能
实现的换肤功能:主题色切换、亮色模式和暗黑模式切换、背景图切换 主题色就是网站主色,可以配置到组件库上面;亮色模式又分为两种风格:纯白风格和背景图风格,不需要背景图的话可以删掉这部分逻辑和相关定义;…...

JavaScript编写css自定义属性
一、自定义属性 是在 CSS 中定义的变量,以 --开头。它们可以存储颜色、尺寸、字体等任何 CSS 值,并且可以在整个文档中重复使用。 :root {--primary-color: #3498db;--font-size: 16px; }body {color: var(--primary-color);font-size: var(--font-siz…...

我们来学webservie - WSDL
WSDL 题记WSDL系列文章 题记 举个例子 酒桌上大领导们谈笑风生,把酒临风,其喜洋洋者矣老张说能签下xx项目,一来证明了集团在行业中的翘楚地位,二来感谢各位领导给予的大力支持接下来的一周,项目经理、业务顾问相继入场࿰…...

【Agent】构建智能诗歌创作系统:基于多 Agent 的协同创作实现
在探索大语言模型的创意应用过程中,我们开发了一个基于多 Agent 的智能诗歌创作系统。本文将介绍如何通过多个专业化的 Agent 协同工作,实现根据地点和天气信息自动创作诗歌的功能。 GitHub Code 项目地址 核心架构设计 1. Agent 基类设计 from pydan…...

001 LVGL PC端模拟搭建
01 LVGL模拟器介绍 使用PC端软件模拟LVGL运行,而不需要任何嵌入式硬件 环境搭建:codeblocks-20.03mingw-setup 正常安装流程即可 工程获取:LVGL官网-> github仓库 本地安装包下载资源包 工程模版和软件安装包 补充:…...

AJAX三、XHR,基本使用,查询参数,数据提交,promise的三种状态,封装-简易axios-获取省份列表 / 获取地区列表 / 注册用户,天气预报
一、XMLHttpRequest基本使用 XMLHttpRequest(XHR)对象用于与服务器交互。 二、XMLHttpRequest-查询参数 语法: 用 & 符号分隔的键/值对列表 三、XMLHttpRequest-数据提交 核心步骤 : 1. 请求头 设置 Content-Type 2. 请求体 携带 符合要求 的数…...

mybatis之数据统计与自定义异常处理
文章目录 需求描述定义实体方式一、mybatisPlus实现方式二、自定义SQL实现简单查询过滤查询 异常处理1、SQL拼写异常 在使用Mybatis或MybatisPlus进行数据统计,在【 SpringBoot的Mybatis-plus实战之基础知识】中对mybatisplus引入有介绍,本次要使用其进…...

qt creator使用taglib读取音频元信息,windows平台vcpkg安装
注意:qt creator用的构建组件是qt 6.2.3 MSVC2019 64bit 安装vcpkg // 我的安装位置C:\vcpkg git clone https://github.com/microsoft/vcpkg.git C:\vcpkg cd C:\vcpkg .\bootstrap-vcpkg.bat// 设置系统环境变量 VCPKG_ROOT C:/vcpkg用vcpkg安装taglib vcpkg …...

设计模式之生成器模式
目录 1.简介 2.结构 3.使用场景 4.实例 5.优缺点 6.与其他模式的关系 7.总结 1.简介 生成器模式(Builder Pattern)是一种创建型设计模式,它允许你通过一步一步构建复杂对象,而不是通过一个包含大量参数的构造函数或方法。该…...

python学opencv|读取图像(三)放大和缩小图像
【1】引言 前序已经学习了常规的图像读取操作和图像保存技巧,相关文章链接为: python学opencv|读取图像-CSDN博客 python学opencv|读取图像(二)保存彩色图像-CSDN博客 今天我们更近一步,学习放大和缩小图像的技巧&…...

1 数据库(上):MySQL的概述和安装、SQL简介、IDEA连接数据库使用图形化界面
文章目录 前言一、数据库相关的概念二、MySQL概述1 MySQL的安装和配置2 MySQL登录、退出(1)mysql -uroot -p1234 或者mysql -uroot -p ---- 登录(2)exit或者quit ---- 退出 3 远程登录服务器上的MySQL命令mysql -hip地址 -P3306 -…...

C++初阶—类与对象(中篇)
第一章:类的6个默认成员函数 如果一个类中什么成员都没有,简称为空类。 空类中真的什么都没有吗?并不是,任何类在什么都不写时,编译器会自动生成以下6个默认成员函数。 默认成员函数:用户没有显式实现&a…...

Leetcode15. 三数之和(HOT100)
链接 一般这种三数之和,四数之和都使用双指针,复杂度最优,次一级可使用哈希表。前者要求有序,后者空间上有花费。 题目: 题目要求答案中不能出现重复vector,比如{-1 1 0}和{-1 0 1}; 这两个…...

Oracle数据库小白备忘
sqlplus相关 导入sql文件 在sqlplus中,导入一个sql文件,是使用或者start。 如当前目录下有一个hello.sql,则可以使用 hello.sql 或者 start hello.sql 来进行导入,功能类似于mysql里面的source。 退出编辑模式 当使用sqlplus…...

DDR4与DDR3服务器内存的关键区别有哪些?
内存作为服务器性能的关键组件之一,已经经历了从DDR3到DDR4的过渡。DDR4内存相较于DDR3在多个方面有所提升,包括速度、带宽、功耗以及数据传输效率等。然而,尽管DDR4内存在性能上占有优势,DDR3内存依然在一些特定场景中得到了广泛…...

Linux: shell: bash: set -x;调试使用
man bash set -x -x After expanding each simple command, for command, case command, select command, or arithmetic for command, display the expanded value of PS4, followed by the command and its expanded arguments or associated word list. 这个可以帮助将变量…...