一个极易踩坑的例子,希望大家引以为戒

news/2025/2/26 4:15:27/文章来源:https://www.cnblogs.com/wenbochang/p/18565021

前言

最近在写需求的过程中,需要返回给前端一个字段,表示账单是否结清,那么理所当然的我把这个字段命名为了isSettle

踩坑过程

明眼人一看就知道问题所在,非常经典的错误,当时聊天记录大概是这样的。

后端:这个字段一直显示错误,有空帮忙看下
前端:你这边返回的是settle,我看文档上是isSettle
后端:好的,我去看下文档
a few seconds later
后端:靠,有坑,我修改下

非常经典的错误,我当时一看就立马明白是序列化的问题。之前一直知道有这个坑,写的时候没太注意,差点酿成了大祸,这可是直接给用户看的,账单是否结清,非常重要的一个字段。

原理

在java的世界里,尤其是java web的世界里面。框架帮我们承担了一切,尤其是springboot的出现,更加降低了入门门槛。基本都是spring一把梭,上来就是spring全家桶。

这对打工人的确有好处,因为可以专心于业务,但是因为封装的太好了,导致现在很多人其实不清楚其中的原理,框架帮你做了什么,如果出了问题,你如何解决,这些都是培训班or应届生欠缺的,回归正题。

后端返回给前端,其中springmvc会帮我们将数据进行一个转换。具体的转化器是在这里MappingJackson2HttpMessageConverter。它是在springboot启动的时候,通过自动装配WebMvcAutoConfiguration就加载到spring容器中了,而其中默认使用的序列化就是jackson。

例子1

我现在有一个person类如下

@Data
public class Person {private int age;private String name;private boolean isSettle; // isxxx需注意
}

使用主流的json转化器如下

Person person = new Person();
person.setAge(18);
person.setName("zhangsan");
person.setSettle(true);// 1. gson
System.out.println("gson -->  " + GsonUtils.toJson(person));// 2. fastjson
System.out.println("fastjson -->  " + JSON.toJSONString(person));// 3. fastjson2
System.out.println("fastjson2 -->  " + com.alibaba.fastjson2.JSON.toJSONString(person));// 4. jackson
ObjectMapper objectMapper = new ObjectMapper();
System.out.println("jackson -->  " + objectMapper.writeValueAsString(person));

结果如下。我们发觉除了gson是以isXxx输出,其他的全部把is给默认去掉了

gson -->  {"age":18,"name":"zhangsan","isSettle":true}
fastjson -->  {"age":18,"name":"zhangsan","settle":true}
fastjson2 -->  {"age":18,"name":"zhangsan","settle":true}
jackson -->  {"age":18,"name":"zhangsan","settle":true}

例子2

我们尝试去修改springmvc的序列化转换器。非常简单,修改MessageConverters即可。
其中PrettyPrinting是为了更加方便看出修改gson已经成功了

@Configuration
public class MessageConverterConfig implements WebMvcConfigurer {@Overridepublic void configureMessageConverters(List<HttpMessageConverter<?>> converters) {converters.clear();  // 移除jackson,或者在pom中完全排除jacksonGsonHttpMessageConverter gsonConverter = new GsonHttpMessageConverter();gsonConverter.setGson(new GsonBuilder().setPrettyPrinting().create()); // setPrettyPrinting 明确可以看出使用了gsonconverters.add(gsonConverter);}
}

我们现在有一个controller接口如下

@RequestMapping("/test/message")
public Person test() {Person person = new Person();person.setAge(18);person.setName("zhangsan");person.setOk(true);return person;
}

结果如下。发觉boolean isOk的值返回完全不同了,一个是有is,一个是没有is的,符合我们的预期

默认jackson的输入  --> {"name":"zhangsan","age":18,"ok":true}修改成gson转换器的输出 -->  
{"name": "zhangsan","age": 18,"isOk": true
}

最后

这是一个非常非常简单基础的例子,其实稍微有点经验的程序员都应该避免,只是有时候大意疏忽会导致各种各样的问题。本质上我还是想提醒大家,虽然框架帮助我们做了很多,但我们还是需要理解其底层实现原理,每当出现问题的时候,如果你懂原理,非常容易的可以快速解决问题,这也是高级程序员和码农的一个区别吧。其中在阿里的规约里面,已经明确禁止使用isxxx这种命名方式。

最后祝所有程序员,写的代码无bug,世界上不再有bug出现。

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

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

相关文章

学期:2024-2025-1 学号:20241303 《计算机基础与程序设计》第九周学习总结

作业信息这个作业属于哪个课程 <班级的链接>(如2024-2025-1-计算机基础与程序设计)这个作业要求在哪里 <作业要求的链接>(如2024-2025-1计算机基础与程序设计第九周作业)这个作业的目标 <写上具体方面> 计算机科学概论(第七版)第10,11章 并完成云班课测…

Java大作业4-6次总结性BLOG

前言本次BLOG由第4到6次的大作业答题判题程序- 4、家居强电电路模拟程序- 1和家居强电电路模拟程序 -2组成,其中答题判断程序-4由前三次迭代升级而来,涉及到填空题、单选题、多选题等多种题目的存储计算和判分逻辑。家居强电电路模拟程序为新的题目集,家居强电电路模拟程序1…

对于答题判断程序-4以及家居强电电路模拟程序1-2的总结性Blog

一、前言相关知识点:1、答题判断程序-4在前面答题判断程序-3的基础上增加了更多的输入格式判断以及对于边界条件情况的处理,对于面对对象编程的概念进一步的深化了。2、家居强电电路模拟程序-1从此次的大作业开始使用了抽象类的继承,以及对于电路中相关数据的计算进行了模拟…

答题判题程序终章与家居强电电路模拟程序

题目要求1.设计实现答题程序,模拟一个小型的测试,要求输入题目信息、试卷信息、答题信息、学生信息、删除题目信息,根据输入题目信息中的标准答案判断答题的结果 家居强电电路模拟程序2.智能家居是在当下家庭中越来越流行的一种配置方案,它通过物联网技术将家中的各种设备(…

题目4 - 6 总结

一、前言 在完成题目集 4 - 6 的编程实践过程中,经历了一系列从基础数据处理到较为复杂的电路设备模拟及分析等不同层次的任务挑战,每一次的题目集都犹如一次知识与技能的深度探索之旅,不仅拓宽了知识面,更在编程思维与实践能力方面得到了显著的提升。 (一)知识点覆盖 题…

02在ubuntu18.04上面搭建python环境

一、安装python3.6 # 1、python版本 python3.6 (1)更新包列表 sudo apt-get update (2)更新已安装的包 sudo apt-get upgrade 这里会显示无法获得锁---(问题1),解决之后系统提示“您希望继续执行吗?输入y” 这个命令执行时间有点久需要耐心等待。 (3)安装python3.6 sud…

Blog-2 题目集4~6的总结

22207203-陈思思 一、 前言 (一) 第4次题目集(答题判题程序4)知识点主要是类与对象、继承与多态、集合、正则表达式、业务逻辑的处理和设计模式的初步应用等。定义了多个类,每个类都进行了封装。集合方面,使用了 Map来存储问题、考试卷和学生信息,通过键值对快速访问;使…

MySQL原理简介—1.SQL的执行流程

大纲(2426字) 1.MySQL驱动的作用 2.Java系统中的数据库连接池的作用 3.MySQL中的数据库连接池的作用 4.网络连接必须让线程来处理 5.SQL接口会负责处理接收到的SQL语句 6.查询解析器会让MySQL读懂SQL语句 7.查询优化器会选择最优的查询路径 8.调用存储引擎接口来真正执行SQL语句…

22207203-陈思思

** Blog-2 题目集4~6的总结** 一、 前言 (一) 第4次题目集(答题判题程序4)知识点主要是类与对象、继承与多态、集合、正则表达式、业务逻辑的处理和设计模式的初步应用等。定义了多个类,每个类都进行了封装。集合方面,使用了 Map来存储问题、考试卷和学生信息,通过键值对…

2024-2025-1 20241403 《计算机基础与程序设计》第九周学习总结

2024-2025-1 20241403 《计算机基础与程序设计》第九周学习总结 作业信息这个作业属于哪个课程 <班级的链接>(2024-2025-1-计算机基础与程序设计)这个作业要求在哪里 <作业要求的链接>(2024-2025-1计算机基础与程序设计第九周作业)这个作业的目标 操作系统责任 内…

OOP实验四

任务2: 源码:1 #include <iostream>2 #include <vector>3 #include <string>4 #include <algorithm>5 #include <numeric>6 #include <iomanip>7 8 using std::vector;9 using std::string;10 using std::cin;11 using std::cout;12 usi…

【淘汰9成NLP面试者的高频面题】RNN是如何基于时间进行参数学习(BPTT)的?

【淘汰9成NLP面试者的高频面题】RNN是如何基于时间进行参数学习(BPTT)的? 重要性:★★ 本【淘汰9成NLP面试者的高频面题】RNN是如何基于时间进行参数学习(BPTT)的? 重要性:★★本问题主要考察面试者有有以下几点:① 理解RNN循环的概念,认识到截断的 BPTT的必要性 ② …