拒绝写重复代码,试试这套开源的 SpringBoot 组件,效率翻倍~

作者:皮皮林551日期:2026/3/7

目录

  • 1 简介
  • 2 快速入门
    • 2.1 Spring Boot 接口开发现状
    • 2.2 快速入门

1 简介

Graceful Response 是一个 Spring Boot 技术栈下的优雅响应处理器,提供一站式统一返回值封装、全局异常处理、自定义异常错误码 等功能,使用 Graceful Response 进行 web 接口开发不仅可以节省大量的时间,还可以提高代码质量,使代码逻辑更清晰。

强烈推荐你花 3 分钟学会它!

本项目案例工程代码:https://github.com/feiniaojin/graceful-response-example.git ,注意选择最新版本的分支。

Spring Boot 版本Graceful Response 版本graceful-response-example 分支
2.x3.2.1-boot23.2.0-boot2
3.x3.2.1-boot33.2.0-boot3

注意,3.2.1-boot2 版本的 Graceful Response 源码由单独的仓库进行维护,地址为:https://github.com/feiniaojin/graceful-response-boot2

3.2.1-boot2 和 3.2.1-boot3 除了支持的 Spring Boot 版本不一样,其他实现完全一致,Maven 引用时只需要根据对应的 Spring Boot 版本选择 Graceful Response 的 version 即可,两者的 groupId、artifactId 是一致的。

2 快速入门

2.1 Spring Boot 接口开发现状

目前,业界使用 Spring Boot 进行接口开发时,往往存在效率底下、重复劳动、可读性差等问题。以下伪代码相信大家非常熟悉,我们大部分项目的 Controller 接口都是这样的。

1@Controller  
2public class Controller {  
3
4    @GetMapping("/query")  
5    @ResponseBody  
6    public Response query(Map<String, Object> paramMap) {  
7        Response res = new Response();  
8        try {  
9            //1.校验params参数合法性,包括非空校验、长度校验等  
10            if (illegal(paramMap)) {  
11                res.setCode(1);  
12                res.setMsg("error");  
13                return res;  
14            }  
15            //2.调用Service的一系列操作,得到查询结果  
16            Object data = service.query(params);  
17            //3.将操作结果设置到res对象中  
18            res.setData(data);  
19            res.setCode(0);  
20            res.setMsg("ok");  
21            return res;  
22        } catch (Exception e) {  
23            //4.异常处理:一堆丑陋的try...catch,如果有错误码的,还需要手工填充错误码  
24            res.setCode(1);  
25            res.setMsg("error");  
26            return res;  
27        }  
28    }  
29}
30

这段伪代码存在什么样的问题呢?

第一个问题,效率低下。 Controller 层的代码应该尽量简洁,上面的伪代码其实只是为了将数据查询的结果进行封装,使其以统一的格式进行返回。例如以下格式的响应体:

1{  
2  "code": 0,  
3  "msg": "ok",  
4  "data": {  
5    "id": 1,  
6    "name": "username"  
7  }  
8}
9

查询过程中如果发生异常,需要在 Controller 进行手工捕获,根据捕获的异常人工地设置错误码,当然,也用同样的格式封装错误码进行返回。

可以看到,除了调用 service 层的 query 方法这一行,其他大部分的代码都执行进行结果的封装,大量的冗余、低价值的代码导致我们的开发活动效率很低。

第二个问题,重复劳动。 以上捕获异常、封装执行结果的操作,每个接口都会进行一次,因此造成大量重复劳动。

第三个问题,可读性低。 上面的核心代码被淹没在许多冗余代码中,很难阅读,如同大海捞针。

我们可以通过 Graceful Response 这个组件解决这样的问题。

2.2 快速入门

2.2.1 引入 Graceful Response 组件

Graceful Response 已发布至 maven 中央仓库,我们可以直接引入到项目中。

maven 依赖如下:

1<dependency>  
2    <groupId>com.feiniaojin</groupId>  
3    <artifactId>graceful-response</artifactId>  
4    <version>{latest.version}</version>  
5</dependency>
6
Spring Boot 版本Graceful Response 最新版本
2.x3.2.1-boot2
3.x3.2.1-boot3

2.2.2 启用 Graceful Response

在启动类中引入 @EnableGracefulResponse 注解,即可启用 Graceful Response 组件。

1@EnableGracefulResponse  
2@SpringBootApplication  
3public class ExampleApplication {  
4    public static void main(String[] args) {  
5        SpringApplication.run(ExampleApplication.class, args);  
6    }  
7}
8

2.2.3 Controller 层

引入 Graceful Response 后,我们不需要再手工进行查询结果的封装,直接返回实际结果即可,Graceful Response 会自动完成封装的操作。

Controller 层示例如下。

1@Controller  
2public class Controller {  
3    @RequestMapping("/get")  
4    @ResponseBody  
5    public UserInfoView get(Long id) {  
6        log.info("id={}", id);  
7        return UserInfoView.builder().id(id).name("name" + id).build();  
8    }  
9}
10

在示例代码中,Controller 层的方法直接返回了 UserInfoView 对象,没有进行封装的操作,但经过 Graceful Response 处理后,我们还是得到了以下的响应结果。

1{  
2  "status": {  
3    "code": "0",  
4    "msg": "ok"  
5  },  
6  "payload": {  
7    "id": 1,  
8    "name": "name1"  
9  }  
10}
11

而对于命令操作(Command)尽量不返回数据,因此 command 操作的方法的返回值应该是 void,Graceful Response 对于对于返回值类型 void 的方法,也会自动进行封装。

1public class Controller {  
2    @RequestMapping("/command")  
3    @ResponseBody  
4    public void command() {  
5        //业务操作  
6    }  
7}
8

成功调用该接口,将得到:

1{  
2  "status": {  
3    "code": "200",  
4    "msg": "success"  
5  },  
6  "payload": {}  
7}
8

2.2.4 Service 层

在引入 Graceful Response 前,有的开发者在定义 Service 层的方法时,为了在接口中返回异常码,干脆直接将 Service 层方法定义为 Response,淹没了方法的正常返回值。

Response 的代码如下。

1//lombok注解  
2@Data  
3public class Response {  
4    private String code;  
5    private String msg;  
6    private Object data;  
7}
8

直接返回 Response 的 Service 层方法:

1/**  
2 * 直接返回Reponse的Service  
3 * 不规范  
4 */  
5public interface Service {  
6    public Reponse commandMethod(Command command);  
7}
8

Graceful Response 引入 @ExceptionMapper 注解,通过该注解将异常和错误码关联起来,这样 Service 方法就不需要再维护 Response 的响应码了,直接抛出业务异常,由 Graceful Response 进行异常和响应码的关联。

@ExceptionMapper 的用法如下。

1/**  
2 * NotFoundException的定义,使用@ExceptionMapper注解修饰  
3 * code:代表接口的异常码  
4 * msg:代表接口的异常提示  
5 */  
6@ExceptionMapper(code = "1404", msg = "找不到对象")  
7public class NotFoundException extends RuntimeException {  
8  
9}
10

Service 接口定义:

1public interface QueryService {  
2    UserInfoView queryOne(Query query);  
3}
4

Service 接口实现:

1public class QueryServiceImpl implements QueryService {  
2    @Resource  
3    private UserInfoMapper mapper;  
4  
5    public UserInfoView queryOne(Query query) {  
6        UserInfo userInfo = mapper.findOne(query.getId());  
7        if (Objects.isNull(userInfo)) {  
8            //这里直接抛自定义异常  
9            throw new NotFoundException();  
10        }  
11        //……后续业务操作  
12    }  
13}
14

当 Service 层的 queryOne 方法抛出 NotFoundException 时,Graceful Response 会进行异常捕获,并将 NotFoundException 对应的异常码和异常信息封装到统一的响应对象中,最终接口返回以下 JSON。

1{  
2  "status": {  
3    "code": "1404",  
4    "msg": "找不到对象"  
5  },  
6  "payload": {}  
7}
8

2.2.5 参数校验

Graceful Response 对 JSR-303 数据校验规范和 Hibernate Validator 进行了增强,Graceful Response 自身不提供参数校验的功能,但是用户使用了 Hibernate Validator 后,Graceful Response 可以通过 @ValidationStatusCode 注解为参数校验结果提供响应码,并将其统一封装返回。

例如以下的 UserInfoQuery。

1@Data  
2public class UserInfoQuery {  
3    @NotNull(message = "userName is null !")  
4    @Length(min = 6, max = 12)  
5    @ValidationStatusCode(code = "520")  
6    private String userName;  
7}
8

UserInfoQuery 对象中定义了 @NotNull 和 @Length 两个校验规则,在未引入 Graceful Response 的情况下,会直接抛出异常;

在引入 Graceful Response 但是没有加入 @ValidationStatusCode 注解的情况下,会以默认的错误码进行返回;

在上面的 UserInfoQuery 中由于使用了 @ValidationStatusCode 注解,并指定异常码为 520,则当 userName 字段任意校验不通过时,都会使用异常码 520 进行返回,如下。

1{  
2  "status": {  
3    "code": "520",  
4    "msg": "userName is null !"  
5  },  
6  "payload": {}  
7}
8

而对于 Controller 层直接校验方法入参的场景,Graceful Response 也进行了增强,如以下 Controller。

1public class Controller {  
2  
3    @RequestMapping("/validateMethodParam")  
4    @ResponseBody  
5    @ValidationStatusCode(code = "1314")  
6    public void validateMethodParam(  
7            @NotNull(message = "userId不能为空") Long userId,  
8            @NotNull(message = "userName不能为空") Long userName) {  
9        //省略业务逻辑  
10    }  
11}
12

如果该方法入参校验触发了 userId 和 userName 的校验异常,将以错误码 1314 进行返回,如下。

1{  
2  "status": {  
3    "code": "1314",  
4    "msg": "userId不能为空"  
5  },  
6  "payload": {}  
7}
8

2.2.6 自定义 Response 格式

Graceful Response 内置了两种风格的响应格式,并通过 graceful-response.response-style 进行配置。

graceful-response.response-style=0,或者不配置(默认情况),将以以下的格式进行返回:

1{  
2  "status": {  
3    "code": 1007,  
4    "msg": "有内鬼,终止交易"  
5  },  
6  "payload": {  
7  }  
8}
9

graceful-response.response-style=1,将以以下的格式进行返回:

1{  
2  "code": "1404",  
3  "msg": "not found",  
4  "data": {  
5  }  
6}
7

如果这两种格式均不满足业务需要,Graceful Response 也支持用户自定义响应体,关于自定义响应体的技术实现,请到自定义 Response 格式进行了解。

本项目提供的进阶功能,包括

  • 第三方组件汽车(Swagger、执行器等)
  • 自定义响应
  • 异常请求放行
  • 异常别名
  • 常用配置项

目前该组件在 GitHub 上已经有两百多 Star,很多朋友已经开始用了,大家可以通过下方链接了解下:


拒绝写重复代码,试试这套开源的 SpringBoot 组件,效率翻倍~》 是转载文章,点击查看原文


相关推荐


程序员的明天:AI 时代下的行业观察与个人思考
勇哥Java实战2026/2/27

这篇文章分享了我对 AI 时代下,软件行业发展以及程序员命运走向的 5 点思考,供大家参考。 1 匠人时代落幕 Redis 之父 antirez,最近写了一篇文章 《 Don't fall into the anti-AI hype 》,读完之后,我深有感触。 文章的观点非常明确: AI 不仅改变了编码方式,更重塑了软件行业的价值结构和职业路径,程序员需要从“手动编码”转向“设计系统与与 AI 协作” 。 过去的软件行业,其实有一种很典型的“匠人红利”。谁代码写得更优雅,谁框架更熟,谁对某个


QT & QML 总结备查
瞰百2026/2/19

QT & QML 总结备查 首要注意,在桌面端开发QT可免费商用,而嵌入式端QT商用则收费。 各种 UI 库的总结和对比: Cpp-Learning/C-C++实用库备查.md at main · Staok/Cpp-Learning。 文章所在 Github 仓库 Staok/QT-QML-Learning: QT & QML 总结备查文章 会保持最新,其它地方的不会跟进。 常看常新 QT 安装:网搜 Qt Creator 下载和安装即可。 编译器:对于 Win 上


英语语法笔记:英语不应该成为开发工程师的发展瓶颈
修己xj2026/2/11

前几天,是公司成立二十周年的年会。老板作了一场题为《穿越寒冬,求实存善》的演讲。那一刻我在想:当寒意渐浓,作为领航者,他思考的是如何带领公司扛过这场冬天;那作为程序员的我们,又该如何穿越自己的寒冬呢? Vue 作者尤雨溪曾坦言:“不仅英语差会成为瓶颈,英语好还能成为优势,因为学习效率会比别人高。像我这样半路出家自学的人,只能靠英语了……”确实,无论是阅读技术文档、参与开源社区、在 Stack Overflow 寻找答案,还是追踪最新技术资讯、争取一份远程机会,英语早已不是可选项,而是必修课——是


AI - 通过 Docker 来安装与访问 OpenClaw
LinXunFeng2026/2/2

欢迎关注微信公众号:FSA全栈行动 👋 一、简介 这是我在 Mac 上通过 Docker 来安装和配置 OpenClaw 的一份记录,随着文章从上到下一步步做就可以了。 二、docker 拉取 Ubuntu 镜像 docker pull ubuntu:latest 创建容器 创建容器,并映射 18789 端口 docker run -it -p 18789:18789 --name openclaw ubuntu 搭配 Docker 容器的分离快捷键,先按 Ctrl+P,再按 Ctrl+


🚀 纯前端离线局域网P2P大文件断点传输:别让你的照片墙崩了
子兮曰2026/1/23

前言:小明和他的照片墙危机 想象一下,你是小明,一个热爱摄影的程序员。周末去爬山拍了一堆4K高清照片,总共3GB,准备发给老婆分享。微信传?算了,压缩后画质渣得像像素风。网盘?离线状态下连不上。蓝牙?慢得像蜗牛在跑步。你急得团团转,突然灵机一动:用电脑直接传啊!可是怎么在浏览器里实现局域网P2P大文件传输,还得支持断点续传?别急,今天咱们就聊聊这个技术方案。 技术背景:P2P不是什么新鲜玩意儿 P2P(点对点)传输在局域网里其实挺常见的,BT下载就是经典案例。但咱们今天聊的是纯前端实现,意思是完


【云计算】利用 LVS 构建集群实现负载均衡 | 集群的概念 | 单服务器性能瓶颈验证例子 | LVS 基础 | LVS 构建负载均衡集群实操步骤
王平渊2026/1/15

利用 LVS 构建集群实现负载均衡 LVS 是构建高性能、高可靠负载均衡集群的利器,其内核态转发机制和丰富的调度算法,使其成为大规模集群场景的首选方案。在实际应用中,需根据业务场景选择合适的工作模式(DR 模式为最优选择),并结合 Keepalived 实现高可用,最终解决单服务器的性能瓶颈问题。 Ⅰ. 集群(Cluster)基础 0x00 集群的概念 集群(Cluster),是一组相互独立且相互依赖、通过高速网络互联的计算机组成的计算机组,以单一模式加以管理,为用户提供统一服务。 从用户视角


Excel/WPS 表格数据合并操作指南
GalenZhang8882026/1/6

Excel/WPS 表格数据合并操作指南 场景一:同一个文件,不同工作表(Sheet) 适用情况:数据都在同一个 Excel 文件里,比如在 Sheet1 和 Sheet2,都有共同的 A列 作为关联。 1. 推荐公式:XLOOKUP 公式示例: =XLOOKUP(A2, Sheet2!A:A, Sheet2!D:D) 2. 参数详细说明 A2(查找值): 当前表格(Sheet1)中你要拿去匹配的那个单元格(通常是 ID、姓名等)。Sheet2!A:A(查找数组): 去哪里找这个 ID?即 S


MySQL 版本演进全景图:从 5.6 到 8.4 的技术变革与行业实践
刘一说2025/12/29

文章目录 一、版本演进时间线概览二、核心功能迭代:从基础架构到现代数据库1. 数据类型与存储引擎革新2. 查询语言与计算能力3. 事务与一致性 三、架构与性能优化:从单机到云原生1. 复制与高可用2. 性能调优 四、安全与兼容性:从传统认证到现代密钥管理1. 认证机制演变2. 加密与审计 五、典型场景适配建议六、未来趋势与行业挑战结语 一、版本演进时间线概览 版本发布时间核心突破行业定位5.62013年在线 DDL、性能优化传统 OLTP 基础架构5.7201


前端原生能力速查笔记(HTML + 浏览器 API 实战篇)
遇见~未来2025/12/20

本笔记用于整理前端开发中不依赖框架即可实现的高频实用功能,涵盖文件下载、打印、HTML 原生属性以及浏览器内置 JS API。 适合作为:日常开发速查 / 基础能力沉淀 / 新人教学笔记 一、a 标签文件下载功能 1. 核心原理 利用 HTML5 的 download 属性, 让浏览器在点击链接时触发下载行为,而不是直接预览资源。 2. 基础用法 <!-- 直接下载(使用原文件名) --> <a href="files/demo.pdf" download>下载 PDF</a> <


自主高性价比、高精度车规级姿态感知、倾角感知模组-应用消费级无人机、自动驾驶、机器人、智能制造、基础设施、智能穿戴等
moonsims2025/12/12

自主高性价比、高精度车规级姿态感知、倾角感知模组-应用消费级无人机、自动驾驶、机器人、智能制造、基础设施、智能穿戴等 在小说阅读器中沉浸阅读 IMU 惯性测量单元(Inertial Measurement Unit) 是测量物体三轴角速度和加速度的设备。一个IMU内可能会装有三轴陀螺仪和三轴加速度计,来测量物体在三维空间中的角速度和加速度。严格意义上的IMU只为用户提供三轴角速度以及三轴加速度数据。 VRU 垂直参考单元(Vertical Reference Unit)是

首页编辑器站点地图

本站内容在 CC BY-SA 4.0 协议下发布

Copyright © 2026 XYZ博客