记一次后台传递Long类型主键给前端导致精度损失的处理

原因

JavaScript的number的最大长度为9007199254740991,超出这个长度就会出现数据不精准的问题

想法

  • 后端修改字段的类型,把Long改成String

  • 后端在对应字段上添加注解@JsonSerialize(using = ToStringSerializer.class)(在序列化的过程中将字段将字段转为String,反序列化时转为Long)

  • 前端把数据类型进行转换

其中第二个想法的两种方式

  • 引入jackson,使用jackson自带的序列化类(方便)

     <!-- jacksond依赖 2.11.2-->
            <dependency>
                <groupId>com.fasterxml.jackson.core</groupId>
                <artifactId>jackson-databind</artifactId>
                <version>${jackson.version}</version>
            </dependency>
            <dependency>
                <groupId>com.fasterxml.jackson.core</groupId>
                <artifactId>jackson-annotations</artifactId>
                <version>${jackson.version}</version>
            </dependency>
    // 实体类加入序列化注解
    @JsonSerialize(using = ToStringSerializer.class)
    private Long pkUsed;
    
  • 手工写序列化类(特殊的转化可以这样做)

    //反序列化
    public class LongJsonDeserializer extends JsonDeserializer<Long> {
        private static final Logger log = 
        LoggerFactory.getLogger(LongJsonDeserializer.class);
        @Override
        public Long deserialize(JsonParser jsonParser, DeserializationContext 
         deserializationContext) throws IOException, JsonProcessingException {
            String value = jsonParser.getText();
            try {
                return value == null ? null : Long.parseLong(value);
            } catch (NumberFormatException e) {
                log.error("解析长整形错误", e);
                return null;
            }
        }
    }
    // 序列化
    public class LongJsonSerializer extends JsonSerializer<Long> {
        @Override
        public void serialize(Long value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
            String text = (value == null ? null : String.valueOf(value));
            if (text != null) {
                gen.writeString(text);
            }
        }
    }
    // 实体类增加注解 
     @JsonSerialize(using = LongJsonSerializer.class)
     @JsonDeserialize(using = LongJsonDeserializer.class)
     private Long pkUsed;
    

    另一种方式:https://blog.csdn.net/qq_45454550/article/details/107887442(待验证)

posted @ 2021-04-22 15:36  不忘初心V  阅读(337)  评论(0)    收藏  举报