目录
问题分析
Java Long 类型转为 JSON 时可能出现精度丢失的原因主要包括 JSON 的通用数字类型不指定位数大小以及JavaScript 存储大数字时的精度限制。
- JSON 的通用数字类型不指定位数大小:JSON 作为一种跨平台的数据交换格式,其数字类型是通用的,不指定位数大小。这意味着在将Java中的Long类型( 64位 有符号整数,范围从-9,223,372,036,854,775,808到9,223,372,036,854,775,807)序列化为 JSON 字符串时,如果数字超出了 JSON 能够精确表示的范围,就可能导致精度丢失。
- JavaScript 存储大数字时的精度限制:在 JavaScript 中,整数表达存在精度限制,最多能表达的数字位数为 15 位。当数字超过 15 位时,JavaScript会出现精度丢失问题,表现为数字被截断或以科学计数法表示。
- 例如,当 JavaScript 尝试表示一个超过 15位 的整数时,最后几位数字可能会变为0,导致精度丢失。
解决方案
- 局部设置:在 Java 对象中,可以为 Long 类型的字段添加
@JsonFormat(shape = JsonFormat.Shape.STRING)
注解,这样在序列化为 JSON 时,Long 类型会 被当作字符串处理,从而避免精度丢失问题。- 全局设置:在 Spring 框架中,可以通过配置
ObjectMapper
来设置全局的序列化行为,例如使用ToStringSerializer
来确保 Long 类型被序列化为字符串格式,或者在配置中添加自定义的序列化模块来处理 Long 类型的序列化。
问题实例
后端
前端
前端后端数据的 id 是对不上的!!!! 前端接收的数据中id后三位是不对的,出现了精度丢失。
解决方法:
添加一个全局配置
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import org.springframework.boot.jackson.JsonComponent;
import org.springframework.context.annotation.Bean;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
/**
* Spring MVC Json 配置
*
* @author lhd
*/
@JsonComponent
public class JsonConfig {
/**
* 添加 Long 转 json 精度丢失的配置
*/
@Bean
public ObjectMapper jacksonObjectMapper(Jackson2ObjectMapperBuilder builder) {
ObjectMapper objectMapper = builder.createXmlMapper(false).build();
SimpleModule module = new SimpleModule();
module.addSerializer(Long.class, ToStringSerializer.instance);
module.addSerializer(Long.TYPE, ToStringSerializer.instance);
objectMapper.registerModule(module);
return objectMapper;
}
}
前后端数据中的 id 对上了