JavaScript 无法存储 Java Long 类型数据问题

本文讲述了在前后端交互过程中,由于JavaScript无法存储Java中的Long类型数据,导致前端传递的数值错误。问题表现为前端提交的镜像val值不正确。解决方案是后端在序列化JSON时将Long类型转换为字符串,确保数据准确传递。

问题描述

今天在解决一个需求问题的时候,遇到了一个难得一见的 JS 问题。这个问题大概是和一些同学在开发环境使用 == 来比较包装类型的整数一样,由于比较的数值在缓存范围内,因缘际会的错过了 bug 的出现。

简单说一下问题经过,是这样的,笔者这个需求最终要求接口返回一组自定义结构的 k-v (不是单纯的键值对)数据,用于在前端表单中进行分类展示。

后端响应的数据结构类似如下:

{
    "code": 200, 
    "errorMsg": "", 
    "result": [
        {
            "extend": null, 
            "items": [
                {
                    "extend": null, 
                    "key": "CentOS 8.1 64位", 
                    "val": 8014753905961037835
                }, 
                {
                    "extend": null, 
                    "key": "CentOS 8.0 64位", 
                    "val": 8014753905961037838
                }, 
            ], 
            "key": "CentOS", 
            "pubProperty": "", 
            "val": 14
        }, 
        {
            "extend": null, 
            "items": [
                {
                    "extend": null, 
                    "key": "RedHat Enterprise Linux 8.0 64位", 
                    "val": 7979917486755315712
                }, 
                {
                    "extend": null, 
                    "key": "RedHat Enterprise Linux 7.7 64位", 
                    "val": 8014753905961037829
                }
            ], 
            "key": "Redhat", 
            "pubProperty": "", 
            "val": 5
        }
    ], 
    "success": true
}

在前端表单中的展示效果大概如下:

在这里插入图片描述

原因分析

笔者相信各位同学都应该猜得到,当提交表单的时候,前端肯定会把选中的镜像的 val 值传递给后端,然后由后端继续进行处理。

但是就在这个环节,由前端传给后端的 val 值竟然错了,例如:当选中了 CentOS 8.1 64 位这个镜像时,本该传递的 val 值为 8014753905961037835,实际传递的却是: 8014753905961038000。

后端接口测试的响应数据没问题,那问题显然就是出在前端了。

最终,配合前端开发定位这个问题的原因是因为: JavaScript 中无法存储 Java 中的 Long 类型数据,当位数超过 JavaScript 整数存储的范围,就会以0来代替了。

在这里插入图片描述

解决方案

JavaScript 存储不了就存储不了吧,咱们这个需求还得解决啊,最终的解决方法就是将后端响应回来的 Long 类型数据转换为字符串。

// 在序列化为 JSON 时将该字段转换为 String 类型
@JsonFormat(shape = JsonFormat.Shape.STRING)
private Long val;

后端响应的数据结构类似如下:

{
    "code": 200, 
    "errorMsg": "", 
    "result": [
        {
            "extend": null, 
            "items": [
                {
                    "extend": null, 
                    "key": "CentOS 8.1 64位", 
                    "val": "8014753905961037835"
                }, 
                {
                    "extend": null, 
                    "key": "CentOS 8.0 64位", 
                    "val": "8014753905961037838"
                }, 
            ], 
            "key": "CentOS", 
            "pubProperty": "", 
            "val": 14
        }, 
        {
            "extend": null, 
            "items": [
                {
                    "extend": null, 
                    "key": "RedHat Enterprise Linux 8.0 64位", 
                    "val": "7979917486755315712"
                }, 
                {
                    "extend": null, 
                    "key": "RedHat Enterprise Linux 7.7 64位", 
                    "val": "8014753905961037829"
                }
            ], 
            "key": "Redhat", 
            "pubProperty": "", 
            "val": 5
        }
    ], 
    "success": true
}
### Java 数据类型的分类 Java 中的数据类型可以分为 **基本数据类型** 和 **引用数据类型** 两类。 #### 基本数据类型 Java 的基本数据类型共有八种,具体如下: - `byte`:8位有符号整数,取值范围为 -128 到 127[^3]。 - `short`:16位有符号整数,取值范围更大于 `byte`[^2]。 - `int`:32位有符号整数,适用于大多数场景下的整型变量声明。 - `long`:64位有符号整数,用于存储更大的整数值。 - `float`:单精度浮点数,适合表示较小的小数范围。 - `double`:双精度浮点数,具有更高的精确度和更广的取值范围,通常推荐使用此类型来处理小数。 - `char`:16位Unicode字符,用于表示单一字符。 - `boolean`:逻辑值类型,只有两个可能的值:`true` 或 `false`。 以下是展示部分基本数据类型的简单代码示例: ```java public class BasicTypes { public static void main(String[] args) { byte b = 10; short s = 30000; int i = 1_000_000; long l = 9_223_372_036_854_775_807L; float f = 3.14f; double d = 3.141592653589793; char c = 'A'; boolean flag = true; System.out.println(b); System.out.println(f); System.out.println(c); System.out.println(flag); } } ``` #### 引用数据类型 引用数据类型主要包括但不限于以下几种: - **类 (Class)**:通过自定义类创建的对象实例属于此类。例如,在 Java 中可以通过 `new` 关键字创建对象。 - **接口 (Interface)**:一种抽象类型,允许实现多继承的功能。 - **数组 (Array)**:用来存储相同类型的一组固定数量的元素。 - **字符串 (String)**:是一种特殊的引用类型,代表不可变的字符序列。例如,下面展示了如何初始化并打印一个字符串[^1]: ```java public class StringTypeExample { public static void main(String[] args) { String str = "hello Java world"; System.out.println(str); } } ``` - **枚举类型 (Enum)**:用于定义一组固定的常量集合。 - **注解类型 (Annotation)**:提供元数据功能,影响程序运行方式或编译行为。 另外需要注意的是,虽然题目提到关于 JavaScript DOM 节点 (`Node`) 类型的内容[^4],但这并不属于标准 Java 数据类型范畴,而是 Web 开发领域的一部分。 ### 总结 综上所述,Java 提供了丰富的数据类型支持开发者构建各种复杂的应用程序。其中既包含了高效简洁的基本数据类型也涵盖了灵活强大的引用数据类型
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

查尔斯-BUG万象集

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值