Spring Boot 统一数据返回格式 分析 和 处理

news2024/11/26 16:55:59

目录

实现统一数据格式

 测试 

 原因分析

 解决方案


  • 🎥 个人主页:Dikz12
  • 📕格言:吾愚多不敏,而愿加学
  • 欢迎大家👍点赞✍评论⭐收藏

实现统一数据格式

统⼀的数据返回格式使⽤ @ControllerAdvice ResponseBodyAdvice 的⽅式实现;
@ControllerAdvice : 表⽰控制器通知类.
比如:添加类 ResponseAdvice , 实现 ResponseBodyAdvice 接⼝, 并在类上添加
@ControllerAdvice 注解.
import com.example.demo.model.Result;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

@ControllerAdvice
public class ResponseAdvice implements ResponseBodyAdvice {
    @Override
    public boolean supports(MethodParameter returnType, Class converterType) {
        return true;
    }

    @Override
    public Object beforeBodyWrite(Object body, MethodParameter returnType,
                                  MediaType selectedContentType, Class selectedConverterType,
                                  ServerHttpRequest request, ServerHttpResponse response) {
        return Result.success(body); //返回 Result 类型的数据
    }
}

 supports⽅法: 判断是否要执⾏beforeBodyWrite⽅法. true为执⾏, false不执⾏. 通过该⽅法可以 选择哪些类或哪些⽅法的response要进⾏处理, 其他的不进⾏处理.

beforeBodyWrite⽅法:对response⽅法进⾏具体操作处理.

 测试 

 写一些不同的返回结果,看看哪些会出现问题!

import com.example.demo.model.BookInfo;
import com.example.demo.model.Result;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/test")
public class TestController {
    @RequestMapping("/t1")
    public Integer t1() {
        return 12334;
    }

    @RequestMapping("/t2")
    public String t2() {
        return "hello";
    }

    @RequestMapping("/t3")
    public Boolean t3() {
        return true;
    }

    @RequestMapping("/t4")
    public BookInfo t4() {
        return new BookInfo();
    }

    @RequestMapping("/t5")
    public Result t5() {
        return Result.success("success");
    }
}

1.返回结果为Integer,可以正确响应.

 

2.返回结果为String,结果显示内部错误.

 

 控制台查看日志:

3.返回结果为Boolean,可以正常响应.

 

 4.返回结果为BookInfo对象,可以正常响应.

5.返回结果为Result,发现又进行了一次封装.

  

 问题:1.返回结果为String,不能正常进行处理了;2.返回结果为Result,又多进行了一次封装.

 原因分析

这时候就会非常纳闷了,为什么就处理String的时候会出错呢?就不得不去看源码分析了.

SpringMVC (也就是在初始化时) 默认会注册⼀些⾃带的 HttpMessageConverter (转换器) (从先后顺序排列分别为 ByteArrayHttpMessageConverter , StringHttpMessageConverter , SourceHttpMessageConverter , SourceHttpMessageConverter , AllEncompassingFormHttpMessageConverter )


 这些转换器是有先后顺序的,是用ArrayList存储的.会根据我们的返回结果挨个判断使用哪个转换器!!!

此时,就会发现问题就出现在 StringHttpMessageConverter.

处理的内容主要是在AbstractMessageConverterMethodProcessor 中 会有一个writeWithMessageConverters()方法.

通过getAdvice()拿到了beforBodyWrite 就会对body进行处理,处理完之后并没有结束(body变成了Result类型),此时,也并没有出错。会继续执行((HttpMessageConverter) converter).write(body, selectedMediaType, outputMessage).

 由于 StringHttpMessageConverter 重写了addDefaultHeaders⽅法, 所以会执⾏⼦类的⽅法

然⽽⼦类 StringHttpMessageConverter 的addDefaultHeaders⽅法定义接收参数为String, 此

时t为Result类型, 所以出现类型不匹配" Result cannot be cast to java.lang.String "的异常.

 解决方案

1.当返回结果为Result时,就直接返回body.

2.当返回结果为String时,采用SpringBoot内置提供的Jackson来实现信息的序列化 

@ControllerAdvice
public class ResponseAdvice implements ResponseBodyAdvice {

    @Autowired
    private ObjectMapper objectMapper;

    @Override
    public boolean supports(MethodParameter returnType, Class converterType) {
        return true;
    }

    @SneakyThrows
    @Override
    public Object beforeBodyWrite(Object body, MethodParameter returnType,
                                  MediaType selectedContentType, Class selectedConverterType,
                                  ServerHttpRequest request, ServerHttpResponse response) {
        //body 是返回的结果
        //当返回结果为Result类型时,就直接返回body
        if (body instanceof Result) {
            return body;
        }
        //返回结果为String类型, 使⽤SpringBoot内置提供的Jackson来实现信息的序列化
        if (body instanceof String) {
            return objectMapper.writeValueAsString(Result.success(body));
        }
        return Result.success(body); //返回 Result 类型的数据
    }
}

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

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

相关文章

达梦数据库新手上路排坑

数据库安装 这个没啥说的,按照官网教程操作,我使用的是docker进行安装 下载文件docker文件 官方下载地址- load -i dm8****.tar (注意修改为当前下载的文件)达梦官方文档注意修改为当前版本 docker run -d -p 5236:5236 --name dm8 --privilegedtrue -…

京东云4核16G服务器优惠价格26元1个月、658元1年、三年3098元

京东云4核16G服务器优惠价格26元1个月、80元3个月、658元1年、3098元三年,配置为:轻量云主机4C16G-220G SSD系统盘-5M带宽-500G月流量,京东云优惠活动 atengyun.com/go/jd 可以查看京东云服务器详细配置和精准报价单,活动打开如下…

电子显微镜——相机

相机种类 相机种类繁多,下面根据相机接口和图像传感器类型进行分类。 根据数据接口分类 1. USB相机 USB相机通常可以指代多种不同类型的USB接口相机,其中包括UVC(USB Video Class)相机和U3V(USB3 Vision)相机等,它们通常使用SOC进行开发。以下是它们的区别和特点: …

香港服务器与SEO的关系(香港服务器对SEO影响大吗?)

香港服务器与 SEO 的关系是一个备受关注的话题,不少站长在选择了香港服务器后,便会疑问:香港服务器对SEO的影响是否显著?那么,在这里就跟大家聊聊两者的关系以及影响大小。 其实,不少站长对 SEO 的这种担忧和想法是片…

测开——测试用例设计题

1.测试手机的短信功能需要考虑哪些测试点? 考测试思维 是否能正常打开或进入短信界面短信可以正常编辑、修改、删除短信可以正常发送、接收短信页面的字体、颜色显示是否正常【UI界面 手机设置了字体颜色 大小是否同步】短信的字体是否能够调整同时给多个人发短信…

JVM(一)——内存结构

一. 前言 1、什么是 JVM? 1)定义: Java Virtual Machine - java 程序的运行环境(java 二进制字节码的运行环境) 2)好处: 一次编写,到处运行自动内存管理,垃圾回收功能数组下标越…

二十九 超级数据查看器 讲解稿 查询复用

二十九 超级数据查看器 讲解稿 查询复用 ​点击此处 以新页面 打开B站 播放当前教学视频 点击访问app下载页面 百度手机助手 下载地址 大家好,今天我们讲一下超级数据查看器的查询复用功能,这是新版本要增加的功能,这讲是预告。 先介绍…

【面试那些事儿】浏览器键入网址到网页显示,期间发生了什么

当用户在浏览器中键入网址并按下回车键后,直到最终显示出完整的网页内容,这一过程中经历了哪些步骤呢? 这是一道经典的面试题,我们来看看具体有哪些阶段。 1. 解析URL 浏览器首先解析用户输入的URL,判断它的语法和协…

这本JCR一区期刊被On Hold,投稿需谨慎!

ENVIRONMENTAL SCIENCE AND POLLUTION RESEARCH 《环境科学与污染研究》 期刊官网:https://link.springer.com/journal/11356 【基础信息】 ISSN:0944-1344 eISSN:1614-7499 Index:SCIE IF(2022):5.8 出版社&am…

Codigger用户篇:安全、稳定、高效的运行环境(二)

在当今数字化时代,随着云计算和大数据技术的飞速发展,分布式操作系统已成为支撑各类应用高效运行的关键基础设施。我们推出的Codigger分布式操作系统,正是为了满足用户对安全、稳定、高效私人应用运行环境的需求而精心设计的。上一次&#xf…

警惕.360勒索病毒:如何预防.360勒索病毒攻击

导言: 在网络安全领域,勒索病毒是一种非常危险的恶意软件,它以其独特的加密方式和高昂的赎金要求,给个人和企业带来了严重的损失。.360勒索病毒便是其中之一,它属于BeijingCrypt勒索病毒家族,具有高度的隐…

下水游泳耳机怎么选?六招教你避开陷阱,选对不选贵!

游泳耳机是许多水上爱好者的首选,它不仅为我们在水中的锻炼提供了音乐的陪伴,还帮助我们隔绝外界的嘈杂,让我们更加专注于自己的水上世界。然而,面对市场上众多的游泳耳机产品,如何选择一款既适合自己又性价比高的产品…

PyCharm代码一键格式化

前言 每次写完代码,就看见很多警告,乍一看还以为我又写了什么bug,原来是提示,啊放心了。可是我可见不得这些东西,因为代码里都是红红的下划线,好像在圈圈点点。。。 代码格式化 于是利用PyCharm里的快捷…

分布式图床项目

一、图床架构分析 二、后台数据处理框架 秒传: 如果上传的文件已经在服务器中存在了,就不需要二次上传了,但是服务器会对这个文件的引用计数加一,这样服务器就知道这个文件是多个人持有的。先对上传的文件进行 md5 校验来判断服务器中已经存在相同的文件了(同样的文件拿到…

【动手学深度学习】9.6 编码器和解码器

正如我们在 9.5节中所讨论的, 机器翻译是序列转换模型的一个核心问题, 其输入和输出都是长度可变的序列。 为了处理这种类型的输入和输出, 我们可以设计一个包含两个主要组件的架构: 第一个组件是一个编码器(encoder&a…

AI 文字转语音工具以及它们的官网收集(值得收藏)

目前比较成熟的 AI 文字转语音工具以及它们的官网: 百度语音合成 (https://ai.baidu.com/tech/speech/tts): 百度语音合成是百度 AI 推出的语音合成服务,支持多种语言和音色,可以用于语音播报、智能客服、有声阅读等场景。 阿里云…

基于单片机的便携式瓦斯检测仪系统设计

**单片机设计介绍,基于单片机的便携式瓦斯检测仪系统设计 文章目录 一 概要二、功能设计设计思路 三、 软件设计原理图 五、 程序六、 文章目录 一 概要 基于单片机的便携式瓦斯检测仪系统设计是一个针对煤矿等工业环境中瓦斯气体浓度检测的重要项目。以下是该设计…

GESP Python编程三级认证真题 2024年3月

Python 三级 2024 年 03 月 1 单选题(每题 2 分,共 30 分) 第 1 题 小杨的父母最近刚刚给他买了一块华为手表,他说手表上跑的是鸿蒙,这个鸿蒙是?( ) A. 小程序 B. 计时器 C. 操作系统…

Photoshop 2024 中文---专业图像处理软件的又一次飞跃

Photoshop 2024是一款功能强大的图像处理软件,广泛应用于创意设计和图像处理领域。它提供了丰富的绘画和编辑工具,包括画笔、铅笔、颜色替换、混合器画笔等,使用户能够轻松进行图片编辑、合成、校色、抠图等操作,实现各种视觉效果…

Spring后置处理器(PostProcessor)

文章目录 引言BeanFactoryPostProcessor常见用法创建自定义后置处理器注册后置处理器执行后置处理器 BeanPostProcessor常见用法创建自定义后置处理器注册后置处理器执行后置处理器 实际需求验证配置文件的正确性检验逻辑 引言 在Spring框架中,后置处理器为我们提供…