后端接口Long类型传输过程精度丢失问题

2024-06-15 23:30:36 浏览数 (1)

前言

在Web应用程序中,后端Java代码中的Long类型数据在传输到前端时,常常会遇到精度丢失的问题。这主要是因为JavaScript中的Number类型无法精确表示超过其安全整数范围(即-9007199254740991(-2^53 1)到9007199254740991(2^53 - 1))的整数值。因此,当后端Java的Long类型数据超过这个范围时,前端JavaScript在解析这些数据时就会丢失精度。

出现这个问题,主要是数字字段,后端使用Long类型定义,或者字段接收使用Long类型,就出现进度丢失。

一、字段加注解

在Java后端中,可以使用Jackson库的@JsonFormat注解来将Long类型字段序列化为字符串类型。这样,在数据传输到前端时,就会以字符串的形式进行传输,从而避免了精度丢失的问题,如代码字段返回转换成字符串。

代码语言:java复制
import com.fasterxml.jackson.annotation.JsonFormat;

public class MyEntity {
    @JsonFormat(shape = JsonFormat.Shape.STRING)
    private Long myLongField;
}

二、获取遍历重新赋值转为字符串

另一种方法是在数据从数据库查询出来之后,通过遍历每一个Long类型的字段,将其值转换为字符串类型,然后再进行数据传输。这种方法比较繁琐,但可以有效地解决精度丢失问题。

三、工程全局处理,对于Long类型的全部转为String

为了更加便捷地解决这个问题,还可以在整个Web应用程序中进行全局处理,将所有Long类型的数据都转换为字符串类型。这可以通过配置Jackson的ObjectMapper来实现。这个也是比较通用的方法,一般开发都是使用全局配置。

首先,需要在项目中引入Jackson的依赖:

代码语言:xml复制
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.9.2</version>
</dependency>

然后,需要配置一个WebMvcConfigurer的实现类,在其中重写configureMessageConverters方法,添加自定义的HttpMessageConverter来处理Long类型的数据。代码如下:

代码语言:java复制
import com.fasterxml.jackson.annotation.JsonInclude;
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.Jackson2ObjectMapperBuilder;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.util.List;

@Configuration
@EnableWebMvc
public class WebMvcConfig implements WebMvcConfigurer {

    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        // 配置StringHttpMessageConverter(如果需要的话)
        converters.add(new StringHttpMessageConverter());

        Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder();
        builder.serializationInclusion(JsonInclude.Include.NON_NULL);
        ObjectMapper objectMapper = builder.build();

        SimpleModule simpleModule = new SimpleModule();
        // 为Long类型注册ToStringSerializer,将其序列化为字符串
        simpleModule.addSerializer(Long.class, ToStringSerializer.instance);
        objectMapper.registerModule(simpleModule);

        // 将配置好的ObjectMapper添加到MappingJackson2HttpMessageConverter中
        converters.add(new MappingJackson2HttpMessageConverter(objectMapper));

        // 如果继承了其他WebMvcConfigurer实现类,可以调用super.configureMessageConverters(converters);
        // 但在这个例子中,我们并没有继承其他实现类,所以不需要调用
    }
}

通过以上配置,就可以在整个Web应用程序中将Long类型的数据都转换为字符串类型,从而避免了在前端JavaScript中处理时精度丢失的问题。这种方法简单、高效,且不需要对原有代码进行大量修改,是一种非常实用的解决方案。

我正在参与2024腾讯技术创作特训营最新征文,快来和我瓜分大奖!

0 人点赞