在 Java 后端开发中,可能会遇到前后端交互过程中 Long 类型精度丢失的问题。尤其是在 JavaScript 中,由于其 Number 类型是双精度浮点数,超过 16 位的 Long 类型值就会发生精度丢失。
问题背景
假设有如下实体类:
public class TemplateValue implements Serializable {
private Long colHeadId;
private Long rowHeadId;
private String val1;
private String val2;
}
这在后端没有问题,但如果前端直接接收这个数据,colHeadId
和 rowHeadId
可能会在 JS 中出现精度问题,比如:
{
"colHeadId": 1234567890123456789
}
1234567890123456770 // 精度丢失!
解决方案:Long 类型转 String 传给前端
为了解决这个问题,我们需要在序列化时将 Long 类型转成 String,即使用:
@JsonSerialize(using = ToStringSerializer.class)
同时,前端传来的 String 要转回 Long 怎么办?
这就是本文的重点!序列化做了,反序列化没做,就会出现类型转换失败或数据无法接收的问题。
那么我们需要自定义一个反序列化器,将前端传来的 String 自动转成 Long 类型。
实现步骤
1.创建自定义反序列化器 ToLongDeserializer
可以放在工具类里
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. 在实体类上使用序列化 & 反序列化注解
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,创建自定义反序列化器,确保后端能正常接收