Long类型后端传前端精度丢失的优雅解决方案

发布时间 2023-06-15 17:13:27作者: 推荐了再走

前言提要:javaScript 的最大安全值:Number.MAX_SAFE_INTEGER 是一个值为 9007199254740991 的常量,如果超过这个值,那么js会出现不精确问题

  • 解决方案(推荐级别:低等):修改字段类型为String
  • 解决方案(推荐级别:中等):字段上添加注解 @JsonFormat(shape = JsonFormat.Shape.STRING)
  • 解决方案(推荐级别:中等):字段上添加注解 @JsonSerialize(using = ToStringSerializer.class)
  • 解决方案(推荐级别:优等):全局设置
    精度丢失全局定义类:
    image
全局定义类代码,点击查看
package com.xqz.pms.handler;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.io.IOException;

/**
 * @author XueQiZheng
 * @date 2021/11/10
 *
 * 描述:jackson全局配置
 */
@Configuration
@Slf4j
public class JacksonCustomizerConfig {
    /**
     * 描述:统一配置类型的转换策略
     */
    @Bean
    public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() {
        return builder -> {
            /**
             * 将ID为Long类型转换成string类型返回,避免Long类型ID传前端后精度丢失的问题
             */
            JsonSerializer<Long> serializer = new JsonSerializer<Long>() {

                @Override
                public void serialize(Long value, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
                    //如果项目中有Long类型有特殊使用场景,可以在这里做区分,超过精度的才转为String
//                    if (Objects.nonNull(value) && value >= 9007199254740991L) {
//                        log.info("Jackson2ObjectMapperBuilderCustomizer value ={}", value);
                        jsonGenerator.writeString(value.toString());
//                    } else {
//                        jsonGenerator.writeNumber(value);
//                    }
                }
            };
            builder.serializerByType(Long.class, serializer);
        };
    }
}

精度丢失注解方案:
image