Long类型的数据,后端传给前端产生的精度丢失问题

问题出现

后端的Java Bean的id属性是用的Long类型对应数据库主键使用bigint类型,当使用JSON方式传递该数据给前端时,前端接收到的数据末尾会变成0。(发生的精度丢失问题)

问题原因

Java中的long能表示的范围比js中number大,也就意味着部分数值在js中存不下(变成不准确的值),导致Id最后几位直接变成了0。

解决方案

将后端的id变成字符串类型,前端以字符串的方式接收就不会有精度丢失

方案一:Jackson

单个配置

在Long类型字段上加序列化注解

@JsonSerialize(using = ToStringSerializer.class)
private Long 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.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;

@Configuration
public class JacksonConfig {
     @Bean
     @Primary
     @ConditionalOnMissingBean(ObjectMapper.class)
     public ObjectMapper jacksonObjectMapper(Jackson2ObjectMapperBuilder builder) {
         ObjectMapper objectMapper = builder.createXmlMapper(false).build();
         SimpleModule simpleModule = new SimpleModule();
         //Long类型----String
         simpleModule.addSerializer(Long.class, ToStringSerializer.instance);
         objectMapper.registerModule(simpleModule);
         return objectMapper;
    }
}

方案二:FastJSON

单个配置

在Long类型字段上加注解Long转String

@JSONField(serializeUsing = ToStringSerializer.class)
private Long userId;

统一配置

通过重写WebMvcConfigurer中的configureMessageConverters方法来重新配置转换器

import com.alibaba.fastjson.serializer.SerializeConfig;
import com.alibaba.fastjson.serializer.ToStringSerializer;
import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class CustomFastJsonConfig {
    @Bean
    FastJsonHttpMessageConverter fastJsonHttpMessageConverter() {
        //1.需要定义一个convert转换消息的对象
        FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter();

        //2.添加fastJson的配置信息
        FastJsonConfig fastJsonConfig = new FastJsonConfig();
        //3.设置Long为字符串
        SerializeConfig serializeConfig = SerializeConfig.globalInstance;
        serializeConfig.put(Long.class, ToStringSerializer.instance);
        serializeConfig.put(Long.TYPE, ToStringSerializer.instance);
        fastJsonConfig.setSerializeConfig(serializeConfig);

        //4.在convert中添加配置信息.
        converter.setFastJsonConfig(fastJsonConfig);
        return converter;
    }
}

后端返回的数据,只要是Long类型的字段,都会被转成String返回,导致扩大了转换范围,不过可以解决所有long类型带来的问题。

注意点

单个属性配置注解的时候:

  • FastJSON使用FastJSON下的ToStringSerializer
  • Jackson使用Jackson下的ToStringSerializer

你可能感兴趣的:(Bug,java,前端)