问题描述

1
2
3
4
5
后端把Long类型的数据传给前端,前端可能会出现精度丢失的情况。
例如:201511200001725439这样一个Long类型的整数,
传给前端后会变成201511200001725440

js中的number类型是16位的,而雪花id是19

下图可以看出,输入的值超出安全值,可能会被js自动转化

3种jackason解决方式(前端再把String类型的19位数字传回服务端的时候,服务端还是接收long类型即可,这是Spring反序列化参数接收默认支持的行为)

重新注册ObjectMapper的Long类型序列化方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
@Configuration
public class LongClassMessageConverter implements InitializingBean {

@Resource
ObjectMapper objectMapper;

private SimpleModule getSimpleModule() {

SimpleModule simpleModule = new SimpleModule();
simpleModule.addSerializer(BigInteger.class, ToStringSerializer.instance);
simpleModule.addSerializer(Long.class, ToStringSerializer.instance);
// 对小写long的转换,约定与前端交互数据时,大Long全部转换成字符串
// simpleModule.addSerializer(Long.TYPE, ToStringSerializer.instance);
objectMapper.registerModule(simpleModule);
return simpleModule;
}


@Override
public void afterPropertiesSet() {
SimpleModule simpleModule = getSimpleModule();
objectMapper.registerModule(simpleModule);
}
}
  • 注解方式 @JsonFormat(shape = JsonFormat.Shape.STRING)

  • 重新构建Jackson序列化方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@Configuration
public class JacksonConfig {
/**
* Jackson全局转化long类型为String,解决jackson序列化时传入前端Long类型缺失精度问题
*/
@Bean
public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() {
Jackson2ObjectMapperBuilderCustomizer cunstomizer = new Jackson2ObjectMapperBuilderCustomizer() {
@Override
public void customize(Jackson2ObjectMapperBuilder jacksonObjectMapperBuilder) {
jacksonObjectMapperBuilder.serializerByType(BigInteger.class, ToStringSerializer.instance);
jacksonObjectMapperBuilder.serializerByType(Long.class, ToStringSerializer.instance);
// jacksonObjectMapperBuilder.serializerByType(Long.TYPE, ToStringSerializer.instance);
}
};
return cunstomizer;
}
}