记一次JSON.toJSONString()转换时非属性方法空指针异常排查及toJSONString保留null值属性

记一次JSON.toJSONString()转换时非属性方法空指针异常排查及toJSONString保留null值属性

异常详情

有一个类,里面有两个属性和一个类似工具的getRealName()方法如下:

getRealName()方法就是获取这个人的真实名字,如果获取不到就以name返回

class JSONTest {String name;String age;public String getName() {return name;}public void setName(String name) {this.name = name;}public String getAge() {return age;}public void setAge(String age) {this.age = age;}public String getRealName() {try {return "real" + this.name.substring(0, 1);} catch (Exception e) {e.printStackTrace();}return this.name;}}

然后Controller中有两个url使用了这个类,并转成JSONString返回。下面就以两个方法模仿这两个url。

public class JsonMainTest {public static void main(String[] args) throws Exception {System.out.println(method01());System.out.println(method02());}static String method01() {JSONTest jsonTest = new JSONTest();jsonTest.setName("lowkey");jsonTest.setAge("18");jsonTest.setName(jsonTest.getRealName());return JSON.toJSONString(jsonTest);}static String method02() {JSONTest jsonTest = new JSONTest();jsonTest.setAge("18");return JSON.toJSONString(jsonTest);}
}

接下来运行这个main方法,可以看到第二个方法报错了

在这里插入图片描述

异常原因

一开始很好奇为什么会异常,因为空指针,name为空了,但是我method02方法并没有调用getRealName(),为什么会调用了它,并空指针了呢。

后面细究发现是因为JSON.toJSONString()的时候是根据getter方法进行的,也就是下面这行
在这里插入图片描述

它会把所有符合以get开头的方法拿出来然后把它转成属性进行设置,所有他会在转method02方法的时候调用了getRealName()方法,而method02方法中name并没有设置值,所有才出现了空指针异常。在过程中还发现它会扫描以is开头的方法。

从打印的JSONString串也可以看出,我的属性里面并没有realName属性它却打印了出来。

解决方案

  • 第一种

    就是规范命名,与类属性无关的方法不要以get/is开头,向我这个类里面getRealName只是将name进行了处理,并不是作为一个类属性使用,所以我们将该方法改成handleRealName()或者其他即可。如下所示:再次运行便正常了,打印中也没有除属性外的字段。

    public class JsonMainTest {public static void main(String[] args) throws Exception {System.out.println(method01());System.out.println(method02());}static String method01() {JSONTest jsonTest = new JSONTest();jsonTest.setName("lowkey");jsonTest.setAge("18");jsonTest.setName(jsonTest.handletRealName());return JSON.toJSONString(jsonTest);}static String method02() {JSONTest jsonTest = new JSONTest();jsonTest.setAge("18");return JSON.toJSONString(jsonTest);}
    }class JSONTest {String name;String age;public String getName() {return name;}public void setName(String name) {this.name = name;}public String getAge() {return age;}public void setAge(String age) {this.age = age;}public String handletRealName() {try {return "real" + this.name.substring(0, 1);} catch (Exception e) {e.printStackTrace();}return this.name;}
    }
    
  • 第二种

    忽略JSON转换,即在进行JSON.toJSONString的时候忽略getRealName方法。在方法上添加@JSONField(serialize = false)注解,如下所示:

    public class JsonMainTest {public static void main(String[] args) throws Exception {System.out.println(method01());System.out.println(method02());}static String method01() {JSONTest jsonTest = new JSONTest();jsonTest.setName("lowkey");jsonTest.setAge("18");jsonTest.setName(jsonTest.getRealName());return JSON.toJSONString(jsonTest);}static String method02() {JSONTest jsonTest = new JSONTest();jsonTest.setAge("18");return JSON.toJSONString(jsonTest);}
    }class JSONTest {String name;String age;public String getName() {return name;}public void setName(String name) {this.name = name;}public String getAge() {return age;}public void setAge(String age) {this.age = age;}@JSONField(serialize = false)public String getRealName() {try {return "real" + this.name.substring(0, 1);} catch (Exception e) {e.printStackTrace();}return this.name;}
    }
    
  • 不过建议还是规范命名

其他问题:空属性不打印的情况

我们还会发现为空的属性,toJSONStirng的时候不打印。我们可以使用时添加SerializerFeature.WriteMapNullValue属性:

JSON.toJSONString(jsonTest, SerializerFeature.WriteMapNullValue);

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

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

相关文章

堆的介绍,实现,使用(c语言实现)

目录 堆的概念 堆的性质: 堆的分类 父子结点的下标关系 堆的向下调整算法 ​编辑小堆 大堆 建堆 堆的向上调整算法 小堆 大堆 堆的基本操作 定义堆 初始化堆 销毁堆 打印堆 堆的插入 堆的删除 大堆(Max Heap)的向下调整算法…

jadx反编译apk

ref:https://github.com/skylot/jadx jadx是一款反编译利器,同时支持命令行和图形界面,能以最简便的方式完成apk的反编译操作。 安装: 1.windos: https://github.com/skylot/jadx/releases/tag/v1.2.0 下载jadx-1.…

Java 设计模式(上)

目录 一、单一职责原则 二、开闭原则 三、里氏替换原则 四、迪米特法则 五、接口隔离原则 六、依赖倒置原则 七、工厂方法 八、抽象工厂 九、建造者模式 十、原型模式 十一、单例模式 十二、适配器模式 一、单一职责原则 单一职责原则又称单一功能原则,…

【Redis 开发】分布式锁中的常见问题和Lua脚本

分布式锁中的问题 分布式锁中我们设置的过期时间: 如果有一个线程获取锁之后在进行操作时,到达了锁的过期时间,之后就会有别的线程获得锁,如果这时,第一个线程执行完成后释放锁,就会将第二个锁的线程删除 …

回溯-单词搜索

给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中,返回 true ;否则,返回 false 。 单词必须按照字母顺序,通过相邻的单元格内的字母构成,其中“相邻”单元格是那些水平相邻或垂直相…

SpringMVC深解--一起学习吧之架构

SpringMVC的工作原理主要基于请求驱动,它采用了前端控制器模式来进行设计。以下是SpringMVC工作原理的详细解释: 请求接收与分发: 当用户发送一个请求到Web服务器时,这个请求首先会被SpringMVC的前端控制器(Dispatche…

关于远程桌面端口的优化措施的建议

在信息技术的世界中,远程桌面连接已成为企业、教育和个人用户之间共享信息、协作工作的重要工具。而这一切的背后,都离不开远程桌面端口(RDP,Remote Desktop Protocol Port)的支持。RDP端口不仅关乎到远程访问的顺畅性…

自然语言处理的发展及归纳介绍

NLP简介 自然语言处理(Natural Language Processing,NLP)是人工智能领域的一个重要分支,旨在使计算机理解、解释和生成人类语言。NLP的产生背景可以追溯到上世纪50年代,随着计算机科学和人工智能领域的发展&#xff0c…

ABAP MR21: BAPI_MATVAL_PRICE_CHANGE

文章目录 前言 一、报错问题 二、代码如下 总结 前言 MR21 发布物料价格,BAPI_MATVAL_PRICE_CHANGE 一、报错问题 BAPI报错:估价XXX 对于物料XXXXXXXXXXXXX没有被维护 解决办法:CKML_PRICE_SEND没有对应的评估范围数据,SM30&a…

问题解答2024年4月28日

import java.util.ArrayList; import java.util.List; import java.util.Stack;//现有数据库里保存有行政区数据, 一个行政区是一行数据,包括行政区id,行政区名称,行政区父id。 比如: // //行政区ID, 行政区名称&…

【Linux】进程信号 -- 详解

⚪前言 注意:进程间通信中的信号量跟下面要讲的信号没有任何关系。 一、从不同角度理解信号 1、生活角度的信号 你在网上买了很多件商品,在等待不同商品快递的到来。但即便快递没有到来,你也知道快递来临时,你该怎么处理快递&a…

CDA认证:数据行业领跑者,告别危机和低谷!

近日,人力资源社会保障部、中央组织部、中央网信办、国家发展改革委、教育部、科技部、工业和信息化部、财政部、国家数据局等九部门印发《加快数字人才培育支撑数字经济发展行动方案(2024—2026年)》(以下简称《行动方案》&#…

LeetCode39题: 组合总和(原创)

【题目描述】 给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target ,找出 candidates 中可以使数字和为目标数 target 的 所有 不同组合 ,并以列表形式返回。你可以按 任意顺序 返回这些组合。candidates 中的 同一个 数字可以 无限制重复…

[NISACTF 2022]bilala的二维码

​​​​​​​NSSCTF{M0RS34ND282X231} 还有一个是像素我找不到

Orange3数据可视化(树查看器-决策树)

树视图 分类和回归树的可视化。 输入 树:决策树 输出 选中的数据:从树节点中选中的实例 数据:带有额外一列,显示每个点是否被选中 这是一个多功能的小部件,用于展示分类和回归树的2D可视化。用户可以选择一个节点…

物联网五层架构:每一层都扮演着不可或缺的角色——青创智通

物联网五层架构涵盖了感知层、网络层、数据层、应用层和业务层,每一层都扮演着不可或缺的角色,共同构成了物联网的完整生态系统。下面我们将详细探讨这五层架构的功能和特点。 首先,感知层是物联网的起点,负责获取和识别各种物理世…

Es6和Es5的区别?

ES5和ES6都是JavaScript语言的版本,ES5在2009年发布,ES6在2015年发布,两者之间有以下的区别: 1、变量声明方式不同:ES5使用var关键字进行变量声明,而ES6则引入了let和const关键字来声明变量。 2、块级作用…

(泛型+栈+队列+可变不可变)的实现(java版)

文章目录 1. 介绍2. 代码实现2.1 普通的栈2.2 普通的循环队列2.3 泛型栈2.4 泛型循环队列2.5 泛型可变栈2.6 泛型可变队列2.7 部分测试 3. 参考链接 如果你之前没有了解过栈或者队列,可以看看本文最后的链接,里面很详细 1. 介绍 泛型,泛指一…

ssm项目后端如何导出war及前端如何导出静态资源

后端如何导出war包 后端工具:IDEA 2020.1.3 运行我们编写工具maven里面的package 运行成功的日志 我们运行完,会生成一个target文件夹,在这个文件夹里面找到war包即可 前端如何导出静态资源 使用工具:WebStorm 2020.1.3 打开左…

VUE3核心语法

💟💟前言 ​ 友友们大家好,我是你们的小王同学😗😗 今天给大家打来的是 VUE3核心语法 希望能给大家带来有用的知识 觉得小王写的不错的话麻烦动动小手 点赞👍 收藏⭐ 评论📄 小王的主页&#xf…