背景

项目中采用springcloud Alibaba技术开发分布式系统,开发过程中采用雪花算法生成分布式Id,为Long类型,而Long类型返回给前端,会出现精度丢失问题。

接下来我们主要了解下,如何快速的处理精度丢失的问题

处理方法

第一种:实体Long类型属性上注解

可以直接在返回实体属性添加"@JsonSerialize(using = ToStringSerializer.class)"。

# 举个例子:比如说我们返回一个Student实体。 
@Data
public class Student {

    @JsonSerialize(using = ToStringSerializer.class)
    private Long id;
    
    private String name;
    
    private Integer sex;
}

这种方式缺点比较明显,分布式系统,几乎所有的id都为Long类型,我们都需要在id添加注解。而且当返回id集合时,这种方式并不适用。博主就是遇到这样的问题,才考虑了采用下面的方法。我们来详细下讲解下面的方法。

第二种:全局配置

通过@Configuration声明配置类,编写下面这段代码

package com.ruoyi.common.core.web.config;

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;

@Configuration
public class JacksonConfig {

    /**
     * 解决主键Long类型返回给页面时,页面精度丢失的问题,时间格式化返回
     */
    @Bean
    public ObjectMapper objectMapper() {
        ObjectMapper objectMapper = new ObjectMapper();
        SimpleModule simpleModule = new SimpleModule();
        simpleModule.addSerializer(Long.class, ToStringSerializer.instance)
                .addSerializer(Long.TYPE, ToStringSerializer.instance);
        objectMapper.registerModule(simpleModule);
        return objectMapper;
    }
}

这样配置后,工程会将所有的Long类型,都转换为String类型返回给前端。新的问题来了,部分Long类型的属性,前端不需要转换,比如分页器的total等,我们怎么办呢?继续往下看:

指定部分Long类型属性在返回前端不转化String

我们先自定义一个序列化器

package com.ruoyi.common.core.web.converter;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;

import java.io.IOException;

/**
 * 序列化Long类型
 *
 * @author xianr
 * @date 2023/04/13
 */
public class LongJsonSerializer extends JsonSerializer<Long> {

    @Override
    public void serialize(Long value, JsonGenerator jsonGenerator, SerializerProvider serializerProvider)
            throws IOException {
        if (value != null) {
            jsonGenerator.writeNumber(value);
        }
    }
}

然后在不需要指定转换的属性上添加下面的注解

/** 总记录数 */ 
@JsonSerialize(using = LongJsonSerializer.class)
private long total;

到这里大功告成,有帮助的话,请点个赞,谢谢!

记录一个小细节:
如果不生效,确认下,是否扫描到@Configuration配置类。

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐