前言

最近在写评论插件时,id使用雪花算法生成(Long),结果传递到前端时发现id最后几位精度丢失全变成了0。

后面经过几番排查后发现前端能够接收的数字最多只能是16位,所以会造成精度丢失。

图片

图片

可以看到后端传递的数据是没有任何问题的,但是接收时精度就丢失了。

在考虑到不改变业务结构的情况下,有两种解决方案。

方案一:自定义消息转换器

通过自定义消息转换器,将传递给前端的Long类型数据转换为String类型数据。

这个方法会将所有传到前端的Long类型转为String。

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
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.util.List;

@Configuration
public class DataConfig implements WebMvcConfigurer {

/**
* 将 Long类型数据转为String
* @param converters
*/
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
MappingJackson2HttpMessageConverter mJHttpMessageConverter = new MappingJackson2HttpMessageConverter();
ObjectMapper objectMapper = mJHttpMessageConverter.getObjectMapper();
SimpleModule simpleModule = new SimpleModule();
simpleModule.addSerializer(Long.class, ToStringSerializer.instance);
simpleModule.addSerializer(Long.TYPE, ToStringSerializer.instance);
objectMapper.registerModule(simpleModule);
mJHttpMessageConverter.setObjectMapper(objectMapper);
converters.add(0, mJHttpMessageConverter);
}

}

图片

可以看到前端接收的数据已经是正常显示了

方案二:注解

在需要转化的实体类属性加上注解。也可以实现和上面同样的效果。

比如id字段:

1
2
3
4
5
6
7
8
9
10
11
12
13
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import lombok.Data;

@Data
public class Comment {

@JsonSerialize(using = ToStringSerializer.class)
private Long id;

private String ahzoo;

}