记一次接口交互is开头的属性序列化后“is”丢失问题

问题背景:

今天在做项目联调时调用别人的第三方接口时,发现字段传递不对导致参数传递异常的问题,当时还很奇怪,明白传好着呢,怎么就好端端的出现字段不对的情况呢?

查看发现该字段为boolean类型的isIsRefresh,但传给第三方json串里字段变为了isRefresh,发现类中定义的字段确实为isIsRefresh,与设计文档上相同,并非定义错误。因此猜测是在服务传递时导致is丢失。(此处对于这个字段属性名称请大家不要喷,第三方叫这个,非常想改无奈别人的代码没法动,叫的的确不咋样,本文重点说一下为什么会出这个问题,这个问题应该如何解决、处理,请各位大佬不要追究属性名哦,也正是因为这个不规范命名才导致了此次联调失败)。

这个是我传的值:

这个是对方接口接收到的值:(命名凑合看)

这个是我的实体Bean:

明显是有区别的,两个is变成了一个is,导致对方接口参数校验失败,(除了命名之外看着是没有问题的,但就是传值不对)

原因分析:

JavaBean类的属性的类型是boolean类型,那么该属性的读方法的格式可以是isXxx()或者getXxx(),例如,名为state的boolean类型的属性,它的读方法可以是isState()或者是getState()。

【强制】POJO 类中的任何布尔类型的变量,都不要加 is 前缀,否则部分框架解析会引起序列化错误。

反例:定义为基本数据类型 Boolean isDeleted 的属性,它的方法也是 isDeleted(),框架在反向解析的时候,“误以为”对应的属性名称是 deleted,导致属性获取不到,进而抛出异常。

问题验证:

定义一个实体类BeanTest,含有boolean的属性isSuccess 和 String类型的属性name,使用Lombok框架来生成getter、setter和constructor。测试方法分别使用Gson、Fastjson和Jackson来进行序列化,测试结果如下。

@Data
class BeanTest {private String name;private boolean isSuccess;private boolean isFlag;public BeanTest(String name, boolean isSuccess, boolean isFlag) {this.name = name;this.isSuccess = isSuccess;this.isFlag = isFlag;}public BeanTest() {}public static void main(String[] args) throws JsonProcessingException {BeanTest bean = new BeanTest("allen",true,false);//GsonString gsonString = new Gson().toJson(bean);System.out.println("Gson: " + gsonString);//fastjsonString fastJsonString = JSON.toJSONString(bean);System.out.println("Fastjson: " + fastJsonString);//JacksonString jacksonString = new ObjectMapper().writeValueAsString(bean);System.out.println("Jackson: " + jacksonString);}
}

执行结果:

Gson: {"name":"allen","isSuccess":true,"isFlag":false}
Fastjson: {"flag":false,"name":"allen","success":true}
Jackson: {"name":"allen","success":true,"flag":false}

可以看出使用Gson序列化后的json串没有出现is丢失的问题,而jackson和fastjson均出现了is丢失的问题,Gson是根据类中属性进行序列化,所以结果没什么问题。而Jackson和FastJson的序列化方式是先找到getter方法,再根据JavaBean规范生成对应的属性名,所以不仅isBooTest属性被序列化成booTest且testAtt这个类中根本不存在的属性也在序列化的结果中。

解决方案:

经过测试发现对于jackson和fastjson会出现一下几种情况,而gson在这些情景下都可以正确的序列化 。

1.is开头的非boolean类型字段,使用getIsXXX方法,序列化后字段名不变

2.is开头的非boolean类型字段,使用isXXX方法,序列化之后消失

3.is开头的boolean类型字段,使用getIsXXX方法,序列化之后字段名不变

4.is开头的boolean类型字段,使用isXXX方法,序列化之后字段名前的is被去除

若要避免该问题,有以下几种方法

方法1:bean的boolean属性设置时不要以is作为小驼峰;

方法2:不要使用@Data生成getter,应该使用快捷键生成,然后手动修改成getIsXxx()的形式;

方法3:使用Gson序列化对象;

方法4:bean的布尔类型属性设置为包装类型Boolean,而不要使用boolean。使用Boolean时@Data生成的getter和setter为getIsXxx(), setIsXxx()。

 对于这个问题,我还是要说一句:既然有规范请严格按照规范,起这种命名害人害己,请大家谨记,以下是阿里开发规范,仅供参考!!!!

注释:RPC(Remote Procedure Call,远程过程调用)是一个计算机通信协议。

  • RPC 是一种基于 TCP 传输层或者 HTTP2 应用层的通信协议;
  • HTTP 只基于 HTTP 协议,包括 HTTP1.x(即 HTTP1.0、1.1) 和 HTTP2,目前很多浏览器默认使用 1.x 来访问服务器数据。

当然你要是实在迫不得已没办法了,这么做也是可以改成的,但并不建议! 

 

https://blog.csdn.net/yangf257/article/details/131209619

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

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

相关文章

node fs模块读取文件 readFile、readFileSync、fsPromises.readFile、createReadStream

文章目录 1.读取文件1.1 readFile1.2 readFileSync1.3 fsPromises.readFile:promise的写法1.4 fs.createReadStream 1.读取文件 readFile:异步读取文件readFileSync:同步读取文件fsPromises.readFile:promise的写法 需要注意的是…

vue data变量不能以“_”开头,否则会产生很多怪异问题

1、 比如给子组件赋值&#xff0c;子组件无法得到这个值&#xff08;也不是一直无法得到&#xff0c;设置后this.$forceUpdate() 居然可以得到&#xff09;&#xff0c; 更无法watch到 <zizujian :config"_config1"> </zizujian>this._config1 { ...…

【微服务核心】MyBatis Plus

MyBatis Plus 文章目录 MyBatis Plus1. 简介2. 入门使用3. 核心功能3.1 CRUD 接口3.1.1 Mapper CRUD 接口3.1.2 Service CRUD 接口 3.2 条件构造器3.3 分页插件3.4 Mybatis-Plus 注解 4. 拓展4.1 逻辑删除4.2 MybatisX快速开发插件 5. 插件5.1 [分页插件](#page)5.2 乐观锁插件…

如何从RTP包的AP类型包,获取h265的PPS、SPS、VPS信息

ffmpeg播放rtp流&#xff0c;为了降低首开延迟&#xff0c;需要在SDP文件中指定PPS、SPS、VPS信息。抓包后发现wireshark无法解析AP包。需要自己进行AP包解析。RTP协议AP包格式如下&#xff1a; 根据如上信息&#xff0c;我们可以解析AP包&#xff0c;效果如下 40 01&#xff…

Windows上安装NodeJs

Windows上安装NodeJs 一、操作环境 操作系统: Windows 10 专业版 SDK:NodeJs v16.19.1&#xff08;安装鸿蒙IDE自动安装的NodeJs&#xff09; 二、安装过程 2.1下载Node.js安装包 官网下载地址&#xff1a; 下载历史版本安装也可 2.2 双击下载好的安装文件 2.3 打开下载…

ClickHouse基础知识(五):ClickHouse的SQL 操作

基本上来说传统关系型数据库&#xff08;以 MySQL 为例&#xff09;的 SQL 语句&#xff0c;ClickHouse 基本都支持&#xff0c; 这里不会从头讲解 SQL 语法只介绍 ClickHouse 与标准 SQL&#xff08;MySQL&#xff09;不一致的地方。 1. Insert 基本与标准 SQL&#xff08;My…

如何基于一台MacBook搞定企业级大模型知识库部署

▼最近直播超级多&#xff0c;预约保你有收获 今晚直播&#xff1a;《ChatGLM3/Qwen业务案例实战》 —1— 为什么要在 MacBook 上搭建知识库&#xff1f; 最核心最重要的是我们手上的文档资料出于安全要求&#xff0c;不能随便上传到云服务&#xff0c;也就无法实际验证知识库的…

统信操作系统中QWebEngine(js与C++交互)

一、直接方式C++调用JS函数 1.1 编写C++界面框架 界面有两个控件组成。QWebEngineView和QPushButton组成。上面部分位webengineview 下面部分位C++的按钮。 处理逻辑是希望按钮按下QPushButton的直接调用QWebEngineView中js定义好的函数。 大致内容如下图: mainwindow.cpp文…

刷算法-- leetcode 96. 不同的二叉搜索树

思路 观察树的组成&#xff0c;可以发现n3时的二叉搜索树可以由&#xff0c;头节点分别为1、2、3时的所有结果组成&#xff01;定义dp[i]为由i个节点组成的二叉搜索树的个数。确定递推公式&#xff0c;dp[i] 由1为头节点组成的二叉搜索树个数由2为头组成的个数…由i为头节点组…

Go 泛型之泛型约束

Go 泛型之泛型约束 文章目录 Go 泛型之泛型约束一、引入二、最宽松的约束&#xff1a;any三、支持比较操作的内置约束&#xff1a;comparable四、自定义约束五、类型集合&#xff08;type set&#xff09;六、简化版的约束形式七、约束的类型推断八、小结 一、引入 虽然泛型是…

等保测评里面,帐号和短信验证码双因子认证机制

短信验证参数检查过滤器 public class MultiTextMessageFilter implements Filter {private AntPathRequestMatcher matcher new AntPathRequestMatcher("/oauth/token");Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterC…

电脑亮度怎么调?揭开亮度调节的秘密!

电脑亮度调节是一项基本的系统设置&#xff0c;它不仅影响我们的视觉体验&#xff0c;还有助于减轻眼部疲劳。可是电脑亮度怎么调呢&#xff1f;本文将介绍三种不同的电脑亮度调节方法&#xff0c;适用于Windows和常见的笔记本电脑&#xff0c;让您的屏幕明亮如新。 方法1&…

数据库管理-第128期 2023总结(202301229)

数据库管理-第128期 2023总结&#xff08;202301229&#xff09; 到了2023年的最后一个工作日&#xff0c;也该对即将过去的2023年做一个小小的总结&#xff1a; 1 写文章 2023年在CSDN总共写了82篇文章。 2023年4月开始在墨天轮写文章&#xff0c;总共写了75篇文章&#xf…

构建高效数据流转的 ETL 系统:数据库 + Serverless 函数计算的最佳实践

作者&#xff1a;柳下 概述 随着企业规模和数据量的增长&#xff0c;数据的价值越来越受到重视。数据的变化和更新变得更加频繁和复杂&#xff0c;因此及时捕获和处理这些变化变得至关重要。为了满足这一需求&#xff0c;数据库 CDC&#xff08;Change Data Capture&#xff…

Python自动化办公指南

文章目录 前言文件处理数据处理网络爬虫自动化操作 如何开始Python自动化办公结论Python技术资源分享1、Python所有方向的学习路线2、学习软件3、入门学习视频4、实战案例5、清华编程大佬出品《漫画看学Python》6、Python副业兼职与全职路线 前言 Python自动化办公一般可以分为…

C实现数组奇数在前偶数在后排序

一、运行结果&#xff1b; 二、源码&#xff1b; # define _CRT_SECURE_NO_WARNINGS # include <stdio.h>//实现调整函数move_odd_even函数&#xff1b; void move_odd_even(int arr[], int sz) {//初始化变量值&#xff1b;int left 0;int right sz - 1;//循环判断和…

作业--day38

1.定义一个Person类&#xff0c;包含私有成员&#xff0c;int *age&#xff0c;string &name&#xff0c;一个Stu类&#xff0c;包含私有成员double *score&#xff0c;Person p1&#xff0c;写出Person类和Stu类的特殊成员函数&#xff0c;并写一个Stu的show函数&#xff…

安装 PyQt5 保姆级教程

作者&#xff1a;billy 版权声明&#xff1a;著作权归作者所有&#xff0c;商业转载请联系作者获得授权&#xff0c;非商业转载请注明出处 前言 博主之前做应用层开发用的一直是 Qt&#xff0c;这次尝试一下在 python 中使用 Pyqt5 模块来开发 UI 界面&#xff0c;这里做一些…

(JAVA)-(多线程)-线程池

线程池&#xff0c;顾名思义就是存放线程的池子&#xff0c;当有任务时能够随时取用线程&#xff0c;任务结束后能够放回线程池中。如果把线程比成碗&#xff0c;线程池就像一个碗柜一样。 使用线程池的好处&#xff1a; 1.当有大量线程对象时&#xff0c;减少了线程创建销毁…

获取拼多多商品详情页数据SKU价格等

拼多多根据ID取商品详情 API 返回值说明 item_get-根据ID取商品详情 pinduoduo.item_get 响应参数 请求测试链接 名称类型必须示例值描述 num_iid String01999629976商品ID title String02019新款女装短袖t恤女夏宽松韩版休闲上衣百搭蝙蝠衫五分袖体恤商品标题 price Flo…