解决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,创建自定义反序列化器,确保后端能正常接收

相关推荐
阿桂有点桂20 小时前
React使用笔记(持续更新中)
前端·javascript·react.js·react
2301_8012522220 小时前
Tomcat的基本使用作用
java·tomcat
lkbhua莱克瓦2420 小时前
Java基础——常用算法3
java·数据结构·笔记·算法·github·排序算法·学习方法
麦麦鸡腿堡20 小时前
Java_TreeSet与TreeMap源码解读
java·开发语言
自由日记20 小时前
实例:跳动的心,火柴人
前端·css·css3
柯腾啊20 小时前
一文简单入门 Axios
前端·axios·apifox
教练、我想打篮球20 小时前
05 kafka 如何存储较大数据记录
java·kafka·record
uesowys20 小时前
华为OD算法开发指导-简易内存池
java·算法·华为od
gladiator+20 小时前
Java中的设计模式------策略设计模式
java·开发语言·设计模式
im_AMBER20 小时前
React 15
前端·javascript·笔记·学习·react.js·前端框架