解决Long类型前端精度丢失和正常传回后端问题

在 Java 后端开发中,可能会遇到前后端交互过程中 Long 类型精度丢失的问题。尤其是在 JavaScript 中,由于其 Number 类型是双精度浮点数,超过 16 位的 Long 类型值就会发生精度丢失。

问题背景

假设有如下实体类:

java 复制代码
public class TemplateValue implements Serializable {
    private Long colHeadId;
    private Long rowHeadId;
    private String val1;
    private String val2;
}

这在后端没有问题,但如果前端直接接收这个数据,colHeadId rowHeadId 可能会在 JS 中出现精度问题,比如:

json 复制代码
{
  "colHeadId": 1234567890123456789
}
javascript 复制代码
1234567890123456770  // 精度丢失!

解决方案:Long 类型转 String 传给前端

为了解决这个问题,我们需要在序列化时将 Long 类型转成 String,即使用:

java 复制代码
@JsonSerialize(using = ToStringSerializer.class)

同时,前端传来的 String 要转回 Long 怎么办?

这就是本文的重点!序列化做了,反序列化没做,就会出现类型转换失败或数据无法接收的问题。

那么我们需要自定义一个反序列化器,将前端传来的 String 自动转成 Long 类型。

实现步骤

1.创建自定义反序列化器 ToLongDeserializer

可以放在工具类里

java 复制代码
package com.yourproject.util;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import java.io.IOException;

public class ToLongDeserializer extends JsonDeserializer<Long> {
    @Override
    public Long deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
        String value = p.getText();
        try {
            return value != null ? Long.parseLong(value) : null;
        } catch (NumberFormatException e) {
            throw new IOException("Invalid long value: " + value, e);
        }
    }
}
2. 在实体类上使用序列化 & 反序列化注解
java 复制代码
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import com.yourproject.util.ToLongDeserializer;

public class TemplateValue implements Serializable {
    @JsonSerialize(using = ToStringSerializer.class)
    @JsonDeserialize(using = ToLongDeserializer.class)
    private Long colHeadId;

    @JsonSerialize(using = ToStringSerializer.class)
    @JsonDeserialize(using = ToLongDeserializer.class)
    private Long rowHeadId;

    private String val1;
    private String val2;
}

这样,在前后端交互时就能做到:

  • 后端返回数据时将 Long -> String,避免精度丢失;

  • 后端接收前端数据时将 String -> Long,方便业务逻辑处理。

总结

前后端交互中,涉及 Long 类型字段时:

  • 必须序列化为 String,@JsonSerialize(using = ToStringSerializer.class),避免前端精度丢失

  • 如果需要将数据回传给后端,必须反序列化为 Long,创建自定义反序列化器,确保后端能正常接收

相关推荐
j***49561 分钟前
Spring Boot 各种事务操作实战(自动回滚、手动回滚、部分回滚)
java·数据库·spring boot
anyup2 分钟前
🔥牛逼!3分钟生成 5 套主题,还能一键切换暗黑模式!
前端·前端框架·uni-app
进击的明明2 分钟前
深入讨论前端开发中的跨域问题🤔
前端
保加利亚的风3 分钟前
【Java】Spring Boot Event事件驱动开发:使用 ApplicationEvent 实现解耦通信
java·驱动开发·spring boot
大怪v4 分钟前
【创世界01】头脑热一把,我要带你纯前端手搓虚拟世界💪!
javascript·css·html
正在走向自律6 分钟前
企业微信消息推送全链路实战:Java后端与Vue前端集成指南
前端·vue.js·企业微信·企业微信消息推送·官方企业微信
_一两风6 分钟前
《从一道“诡异”输出题,彻底搞懂 JavaScript 的作用域与执行上下文》
前端·ecmascript 6
lcc1879 分钟前
Vue3 CompositionAPI的优势
前端·vue.js
豆奶特浓612 分钟前
谢飞机勇闯Java面试:从内容社区的缓存一致性到AI Agent,这次能飞多高?
java·微服务·ai·面试·架构·缓存一致性·feed流
Pou光明13 分钟前
7_线程安全_线程间的内存可视性2缓存_内存屏障_读写排序
java·开发语言·缓存