关于后端传入Long类型id,导致long精度丢失

本文介绍了一种解决SpringBoot应用中CID长整型数据转换为字符串的问题,通过自定义配置类实现数据格式化,确保CID数据完整显示。

问题出现如下:

可以看出cid后面几位缺失。

解决方案如下:

SpringBoot加入如下代码配置:

@EnableWebMvc
@Configuration
public class WebJsonConverterConfig extends WebMvcConfigurerAdapter {
    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        MappingJackson2HttpMessageConverter jackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter();
        ObjectMapper objectMapper = new ObjectMapper();
        SimpleModule simpleModule = new SimpleModule();
        simpleModule.addSerializer(Long.class, ToStringSerializer.instance);
        simpleModule.addSerializer(Long.TYPE, ToStringSerializer.instance);
        objectMapper.registerModule(simpleModule);
        jackson2HttpMessageConverter.setObjectMapper(objectMapper);
        converters.add(jackson2HttpMessageConverter);
    }
}

解决后:

在前后端数据交互过程中,当后端接收字段类型为 `Long`,而前端发送的是 JavaScript 中的 `number` 类型时,其兼容性主要取决于具体数值的大小以及传输格式。 JavaScript 的 `number` 类型采用双精度浮点数(64位)表示,其安全整数范围是 `-(2^53 - 1)` 到 `2^53 - 1`(即 `-9007199254740991` 到 `9007199254740991`)。在这个范围内的整数可以被精确表示和运算[^1]。然而,一旦超出该范围,就会出现精度丢失的问题,这在处理大整数(如数据库主键 ID)时尤为明显。 Java 中的 `Long` 类型为 64 位有符号整数,其取值范围比 JavaScript 的 `number` 更大,从 `-2^63` 到 `2^63 - 1`。因此,如果前端传入的数值超过 JavaScript 的安全整数范围,即使后端使用 `Long` 接收,也会在传输过程中发生精度丢失,从而导致错误的结果。 例如: - 如果前端发送 `9007199254740992`,这个数字已经超出了 JavaScript 的安全整数范围,实际接收到的可能不是预期值。 - 若后端期望接收一个 `Long` 类型的值用于唯一标识符(如数据库 ID),而前端仍以 `number` 形式传递,则在 ID 超过安全整数范围时将无法保证准确性。 为了确保兼容性和数据完整性,推荐以下做法: 1. **前端使用字符串传递大整数**:将大整数以字符串形式传输,避免因浮点数精度问题造成的数据丢失。 2. **后端配置 JSON 序列化器**:如引用中提到的,可以通过 `@JsonSerialize(using = ToStringSerializer.class)` 注解将 `Long` 类型序列化为字符串,确保前端接收到的也是字符串形式的大整数,从而规避精度问题[^2]。 3. **使用 `BigInt` 类型进行运算**:若前端需要对大整数执行计算,可使用 `BigInt` 类型,它支持任意长度的整数运算,但需注意 `BigInt` 不能与普通 `number` 混合运算,且在网络传输中仍需以字符串形式存在。 ### 示例代码 #### 后端实体类示例 ```java import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; public class UserDto { @JsonSerialize(using = ToStringSerializer.class) private Long id; // Getter and Setter public Long getId() { return id; } public void setId(Long id) { this.id = id; } } ``` #### 前端发送请求示例(使用 Axios) ```javascript axios.post('/api/user', { id: '9223372036854775807' }) // 使用字符串传递大整数 .then(response => { console.log(response.data); }); ``` 通过上述方式,可以有效解决前后端之间关于大整数的数据类型兼容性问题。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值