Long型返回给前端精度丢失

前言

最近学习前端的过程中遇到过一些类型的问题,就是比如你默认声明的字符串类型,但是后面赋值的时候却给他赋值了各数字类型亦或者别的类型,就会出现不可预知的错误,而且能让你找半天找不出来问题,因为js不像java这种强类型语言,类型不对,编译都编译不过去,所以js中类型声明时一定要特别注意,不要随意赋值

问题

很多时候后端的主键或者ID用的是长整型的数字,位数在18位左右,例如1600783232689016833这样的数字,如果直接返回给前端Long型,前端是无法保证精度的,可能最终会变为这样1600783232689016800,这是因为它已经超出了js中数字所能表示的最大值,因此后端返回这样的数字时最好直接转换为string类型

解决

如果后端项目用的jackson,则需要添加如下配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(ObjectMapper.class)
@AutoConfigureBefore(JacksonAutoConfiguration.class)
public class JacksonConfiguration {

@Bean
@ConditionalOnMissingBean
public Jackson2ObjectMapperBuilderCustomizer customizer() {
return builder -> {
builder.locale(Locale.CHINA);
builder.timeZone(TimeZone.getTimeZone(ZoneId.systemDefault()));
builder.simpleDateFormat(DatePattern.NORM_DATETIME_PATTERN);
builder.serializerByType(Long.class, ToStringSerializer.instance);
builder.modules(new SirengineJavaTimeModule());
};
}

}

这是我项目中实际用过的,重点是builder.serializerByType(Long.class, ToStringSerializer.instance); 其他的是时间格式化的无需关注,这样做是全局的转换,所以配置后,实体类中正常使用Long型即可,无需改为string类型

如果后端项目中用的是fastjson,则需要以下配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@Configuration
public class SessionConfig implements WebMvcConfigurer{

@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
FastJsonHttpMessageConverter fastJsonConverter = new FastJsonHttpMessageConverter();
FastJsonConfig fjc = new FastJsonConfig();
/**
* 序列换成json时,将所有的long变成string
* 因为js中得数字类型不能包含所有的java long值
*/
SerializeConfig serializeConfig = SerializeConfig.globalInstance;
serializeConfig.put(Long.class , ToStringSerializer.instance);
serializeConfig.put(Long.TYPE , ToStringSerializer.instance);
fjc.setSerializeConfig(serializeConfig);
fastJsonConverter.setFastJsonConfig(fjc);
converters.add(fastJsonConverter);
}
}

如果只需要个别的Long型转为string类型,则可以使用注解@JSONField(serializeUsing = ToStringSerializer.class)在实体类Long型的字段上,一般最好使用全局的,尽量别用这个