
如何处理long类型精度丢失问题
文章摘要
MxGPT
本文介绍了在使用 Vue2 和 Element-UI 开发前端项目的情况下,集成 Flowable 工作流引擎的解决方案。由于公司采购的源码是基于 Vue3、TypeScript 和 Element-Plus,需要将其改造成 Vue2。其中遇到了主键使用雪花算法导致前端接收到的 ID 值被四舍五入的问题。为了解决这个问题,提供了两种解决方案。
此内容根据文章生成,并经过人工审核,仅用于文章内容的解释与总结
投诉前言
由于项目原架构使用的是Vue2、Element-UI开发的前端,现在想集成Flowable工作流引擎,但公司采购的源码采用的是Vue3、TypeScript、Element-Plus,所以只能改造成Vue2,然后再使用
我的问题
主键使用的是雪花算法,长度有19位,前端接收到的id值会被四舍五入,导致数据无法正常被操作
这里分享两组值,分别是数据库存储的id和前端接收到的id值
数据库id值:1724983175923302401
前端id值:1724983175923302401
数据库id值:1724983439078129665
前端id值:1724983439078129700
从以上结果可以看出,数据被四舍五入了
问题分析
Number精度是16位(雪花ID是19位的),所以JS的Number数据类型导致的精度丢失。
解决方案
主要解决思路,还是把Long类型转换为String再传输,以下给出几种解决方案,主要针对不同应用场景
方案一(单个注解)
此方案适用于项目中有及个别字段需要处理,可以采用此种方案,如果项目中id全是雪花算法,此方案不推荐
1 |
|
方案二(全局配置)
Long类型的对象将会使用自定义的LongToStringSerializer进行序列化,将Long类型转换为字符串,从而避免在前端丢失精度的问题。
请确保你已经引入了正确的Jackson库,并且使用了相应的导入语句。
- 创建LongToStringSerializer类
1
2
3
4
5
6
7
8
9
10
11import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import java.io.IOException;
public class LongToStringSerializer extends JsonSerializer<Long> {
public void serialize(Long value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
gen.writeString(value.toString());
}
} - 创建JacksonConfig类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.MapperFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import java.text.SimpleDateFormat;
import java.util.TimeZone;
public class JacksonConfig {
public MappingJackson2HttpMessageConverter jackson2HttpMessageConverter() {
final Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
builder.serializationInclusion(JsonInclude.Include.NON_NULL);
final ObjectMapper objectMapper = builder.build();
SimpleModule simpleModule = new SimpleModule();
// Long 转为 String 防止 js 丢失精度
simpleModule.addSerializer(Long.class, new LongToStringSerializer());
objectMapper.registerModule(simpleModule);
// 忽略 transient 关键词属性
objectMapper.configure(MapperFeature.PROPAGATE_TRANSIENT_MARKER, true);
// 时区设置
objectMapper.setTimeZone(TimeZone.getTimeZone("GMT+8"));
objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
return new MappingJackson2HttpMessageConverter(objectMapper);
}
}
重启项目后,再查看前端id值,发现id值正常
- 感谢你赐予我前进的力量
打赏者名单
因为你们的支持让我意识到写文章的价值🙏
本文是原创文章,采用CC BY-NC-ND 4.0协议,完整转载请注明来自满心记
评论
匿名评论
隐私政策
✅ 你无需删除空行,直接评论以获取最佳展示效果