Graceful Response 构建 Spring Boot 下优雅的响应处理

news2024/11/20 15:24:22

一、Graceful Response

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

github地址:https://github.com/feiniaojin/graceful-response

对应 SpringBoot 版本

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

二、快速使用

引入依赖:

<dependency>
    <groupId>com.feiniaojin</groupId>
    <artifactId>graceful-response</artifactId>
    <version>3.4.0-boot2</version>
</dependency>

启动类增加注解:

@EnableGracefulResponse

声明测试接口:

@Slf4j
@RestController
@RequestMapping("/test")
public class TestController {

    /**
     * 返回对象形式
     */
    @GetMapping("/t1")
    public Map<String, String> t1() {
        //具体逻辑
        return Collections.singletonMap("status","abc");
    }

    /**
     * Command 形式
     */
    @GetMapping("/t2")
    public void t2() {
        // 具体逻辑
    }
}

测试 /test/t1 接口:

在这里插入图片描述

测试 /test/t2 接口:

在这里插入图片描述

三、返回格式调整

Graceful Response 内置了两种风格的返回,可以通过修改 graceful-response.response-style 进行切换,分别是:

默认格式:

graceful-response:
  response-style: 0
{
  "status": {
    "code": 200,
    "msg": "success"
  },
  "payload": {
  }
}

第二种模式:

graceful-response:
  response-style: 1

格式如下:

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

如果需要自定义返回格式则需要实现 Response 接口,并在配置中通过graceful-response.response-class-full-name 进行指定,例如:

@Data
public class CustomResponse implements Response {

    private String code;

    private Long timestamp = System.currentTimeMillis();

    private String message;

    private Object data = Collections.EMPTY_MAP;

    @Override
    public void setStatus(ResponseStatus statusLine) {
        this.code = statusLine.getCode();
        this.message = statusLine.getMsg();
    }

    @Override
    @JsonIgnore
    public ResponseStatus getStatus() {
        return null;
    }

    @Override
    public void setPayload(Object payload) {
        this.data = payload;
    }

    @Override
    @JsonIgnore
    public Object getPayload() {
        return null;
    }
}

然后在配置文件中声明:

graceful-response:
  response-class-full-name: com.bxc.retrydemo.handler.CustomResponse

再次访问上面的测试接口:

在这里插入图片描述

四、自定义异常和错误码

当抛出异常时我们希望根据不同的异常返回不同的错误码,在 Graceful Response 中为我们提供了 @ExceptionMapper 注解,可以快速的指定返回的错误码和提示。

例如:

@ExceptionMapper(code = "1003", msg = "自定义异常", msgReplaceable = true)
public class MyException extends RuntimeException {

    public MyException() {
        super();
    }

    public MyException(String message) {
        super(message);
    }

    public MyException(String message, Throwable cause) {
        super(message, cause);
    }

    public MyException(Throwable cause) {
        super(cause);
    }

    public MyException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
        super(message, cause, enableSuppression, writableStackTrace);
    }
}

测试接口修改:

@Slf4j
@RestController
@RequestMapping("/test")
public class TestController {

    /**
     * 返回对象形式
     */
    @GetMapping("/t1")
    public Map<String, String> t1(Integer a) {
        //具体逻辑
        // ....
        // 抛出异常
        if (a == 0){
            throw new MyException();
        }
        return Collections.singletonMap("status","abc");
    }

    /**
     * Command 形式
     */
    @GetMapping("/t2")
    public void t2(Integer a) {
        //具体逻辑
        // ....
        // 抛出异常
        if (a == 0){
            throw new MyException("t2 接口执行异常");
        }
    }
}

测试 /test/t1 接口:
在这里插入图片描述

测试 /test/t2 接口:

在这里插入图片描述

五、参数校验异常错误码

有的时候我们需要校验某个参数是否合法,当在不同情况下需要返回不同的错误码,在 Graceful Response 中对JSR-303数据校验规范和Hibernate Validator进行了增强,Graceful Response自身不提供参数校验的功能,但是用户使用了Hibernate Validator后,Graceful Response可以通过@ValidationStatusCode注解为参数校验结果提供响应码,并将其统一封装返回。

例如:

@Data
public class TestDTO {
    @NotNull(message = "name 不可为空")
    @Length(min = 1, max = 5, message = "name 的长度在 1-5 之间")
    @ValidationStatusCode(code = "1003")
    private String name;

    @NotNull(message = "age 不可为空")
    @Min(value = 0,message = "age 不可小于 0 ")
    @ValidationStatusCode(code = "1004")
    private Integer age;
}

声明测试接口:

@Slf4j
@RestController
@RequestMapping("/test")
public class TestController {

    @PostMapping("/t3")
    public void t3(@Validated TestDTO dto) {
        //具体逻辑
        // ....
    }
}

测试 /test/t3 接口:

在这里插入图片描述

六、手动抛出指定状态码和信息

Graceful Response 提供了 GracefulResponse 通用工具类,在需要抛出GracefulResponseException时,只需要调用raiseException方法即可。

例如:

@Slf4j
@RestController
@RequestMapping("/test")
public class TestController {

    /**
     * 返回对象形式
     */
    @GetMapping("/t1")
    public Map<String, String> t1(Integer a) {
        //具体逻辑
        // ....
        // 抛出异常
        if (a == 0) {
            GracefulResponse.raiseException("1065", "自定义抛出异常");
        }
        return Collections.singletonMap("status", "abc");
    }
}

测试 /test/t1 接口:

在这里插入图片描述

七、例外请求放行

Graceful Response 会对所有的 controller 方法处理,如果希望跳过自定处理返回可以可以添加 @ExcludeFromGracefulResponse注解:

例如:

@Slf4j
@RestController
@RequestMapping("/test")
public class TestController {

    /**
     * 返回对象形式
     */
    @GetMapping("/t1")
    @ExcludeFromGracefulResponse
    public Map<String, String> t1(Integer a) {
        //具体逻辑
        // ....
        return Collections.singletonMap("status", "abc");
    }
}

在这里插入图片描述
也可以根据包名进行排除,例如:

graceful-response:
  exclude-packages:
    - springfox.**
graceful-response:
  exclude-packages:
    - org.springframework.boot.actuate.*

八、常用配置

graceful-response:
  # 自定义Response类的全限定名,默认为空。 
  # 配置response-class-full-name后,response-style将不再生效
  response-class-full-name:
  # 是否打印异常日志,默认为false
  print-exception-in-global-advice: false
  # Response风格,不配置默认为0
  response-style: 0
  # 自定义的成功响应码,不配置则为0
  default-success-code: 0
  # 自定义的成功提示,默认为ok
  default-success-msg: ok
  # 自定义的失败响应码,默认为1
  default-error-code: 1
  # 自定义的失败提示,默认为error
  default-error-msg: error
  # 全局的参数校验错误码,默认等于default-error-code
  default-validate-error-code:
  # 例外包路径(支持数字, *和**通配符匹配),该包路径下的controller将被忽略处理
  exclude-packages:
    - com.lizhiadmin.pro.module.*.controller
  # 设置是否将原生异常错误信息detailMessage字段填充到Response的msg中
  # 默认为false,即不打开
  origin-exception-using-detail-message: false

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

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

相关文章

SpringBoot 项目如何生成 swagger 文档

推荐使用 springdoc-openapi 的理由 1、springdoc-openapi 是 spring 官方出品&#xff0c;与 springboot 兼容更好&#xff08;springfox 兼容有坑&#xff09; 2、springdoc-openapi 社区更活跃&#xff0c;springfox 已经 2 年没更新了 3、springdoc-openapi 的注解更接近 …

如何在Mendix中实现全文检索

功能背景 在日常的应用使用过程中&#xff0c;存在大量希望使用全文检索技术的场景&#xff0c;对资料库中的内容进行查询。Mendix默认的结构化查询方式&#xff0c;适合对特定业务实体进行类似数据库单表的基于SQL语句的查询。那如何在Mendix实现全文检索的功能呢&#…

Flink-【时间语义、窗口、水位线】

1. 时间语义 1.1 事件时间&#xff1a;数据产生的事件&#xff08;机器时间&#xff09;&#xff1b; 1.2 处理时间&#xff1a;数据处理的时间&#xff08;系统时间&#xff09;。 &#x1f330;&#xff1a;可乐 可乐的生产日期 事件时间&#xff08;可乐产生的时间&…

vue $set 报错 Cannot use ‘in‘ operator to search for ‘imgs‘ in

这行代码会报上述错误 本意是当对象属性为空时,添加一个响应式属性. 猜测增加属性可能需要对象的原始地址,这里的 this.imageUploadData.rowData 显然不是原始地址,他是引用的 rowData 变量的地址. 于是改成 , 修改原始地址对象的属性,报错消失 this.$set(rowData, imgs, nu…

LanChatRoom局域网聊天室

CPP已经结课&#xff0c;我提交的项目是Qt的入门项目&#xff0c;局域网聊天室LanChatRoom。 这个代码重构了很多遍。第一遍是照着明哥推荐到书&#xff0c;把代码抄了一遍。 但抄下来之后&#xff0c;各种问题&#xff0c;而且是清朝老代码。抄了一遍之后&#xff0c;对代码的…

论文阅读:基于MCMC的能量模型最大似然学习剖析

On the Anatomy of MCMC-Based Maximum Likelihood Learning of Energy-Based Models 相关代码&#xff1a;点击 本文只介绍关于MCMC训练的部分&#xff0c;由此可知&#xff0c;MCMC常常被用于训练EBM。最后一张图源于Implicit Generation and Modeling with Energy-Based Mod…

Elasticsearch:带有自查询检索器的聊天机器人示例

本工作簿演示了 Elasticsearch 的自查询检索器 (self-query retriever) 将问题转换为结构化查询并将结构化查询应用于 Elasticsearch 索引的示例。 在开始之前&#xff0c;我们首先使用 langchain 将文档分割成块&#xff0c;然后使用 ElasticsearchStore.from_documents 创建…

IIS通过ARR实现负载均衡

一、实现整体方式介绍 项目中部署在windows服务器上的项目,需要部署负载均衡,本来想用nginx来配置的,奈何iis上有几个项目,把80端口和443端口占用了,nginx就用不了了(因为通过域名访问的,必须要用80和443端口),只能通过IIS的方式实现了。 这里用2个服务在一台机器上…

一个简单的接口自动化测试框架:Python+Requests+Pytest+Allure

项目结构 project&#xff1a;api_test ——api_keyword ————api_key.py&#xff1a;接口关键字驱动类 ——case ————test_cases.py&#xff1a;测试套件和测试用例 ——report_allure&#xff08;无需创建&#xff09;&#xff1a;allure报告 ——result&#xff08;…

git 如何撤销历史某次merge

git&#xff0c;如何 撤销某一次历史提交或merge&#xff0c;并保留该版本的后续提交&#xff1f; 场景1&#xff1a; 你有两个功能迭代版本的分支&#xff0c;一个是 15 号上线&#xff0c;一个是25号上线。5号的时候产品突然说&#xff0c;这两个版本一起上&#xff0c;然后…

【计算机图形学】NAP: Neural 3D Articulation Prior

文章目录 1. 这篇论文做了什么事&#xff0c;有什么贡献&#xff1f;2. Related Work铰接物体建模3D中的Diffusion model扩散模型 3. Pipeline铰接树参数化基于Diffusion的铰接树生成去噪网络 4. 实验评价铰接物体生成——以往做法与本文提出的新指标NAP捕捉到的铰接物体分布质…

gazebo卡住不动

可以看到这个sdf文件里面含有网络连接&#xff0c;有的sdf文件看上去几十个kb, 以为很小&#xff0c;但是里面含有网络连接就不知道有多大了&#xff0c;所以也可能会卡住,然后就会出现这个

无线路由器的五种工作模式:

1.Router&#xff0c;即无线路由模式&#xff0c;这也是我们最常用的一种工作方式&#xff0c;一般家里宽带连接&#xff0c;将宽带猫连接在无线路由的WAN口上&#xff0c;然后做拨号帐号设置&#xff0c;就用这个模式即可。 在Router&#xff08;无线路由&#xff09;模式下&a…

linux下docker搭建mysql8

1&#xff1a;环境信息 centos 7,mysql8 安装docker环境 2.创建mysql容器 2.1 拉取镜像 docker pull mysql:8.0.23 2.2 查询镜像拉取成功 docker images 2.3 创建挂载的目录文件 mkdir /usr/mysql8/conf mkdir /usr/mysql8/data ##给data文件赋予操作权限 chmod 777 /…

关于时间格式yyyy-M-d或yyyy-MM-d到yyyy-MM-dd的转换

工作时遇到前端传的时间格式是"2023-12-3 17:41:52"&#xff0c;和"2023-1-1 17:41:52"但是我想要的是"2023-12-03 17:41:52"和"2023-01-01 17:41:52"。下面给大家分享几个解决方法 方法一&#xff1a; 找前端&#xff01;让他改&…

TCP_可靠数据传输原理

引言 在网络通信中&#xff0c;TCP是确保数据可靠传输的关键协议。但在我们深入研究TCP拥塞控制技术之前&#xff0c;让我们先探索可靠数据传输的原理&#xff0c;特别是TCP头部中一些重要字段的作用。 网络层提供了点对点的通信服务&#xff0c;努力交付数据报&#xff0c;但…

[概率论]四小时不挂猴博士

贝叶斯公式是什么 贝叶斯公式是概率论中的一个重要定理&#xff0c;用于计算在已知一些先验信息的情况下&#xff0c;更新对事件发生概率的估计。贝叶斯公式的表达式如下&#xff1a; P(A|B) P(B|A) * P(A) / P(B) 其中&#xff0c;P(A|B)表示在事件B发生的条件下事件A发生的概…

Android App从备案到上架全过程

不知道大家注意没有,最近几年来,新的移动App想要上架是会非常困难的,并且对于个人开发者和小企业几乎是难如登天,各种备案和审核。但是到底有多难,或许只有上架过的才会有所体会。 首先是目前各大应用市场陆续推出新的声明,各种备案截止日期到12月就要到最后期限责令整改…

wps将姓名处理格式为:姓**

1.打开wps&#xff0c;在要处理数据右侧一个单元格 输入公式&#xff1a;LEFT(A1,1)&"**"&#xff0c;然后回车 2.按住ctrl和处理好的数据的右下角小方框&#xff0c;往下拖动即可生成格式为&#xff1a;姓** 格式的数据 3.复制生成的数据&#xff0c;右键选择 “…

三、HTML元素

一、HTML元素 HTML 文档由 HTML 元素定义。 *开始标签常被称为起始标签&#xff08;opening tag&#xff09;&#xff0c;结束标签常称为闭合标签&#xff08;closing tag&#xff09;。 二、HTML 元素语法 HTML 元素以开始标签起始。HTML 元素以结束标签终止。元素的内容是…