统一数据返回格式 及 可能遇到的问题;统一异常处理

统一数据返回格式

统一数据返回格式就像我们寄快递一样,不管你需要寄的东西具体是什么都需要将它打包到统一的快递箱中。

此时我们需要一个“快递箱”用来将返回的数据“装”在里面。这个类是根据业务情况来自行定义的。

@Data
public class Resp<T> {//200-正常  0-发生异常private Integer code;//错误信息private String desc;//返回数据private T data;//成功public static <T> Resp<T> seccess(T data) {Resp<T> resp = new Resp<>();resp.setCode(200);resp.setData(data);return resp;}
}

有了“快递箱之后”还需要一个“工作人员”来将“快递”进行打包,此时我们需要创建一个新类并使其实现ResponseBodyAdvice 接口并重写里面的方法,然后给当前类加上@ControllerAdvice注解。

@ControllerAdvice
public class Advice implements ResponseBodyAdvice {@Overridepublic boolean supports(MethodParameter returnType, Class converterType) {return false;}@Overridepublic Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {return null;}
}

supports():这个方法用来决定是否执行beforeBodyWrite()方法,如果返回true表示执行,否则返回false。通过该方法可以选择哪些类或哪些方法的响应要进行处理,其他的不进行处理;beforeBodyWrite():对响应进行具体操作处理。

先创建两个用于测试的接口:

@RestController
@RequestMapping("/test")
public class Test {@RequestMapping("/fun1")public boolean fun1() {return false;}@RequestMapping("/fun2")public Integer fun2() {return 34;}
}

接下来将fun1和fun2方法的返回值进行“打包”。

@ControllerAdvice
public class Advice implements ResponseBodyAdvice {@Overridepublic boolean supports(MethodParameter returnType, Class converterType) {return true;}@Overridepublic Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {return Resp.seccess(body);}
}

但是实际应用时还有几个问题:

问题一:重复打包

如果此时fun1返回的就是Resp类型的值那么就会出现重复打包的问题。

@RequestMapping("/fun1")
public Resp<Boolean> fun1() {return Resp.seccess(false);
}

解决方法就是可以在打包前进行一次判断,如果已经被打包了就直接返回,否则进行打包。

@Override
public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {if (body instanceof Resp) {return body;}return Resp.seccess(body);
}

问题二:ClassCastException: com.example.Spring_demo.Resp cannot be cast to java.lang.String

这个问题的出现场景是在返回值为String类型时出现的。假设fun1现在返回值是String类型:

@RequestMapping("/fun1")
public String fun1() {return "hahaha";
}

解决方法就是如果返回结果为String类型, 使用SpringBoot内置提供的Jackson来实现信息的序列化。

@SneakyThrows
@Override
public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {if (body instanceof String) {return new ObjectMapper().writeValueAsString(Resp.seccess(body));}if (body instanceof Resp) {return body;}return Resp.seccess(body);
}

注意:此时返回的是字符串。

使用这个就可以解决:@RequestMapping(value = "/fun1", produces = "application/json")

优点

  • 方便前端程序员更好的接收和解析后端数据接口返回的数据;
  • 降低前端程序员和后端程序员的沟通成本,按照某个格式实现就可以了,因为所有接口都是这样返回的;
  • 有利于项目统一数据的维护和修改;
  • 有利于后端技术部门的统一规范的标准制定,不会出现稀奇古怪的返回内容。
     

统一异常处理

如果fun1方法在执行时出现异常也会出现不合理的返回信息:

@RequestMapping(value = "/fun1", produces = "application/json")
public String fun1() {System.out.println(3/0);return "hahaha";
}

此时就需要用到统一异常处理来对程序执行过程中发生的异常进行捕获和处理。统一异常处理需要使用两个注解@ExceptionHandler@ControllerAdvice,如果返回的是数据还需要加上@ResponseBody注解。

下面代码表示,如果代码出现Exception异常(包括Exception的子类)才会被捕获,然后执行该方法。

@ControllerAdvice
@ResponseBody
public class ErrorAdvice {@ExceptionHandlerpublic Object handler(Exception e) {return Resp.fail("Exception: 程序出现异常");}
}

当有多个异常通知时,匹配顺序为当前类及其子类向上依次匹配。如此时有两个,继续访问fun1方法。

@ControllerAdvice
@ResponseBody
public class ErrorAdvice {@ExceptionHandlerpublic Object handler(Exception e) {return Resp.fail("Exception: 程序出现异常");}@ExceptionHandlerpublic Object handler(ArithmeticException e) {return Resp.fail("ArithmeticException: 程序出现算数异常");}
}

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

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

相关文章

[嵌入式AI从0开始到入土]14_orangepi_aipro小修补含yolov7多线程案例

[嵌入式AI从0开始到入土]嵌入式AI系列教程 注&#xff1a;等我摸完鱼再把链接补上 可以关注我的B站号工具人呵呵的个人空间&#xff0c;后期会考虑出视频教程&#xff0c;务必催更&#xff0c;以防我变身鸽王。 第1期 昇腾Altas 200 DK上手 第2期 下载昇腾案例并运行 第3期 官…

PHP毕业设计图片分享网站76t17

图片分享网站主要是为了提高工作人员的工作效率和更方便快捷的满足用户&#xff0c;更好存储所有数据信息及快速方便的检索功能&#xff0c;对系统的各个模块是通过许多今天的发达系统做出合理的分析来确定考虑用户的可操作性&#xff0c;遵循开发的系统优化的原则&#xff0c;…

【C语言】Linux内核bind系统调用代码

一、Linux 4.9内核bind系统调用代码注释 int __sys_bind(int fd, struct sockaddr __user *umyaddr, int addrlen) {struct socket *sock; // 定义socket对象的指针struct sockaddr_storage address; // 用于存储从用户空间复制过来的地址int err…

谷歌搜索技巧与 ChatGPT 实用指南:提升你的在线生产力

探索谷歌搜索技巧&#xff0c;提升搜索效率 前言 在搜索三巨头百度、必应、谷歌中&#xff0c;谷歌在搜索精确度以及多语言兼容性方面有明显的优势。其次在国内想要使用谷歌搜索你需要会科学上网&#xff08;这里不说&#xff09;。 一.排除干扰内容&#xff08;广告&#xff…

vue-进阶语法(四)

目录 v-model原理 v-model应用于组件 sync修饰符 ref 和 $refs&#xff08;重点&#xff09; $nextTick v-model原理 原理&#xff1a;v-model本质上是一个语法糖。例如应用在输入框上&#xff0c;就是 value属性 和 input事件 的合写。 作用&#xff1a;提供数据的双向…

压缩PDF的大小-Adobe Acrobat Pro

经常遇到上传的pdf太大&#xff0c;无法成功上传。 今天找到一个方法&#xff1a; 打开Adobe Acrobat Pro软件 → 文件 → 另存为其他&#xff08;H&#xff09;... →缩小大小的PDF 版本选择 4.0 最低的版本。 文件由9M变为1.5M。

Codeforces Round 924 (Div. 2) B - D

B. Equalize 题目&#xff1a; 思路&#xff1a;首先排序然后去重&#xff08;可以用set来去重&#xff09;&#xff0c;我们可以肯定的是&#xff0c;如果连续k个数最大值最小值的差小于等于n的话&#xff0c;那么这个长度为k的区间就符合答案要求&#xff0c;那么k就和答案…

###51单片机学习(2)-----如何通过C语言运用延时函数设计LED流水灯

前言&#xff1a;感谢您的关注哦&#xff0c;我会持续更新编程相关知识&#xff0c;愿您在这里有所收获。如果有任何问题&#xff0c;欢迎沟通交流&#xff01;期待与您在学习编程的道路上共同进步。 目录 一. 延时函数的生成 1.通过延时计算器得到延时函数 2.可赋值改变…

Linux释放内存

free -m是Linux上查看内存的指令&#xff0c;其中-m是以兆&#xff08;MB&#xff09;为单位&#xff0c;如果不加则以KB为单位。 如下图表示&#xff0c;&#xff08;total&#xff09;总物理内存是809MB&#xff0c;&#xff08;used&#xff09;已使用167MB&#xff0c;&…

【AI视野·今日NLP 自然语言处理论文速览 第七十九期】Thu, 18 Jan 2024

AI视野今日CS.NLP 自然语言处理论文速览 Thu, 18 Jan 2024 Totally 35 papers &#x1f449;上期速览✈更多精彩请移步主页 Daily Computation and Language Papers Deciphering Textual Authenticity: A Generalized Strategy through the Lens of Large Language Semantics …

【Py/Java/C++三种语言详解】LeetCode每日一题240215【二叉树BFS】LeetCode107、二叉树的层序遍历II

有LeetCode交流群/华为OD考试扣扣交流群可加&#xff1a;948025485 可上全网独家的 欧弟OJ系统 练习华子OD、大厂真题 绿色聊天软件戳 od1336了解算法冲刺训练 文章目录 题目链接题目描述解题思路DFS和BFS异同用队列维护的BFS 代码PythonJavaC时空复杂度 相关习题华为OD算法/大…

计算机视觉基础:获取图像的ROI

在图像处理过程中&#xff0c;我们可能会对图像的某一个特定区域感兴趣&#xff0c;该区域被称为感兴趣区域&#xff08;Region of Interest&#xff0c;ROI&#xff09;。在设定感兴趣区域ROI后&#xff0c;就可以对该区域进行整体操作。 Python实现代码如下&#xff1a; # -…

[职场] 花园管家是做什么的 #笔记#学习方法

花园管家是做什么的 一、工作内容职责&#xff1a; 1.管理花园内的活动和工作&#xff0c;协调各方资源&#xff0c;确保活动的顺利进行&#xff1b; 2.提供优质的客户服务和接待工作&#xff0c;解决客户问题&#xff0c;处理投诉&#xff0c;提高客户满意度&#xff1b; …

(03)Hive的相关概念——分区表、分桶表

目录 一、Hive分区表 1.1 分区表的概念 1.2 分区表的创建 1.3 分区表数据加载及查询 1.3.1 静态分区 1.3.2 动态分区 1.4 分区表的本质及使用 1.5 分区表的注意事项 1.6 多重分区表 二、Hive分桶表 2.1 分桶表的概念 2.2 分桶表的创建 2.3 分桶表的数据加载 2.4 …

操作系统(14)----文件系统的结构

目录 一.文件系统的层次结构 1.用户接口&#xff1a; 2.文件目录系统&#xff1a; 3.存取控制模块&#xff1a; 4.逻辑文件系统与文件信息缓冲区&#xff1a; 5.物理文件系统&#xff1a; 二.文件系统的全局结构 1.文件系统在外存中的结构 &#xff08;1&#xff09;物…

Mermaid绘制UML图教程

Mermaid 是一种轻量级的图形描述语言&#xff0c;用于绘制流程图、时序图、甘特图等各种图表。它采用简单的文本语法&#xff0c;使得用户能够快速绘制各种复杂图表&#xff0c;而无需深入学习图形绘制工具。 一、安装Mermaid Mermaid 可以在浏览器中直接使用&#xff0c;也可…

剑指offer——数值的整数次方

目录 1. 题目描述2. 一般思路2.1 有问题的思路2.2 全面但不高效的思路2.3 面试小提示 3. 全面又高效的思路 1. 题目描述 题目:实现函数 double Power(double base,int exponent)&#xff0c;求base 的exponent 次方。不得使用库函数&#xff0c;同时不需要考虑大数问题 2. 一般…

第13讲创建图文投票

创建图文投票实现 图文投票和文字投票基本一样&#xff0c;就是在投票选项里面&#xff0c;多了一个选项图片&#xff1b;、 <view class"option_item" v-for"(item,index) in options" :key"item.id"><view class"option_input&…

AIGC盛行,带你轻松调用开发

文章目录 前言一、&#x1f4d6;AIGC简介二、&#x1f4e3;开通体验开通模型获取API-KEY 三、&#x1f4dd;基于java实现调用1.设置API-KEY2.体验大语言模型多轮对话演示补充流式输出 3.体验通义千问VL使用官方提供照片本地文件多轮对话流式输出 总结 前言 本篇文章基于java和…

C++的进阶泛型编程学习(1):函数模板的基本概念和机制

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、模板1.1 模板的概念1.1.1 形象的解释&#xff1a;模板就是通用的模具&#xff0c;目的是提高通用性1.1.1 模板的特点&#xff1a;1.1.2 综述模板的作用 1.2…