{"id":14983129,"url":"https://github.com/feiniaojin/graceful-response","last_synced_at":"2025-10-07T17:58:32.918Z","repository":{"id":51972038,"uuid":"427866402","full_name":"feiniaojin/graceful-response","owner":"feiniaojin","description":"Spring Boot接口响应处理解决方案，提供统一返回值封装、全局异常处理、自定义异常错误码、参数校验增强、断言增强等功能","archived":false,"fork":false,"pushed_at":"2025-03-28T05:05:57.000Z","size":1971,"stargazers_count":1192,"open_issues_count":7,"forks_count":167,"subscribers_count":22,"default_branch":"main","last_synced_at":"2025-08-19T22:19:01.391Z","etag":null,"topics":["api","globalexceptionhandler","java","restfull","spring-boot"],"latest_commit_sha":null,"homepage":"https://doc.feiniaojin.com","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/feiniaojin.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2021-11-14T07:36:43.000Z","updated_at":"2025-08-13T11:23:20.000Z","dependencies_parsed_at":"2022-08-24T08:10:37.719Z","dependency_job_id":"9dc5fda7-989c-4405-8a41-a41d990ac62a","html_url":"https://github.com/feiniaojin/graceful-response","commit_stats":{"total_commits":111,"total_committers":14,"mean_commits":7.928571428571429,"dds":0.6036036036036037,"last_synced_commit":"9b44b7135ce526dcfdb0e622422ba5ef484f1f5d"},"previous_names":["feiniaojin/naaf-graceful-response"],"tags_count":18,"template":false,"template_full_name":null,"purl":"pkg:github/feiniaojin/graceful-response","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/feiniaojin%2Fgraceful-response","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/feiniaojin%2Fgraceful-response/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/feiniaojin%2Fgraceful-response/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/feiniaojin%2Fgraceful-response/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/feiniaojin","download_url":"https://codeload.github.com/feiniaojin/graceful-response/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/feiniaojin%2Fgraceful-response/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":278820488,"owners_count":26051766,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-07T02:00:06.786Z","response_time":59,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api","globalexceptionhandler","java","restfull","spring-boot"],"created_at":"2024-09-24T14:06:46.713Z","updated_at":"2025-10-07T17:58:32.666Z","avatar_url":"https://github.com/feiniaojin.png","language":"Java","readme":"\u003cdiv align=center\u003e\u003cimg src=\"./assets/project-name.png\"\u003e\u003c/div\u003e\n\n![](https://img.shields.io/github/license/feiniaojin/graceful-response)\n[![GitHub stars](https://img.shields.io/github/stars/feiniaojin/graceful-response)](https://github.com/feiniaojin/graceful-response/stargazers)\n[![GitHub forks](https://img.shields.io/github/forks/feiniaojin/graceful-response)](https://github.com/feiniaojin/graceful-response/network)\n![](https://img.shields.io/github/issues/feiniaojin/graceful-response)\n![Maven Central](https://img.shields.io/maven-central/v/com.feiniaojin/graceful-response)\n\u003ca href=\"https://hellogithub.com/repository/1fc5b7426d9a4398b53719468a2ae16a\" target=\"_blank\"\u003e\u003cimg src=\"https://abroad.hellogithub.com/v1/widgets/recommend.svg?rid=1fc5b7426d9a4398b53719468a2ae16a\u0026claim_uid=CGoRi0Ug35dqj42\u0026theme=small\" alt=\"Featured｜HelloGitHub\" /\u003e\u003c/a\u003e\n\n# 作者新书推荐\n\n本项目作者的新书《悟道领域驱动设计》目前已上架各大电商平台，感兴趣的朋友可以帮忙支持一下。\n\n\u003cimg alt=\"悟道领域驱动设计\" src=\"assets/book.png\" style=\"width: 50%\"\u003e\n\n购买链接：https://item.jd.com/14835288.html\n\n# 1. 项目介绍\n\nGraceful Response 是 Spring\nBoot 技术体系下的响应处理解决方案，可以帮助开发者优雅地完成包括统一响应格式数据封装、全局异常处理、错误码填充、异常消息国际化等处理过程，提高开发效率，提高代码质量。欢迎\nstar!\n\n![代码现状](./assets/use-gr.png)\n\n项目及案例代码仓库如下:\n\n| Spring Boot 版本 | 项目                                                 | 案例                                                         |\n|----------------|----------------------------------------------------|------------------------------------------------------------|\n| 3.x            | \u003chttps://github.com/feiniaojin/graceful-response\u003e  | \u003chttps://github.com/feiniaojin/graceful-response-example\u003e  |\n| 2.x            | \u003chttps://github.com/feiniaojin/graceful-response2\u003e | \u003chttps://github.com/feiniaojin/graceful-response2-example\u003e |\n\n学习资源：\n\n- B 站教学视频 \u003chttps://www.bilibili.com/video/BV1Wm411C7vs/\u003e\n\n# 2. 核心功能\n\n- 统一返回值封装\n- void 返回类型封装\n- 全局异常处理\n- 自定义响应体：适应不同项目的响应格式需求\n- 参数校验错误码：为参数校验的异常指定错误码，支持全局的参数校验错误码\n- 断言增强：执行断言时填充错误码和异常信息到 Response\n- 异常别名：适配外部异常，通过注解或者配置文件的方式，为外部异常指定错误码\n- 例外请求放行：支持根据路径、返回值、注解、配置等多种方式进行放行，无须担心框架冲突\n- 第三方组件适配：目前已完成 Swagger、springdoc、actuator、FastJson 等框架或者组件的适配\n- RESTful 支持：可以指定异常的 HTTP 状态码，并且支持统一指定\n- 错误码枚举：支持定义错误码枚举，避免创建过多的异常类\n\n更多功能，请到[文档中心](https://doc.feiniaojin.com/graceful-response/home.html)进行了解。\n\n# 3. 感谢\n\n感谢以下公众号或者自媒体对本项目的推广。\n\n| 自媒体名称         | 类型  | 链接                                                  |\n|---------------|-----|-----------------------------------------------------|\n| 芋道源码          | 公众号 | \u003chttps://mp.weixin.qq.com/s/VG6n5IsIDez8iZkY8JK6QQ\u003e |\n| Java 面试那些事    | 公众号 | \u003chttps://mp.weixin.qq.com/s/V9MhNVj3uQRrmnrfy9KkAQ\u003e |\n| 编程奇点          | 公众号 | \u003chttps://mp.weixin.qq.com/s/cQWgivkpuXGEijRR1WRt0g\u003e |\n| macrozheng    | 公众号 | \u003chttps://mp.weixin.qq.com/s/XAHBzVRFuMJTEh8Y1Xvv4g\u003e |\n| Java 后端技术     | 公众号 | \u003chttps://mp.weixin.qq.com/s/4ssfZftGUqq0l9nW9lShLA\u003e |\n| Java 高性能架构    | 公众号 | \u003chttps://mp.weixin.qq.com/s/XImjkUExBHEklgrLnrINyw\u003e |\n| 技术老男孩         | 公众号 | \u003chttps://mp.weixin.qq.com/s/6gafudNaNTK1FRIdvNMXXw\u003e |\n| Java 知音       | 公众号 | \u003chttps://mp.weixin.qq.com/s/ZNmpTZnL2XqsPN2ayq0_4Q\u003e |\n| Java123       | 公众号 | \u003chttps://mp.weixin.qq.com/s/MF0PaawFILzNBMM78O_Pnw\u003e |\n| 程序员追风         | 公众号 | \u003chttps://mp.weixin.qq.com/s/wlY0phnXEiO7E_basxsWJw\u003e |\n| Spring源码项目进行时 | 掘金  | \u003chttps://juejin.cn/post/7367195057559371788\u003e        |\n| 京东云开发者        | 掘金  | \u003chttps://juejin.cn/post/7405158247592427560\u003e        |\n\n# 4. 快速入门\n\n## 4.1 引入 Graceful Response\n\n通过 Maven 依赖进行引入，GAV如下：\n\n```xml\n\n\u003cdependency\u003e\n    \u003cgroupId\u003ecom.feiniaojin\u003c/groupId\u003e\n    \u003cartifactId\u003egraceful-response\u003c/artifactId\u003e\n    \u003cversion\u003e{latest.version}\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\n**版本选择**：请到中央仓库选择最新的版本，boot2 和 boot3 有不用的 GAV。\n\n\u003e 仓库链接：\u003chttps://central.sonatype.com/artifact/com.feiniaojin/graceful-response\u003e\n\n## 4.2 开启 Graceful Response\n\n在启动类中引入@EnableGracefulResponse 注解，即可启用 Graceful Response 组件。\n\n```java\n\n@EnableGracefulResponse\n@SpringBootApplication\npublic class ExampleApplication {\n    public static void main(String[] args) {\n        SpringApplication.run(ExampleApplication.class, args);\n    }\n}\n```\n\n## 4.4 代码编写\n\n### 4.4.1 Controller层\n\n引入 Graceful Response 后，不需要再手工进行查询结果的封装，直接返回实际结果即可，Graceful Response 会自动完成封装的操作。\n\nController 层示例如下。\n\n```java\n\n@Controller\npublic class Controller {\n    @RequestMapping(\"/get\")\n    @ResponseBody\n    public UserInfoView get(Long id) {\n        return UserInfoView.builder().id(id).name(\"name\" + id).build();\n    }\n}\n```\n\n在示例代码中，Controller 层的方法直接返回了 UserInfoView 对象，没有进行封装的操作，但经过 Graceful Response\n处理后，还是得到了以下的响应结果。\n\n```json\n{\n  \"code\": \"0\",\n  \"msg\": \"ok\",\n  \"data\": {\n    \"id\": 1,\n    \"name\": \"name1\"\n  }\n}\n```\n\n而对于命令操作（Command，即写操作）尽量不返回数据，因此写操作的方法的返回值应该是 void，Graceful\nResponse 对于对于返回值类型 void 的方法，也会自动进行封装。\n\n```java\npublic class Controller {\n    @RequestMapping(\"/command\")\n    @ResponseBody\n    public void command() {\n        //业务操作\n    }\n}\n```\n\n成功调用该接口，将得到：\n\n```json\n{\n  \"code\": \"0\",\n  \"msg\": \"ok\",\n  \"data\": {}\n}\n```\n\n不再需要在Controller中手工封装Result/Response进行返回。\n\n### 4.4.2 Service 层\n\n在引入 Graceful Response 前，有的开发者为了在接口中返回异常码，直接将 Service 层方法定义为 Response，淹没了方法的正常返回值，非常不优雅。\n\n例如以下伪代码：\n\n```java\n/**\n * 直接返回Response的Service\n * 不规范\n */\npublic interface Service {\n    Reponse commandMethod(Command command);\n}\n```\n\nGraceful Response 通过多种机制，可以异常和错误码关联起来，这样 Service层方法就不需要再维护 Response 的响应码了，直接抛出业务异常即可。\n\n- 方法一\n\n使用@ExceptionMapper 注解修饰业务异常，提供错误码和错误提示，再由业务方法直接抛出该异常。\n\n业务异常定义：\n\n```java\n/**\n * NotFoundException的定义，使用@ExceptionMapper注解修饰\n * code:代表接口的异常码\n * msg:代表接口的异常提示\n */\n@ExceptionMapper(code = \"1404\", msg = \"找不到对象\")\npublic class NotFoundException extends RuntimeException {\n\n}\n```\n\nService 接口直接抛异常：\n\n```java\npublic class QueryServiceImpl implements QueryService {\n    @Resource\n    private UserInfoMapper mapper;\n\n    public UserInfoView queryOne(Query query) {\n        UserInfo userInfo = mapper.findOne(query.getId());\n        if (Objects.isNull(userInfo)) {\n            //这里直接抛自定义异常\n            throw new NotFoundException();\n        }\n        //……后续业务操作\n    }\n}\n```\n\n当 Service 层的 queryOne 方法抛出 NotFoundException 时，Graceful\nResponse 会进行异常捕获，并将 NotFoundException 对应的异常码和异常信息封装到统一的响应对象中，最终接口返回以下 JSON。\n\n```json\n{\n  \"code\": \"1404\",\n  \"msg\": \"找不到对象\",\n  \"data\": {}\n}\n```\n\n- 方法二\n\n方法一有可能导致定义过多的业务异常类，还可以通过使用GracefulResponse工具类进行异常抛出。\n\n```java\n\n@GetMapping(\"/raiseException0\")\npublic void raiseException0() {\n    //直接指定错误码和提示信息\n    GracefulResponse.raiseException(\"520\", \"测试手工异常0\");\n}\n\n\n@GetMapping(\"/raiseException1\")\npublic void raiseException1() {\n    try {\n\n    } catch (Exception e) {\n        //包装异常并继续抛出\n        GracefulResponse.raiseException(\"1314\", \"测试手工异常1\", e);\n    }\n}\n\n\n@GetMapping(\"/test0\")\npublic void test0() {\n    //抛出异常枚举\n    GracefulResponse.raiseException(ExceptionEnum.CUSTOM_EXCEPTION);\n}\n```\n\n# 5. 使用文档\n\n链接如下：\n\n```text\nhttps://doc.feiniaojin.com/graceful-response/home.html\n```\n\n[点击访问文档中心](https://doc.feiniaojin.com/graceful-response/home.html)\n\n# 6. 交流和反馈\n\n欢迎通过以下二维码联系作者、并加入 Graceful Response 用户交流群，申请好友时请备注“GR”。\n\n\u003cdiv\u003e\u003cimg src=\"./assets/qr.jpg\" style=\"width: 50%\"/\u003e\u003c/div\u003e\n\n公众号: 悟道领域驱动设计\n\n\u003cdiv\u003e\u003cimg src=\"./assets/gzh.jpg\" style=\"width: 50%\"/\u003e\u003c/div\u003e\n\n# 7. 贡献者\n\n\u003ca href=\"https://github.com/feiniaojin/graceful-response/graphs/contributors\"\u003e\n  \u003cimg src=\"https://contrib.rocks/image?repo=feiniaojin/graceful-response\" /\u003e\n\u003c/a\u003e\n","funding_links":[],"categories":["REST错误处理"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffeiniaojin%2Fgraceful-response","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffeiniaojin%2Fgraceful-response","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffeiniaojin%2Fgraceful-response/lists"}