JAVA中关于Long类型返回前端精度丢失问题处理办法
问题出现:
新项目将后端的Java Bean的id属性是用的Long类型对应数据库主键使用bigint类型,id改为雪花后出现的异常问题,比如id:1799633456368132098返回错误的id:1799633456368132000。导致明显问题数值精度丢失。后三位数值转换为0了。
问题原因:
Java中的long能表示的范围比js中number大,也就意味着部分数值在js中存不下(变成不准确的值),导致Id最后几位直接变成了0。
解决方案一
1、将后端id字段类型换位字符串类型,并且前端以字符串的方式接收就不会有精度丢失了。
2、单个字段注释,这只需要我们在需要转换的字段上增加@JsonSerialize(using=ToStringSerializer.class)注解
解决方案二
SpringBoot使用Jackson序列化方式
需要引入依赖 <dependency> <groupId>com.fasterxml.jackson.datatype</groupId> <artifactId>jackson-datatype-jsr310</artifactId> </dependency>
package com.znkj.nvm.common.config; import com.fasterxml.jackson.databind.ser.std.ToStringSerializer; import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; import lombok.extern.slf4j.Slf4j; import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.core.annotation.Order; import java.math.BigDecimal; import java.math.BigInteger; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.TimeZone; /** * jackson 配置 * 加载顺序:-10000 **/ @Slf4j @Order(-10000) @Configuration public class JacksonConfig { @Bean public Jackson2ObjectMapperBuilderCustomizer customizer() { return builder -> { // 全局配置序列化返回 JSON 处理 JavaTimeModule javaTimeModule = new JavaTimeModule(); javaTimeModule.addSerializer(Long.class, BigNumberSerializer.INSTANCE); javaTimeModule.addSerializer(Long.TYPE, BigNumberSerializer.INSTANCE); javaTimeModule.addSerializer(BigInteger.class, BigNumberSerializer.INSTANCE); javaTimeModule.addSerializer(BigDecimal.class, ToStringSerializer.instance); DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(formatter)); javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(formatter)); builder.modules(javaTimeModule); builder.timeZone(TimeZone.getDefault()); log.info("初始化 jackson 配置"); }; } }
package com.gyq.common.config; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.SerializerProvider; import com.fasterxml.jackson.databind.annotation.JacksonStdImpl; import com.fasterxml.jackson.databind.ser.std.NumberSerializer; import java.io.IOException; /** * 超出 JS 最大最小值 处理 **/ @JacksonStdImpl public class BigNumberSerializer extends NumberSerializer { /** * 根据 JS Number.MAX_SAFE_INTEGER 与 Number.MIN_SAFE_INTEGER 得来 */ private static final long MAX_SAFE_INTEGER = 9007199254740991L; private static final long MIN_SAFE_INTEGER = -9007199254740991L; /** * 提供实例 */ public static final BigNumberSerializer INSTANCE = new BigNumberSerializer(Number.class); public BigNumberSerializer(Class<? extends Number> rawType) { super(rawType); } @Override public void serialize(Number value, JsonGenerator gen, SerializerProvider provider) throws IOException { // 超出范围 序列化位字符串 if (value.longValue() > MIN_SAFE_INTEGER && value.longValue() < MAX_SAFE_INTEGER) { super.serialize(value, gen, provider); } else { gen.writeString(value.toString()); } } }
总结
到此这篇关于JAVA中关于Long类型返回前端精度丢失问题处理办法的文章就介绍到这了,更多相关JAVA Long类型返回前端精度丢失内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
相关文章
SpringSecurity自定义资源拦截规则及登录界面跳转问题
这篇文章主要介绍了SpringSecurity自定义资源拦截规则及登录界面跳转问题,我们想要自定义认证逻辑,就需要创建一些原来不存在的bean,这个时候就可以使@ConditionalOnMissingBean注解,本文给大家介绍的非常详细,需要的朋友参考下吧2023-12-12Java处理InterruptedException异常的理论与实践
在使用Java的过程中,有个情景或许很多人见过,您在编写一个测试程序,程序需要暂停一段时间,于是调用 Thread.sleep()。但是编译器或 IDE 报错说没有处理检查到的 InterruptedException。InterruptedException 是什么呢,为什么必须处理它?下面跟着小编一起来看看。2016-08-08使用@ConfigurationProperties实现类型安全的配置过程
这篇文章主要介绍了使用@ConfigurationProperties实现类型安全的配置过程,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教2023-02-02
最新评论