记一次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);

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

janus模块介绍-SIP Gateway

模块启动 默认的SIP GateWay也是https协议,端口为8088或者8089 如果需要在自己搭建的测试服务上测试SIP GateWay模块,则也需要修改为wss 具体改动如下: 找到/opt/janus/share/janus/demos/siptest.js var server "wss://" window.location…

Python与数据库连接

新建表boss create table 创建表 Code import pymysqlcon pymysql.connect(hostlocalhost,\userroot,\password,\port3306,\dbbusiness) cursorcon.cursor() cursor.execute(create table if not exists boss(id int auto_increment primary key,name varchar(20)not null…

打包的意义 作用等前端概念集合 webpack基础配置等

基础网页是什么? 在学校最基础的三剑客 原生JS CSS H5就可以开发静态网页了 对于浏览器而言也能识别这些基础的文件和语法,真正的所见即所得,非常直接。 为什么要使用框架库? 对于常用的前端框架而言,无论是Vue Rea…

什么样的内外网文档摆渡,可以实现安全高效传输?

内外网文档摆渡通常指的是在内网(公司或组织的内部网络)和外网(如互联网)之间安全地传输文件的过程。这个过程需要特别注意安全性,因为内网往往包含敏感数据,直接连接内网和外网可能会带来安全风险。因此会…

为什么深度学习模型在 GPU 上运行得更快:CUDA 编程简介

如今,当我们谈论深度学习时,通常会将其实现与利用 GPU 来提高性能联系起来。 GPU(图形处理单元)最初设计用于加速图像、2D 和 3D 图形的渲染。然而,由于它们能够执行许多并行操作,因此它们的实用性超出了深度学习等应用程序。 GPU 在深度学习模型中的使用始于 2000 年代…

保姆级银河麒麟V10高级服务器离线安装mysql5.7数据库

离线在银河麒麟高级操作系统v10安装mysql5.7 下载mysql5.7 MySQL :: Download MySQL Community Server (Archived Versions) 2、把下载好的包上传到服务器 3、解压 [root1-0001 ~]# cd /data/mysql[root1-0001 mysql]# tar -zxvf mysql-5.7.44-linux-glibc2.12-x86_64.tar.gz…

Beego框架学习:深入指南

文章目录 Beego框架学习:深入指南安装与设置创建控制器自定义路由使用中间件使用模板引擎使用ORM Beego框架学习:深入指南 Beego是一个快速开发Go语言应用的开源框架,它基于MVC模式设计,提供了一系列的工具和库,使得开…

C++ 之 string类的模拟实现

这学习我有三不学 昨天不学,因为昨天是个过去 明天不学,因为明天还是个未知数 今天不学,因为我们要活在当下,我就是玩嘿嘿~ –❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀–❀-正文开始-❀–❀–…

Docker基础学习(3.Docker架构)

⭐ 作者简介:码上言 ⭐ 代表教程:Spring Boot vue-element 开发个人博客项目实战教程 ⭐专栏内容:个人博客系统 ⭐我的文档网站:http://xyhwh-nav.cn/ ⭐微信公众号:码上言 文章目录 Docker基本概念1、镜像&…

JavaWeb-自学JSP组件报告

自学JSP组件报告 一、组件资源及作用 1. commons-fileupload-1.2.2.jar 组件作用:用于处理HTTP文件上传请求,提供了文件上传的解析和存储功能。它允许开发者在Web应用中轻松实现文件上传功能。 2. commons-io-2.4.jar 组件作用:提供了一…

springboot+vue新疆肉牛智慧牧场养殖系统

系统涉及的对象是奶牛。 系统使用员工有管理员和普通员工。 管理员有修改的权限,普通员工没有。 系统需要包含奶牛的编号,种类,体重,健康情况、生长情况、牛奶产量,以及上次更新数据时间等信息,管理员可以对…

Perfect Clear WorkBench 智能修图黑科技,你尽管拍剩下的交给我(v4.6.0.2653)

01 Perfect Clear Perfect Clear WorkBench是EyeQlmaging推出的先进图片处理工具,旨在自动优化和简化图像校正。它通过智能技术提高图片的清晰度、颜色保真度,并增强视觉效果,确保高品质输出。 它的核心优势是利用高级算法和AI技术&#xff…

第59篇:创建Nios II工程之控制LED<一>

Q:还记得第1篇吗?设计简单的逻辑电路,控制DE2-115开发板上LED的亮与熄灭,一行Verilog HDL的assign赋值语句即可实现。本期开始创建Nios II工程,用C语言代码控制DE2-115开发板上的LED实现流水灯效果。 A:在…

win下安装desktop及使用desktop安装k8s

1、下载desktop安装包 Docker Desktop: The #1 Containerization Tool for Developers | Docker 2、点击exe文件进行安装 3、安装完需要在启用或关闭windows功能中勾选如下三个选项 4、在desktop中配置Docker Engine { "registry-mirrors": [ "https:/…

Linux创建YUM仓库

在rhel-8.5中的/mnt/目录下是有AppStream和BaseOS这两个软件包的,里面有可安装的一些软件。 /mnt/BaseOS/Packages/ 普通安装 1.使用rpm命令安装(rpm -i 程序名称) 查看,已经有了这个程序(rpm -qa | grep 程序名&…

Footprint Analytics 与 GalaChain 达成战略合作

​ Footprint Analytics 宣布与 GalaChain 达成战略合作。GalaChain 是 Gala 旗下的 Layer 1 区块链。此次合作标志着双方在游戏(包括 Gala Games) 、娱乐和金融等多个行业的区块链生态系统革新方面迈出了重要的一步。 GalaChain 致力于满足企业级项目的广泛需求&…

【电路笔记】-Colpitts振荡器

Colpitts振荡器 文章目录 Colpitts振荡器1、概述2、基本Colpitts 振荡器电路3、示例14、使用运算放大器的Colpitts振荡器5、总结Colpitts 振荡器设计使用两个中心抽头电容器与并联电感器串联,形成产生正弦振荡的谐振储能电路。 1、概述 在许多方面,Colpitts 振荡器与我们在上…

GO语言写Prometheus自定义node-exporter的Docker容器测试

1. 安装docker-compose 执行以下命令,安装docker-compose到CentOS7.9环境中: # 下载二进制文件 sudo curl -L "https://github.com/docker/compose/releases/download/v2.24.7/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/d…

不懂就问!现货黄金和实物黄金如何选择?

近期金价大涨,很多投资者就将资金从股票等其他投资品种抽调出来,而投入到黄金市场中。然而,整个黄金投资市场中拥有这么多不同的黄金投资品种,像现货黄金和实物黄金,投资者根本不知道该选哪种,下面我们就来…

[数据结构]——排序——插入排序

目录 ​编辑 1 .插入排序 1.基本思想: 2.直接插入排序: ​编辑 1.代码实现 2.直接插入排序的特性总结: 3.希尔排序( 缩小增量排序 ) 1.预排序 2.预排序代码 3.希尔排序代码 4.希尔排序的特性总结: 1 .插入排序 1.基本思…