Spring Boot - 解决前后端Long类型数据传递失真问题

1、场景介绍

项目场景:目前市场上的大多数项目对于对象表建设的ID属性使用的是Long性并使用雪花算法生成,少量使用String的UUID,极少量的使用Long类型的自增长。

1.1 . Long型雪花算法ID

雪花算法 : 分布式id生成算法的有很多种,Twitter的SnowFlake就是其中经典的一种。

  • 优点:雪花算法id是一个64bits的Long数据,第一位为零表示其为正数,最后12位为其序列号,生成的id既能完美契合分布式ID的需求,同时后12位序列号也能够保证主键的有序性。

  • 缺点:雪花算法的长度是19(long型最多19位)位的,前端能够接收的数字最多只能是16位的,因此就会造成精度丢失,导致相关业务无法处理。

1.2  UUID

UUID : 是指在一台机器上生成的数字,它保证对在同一时空中的所有机器都是唯一的。在UUID的算法中,可能会用到诸如网卡MAC地址,IP,主机名,进程ID等信息以保证其独立性。

  • 优点:UUID不是通过数据库的主键生成器生成的,在入库之前就能够获取到其主键,非常符合分布式主键的设计。

  • 缺点:UUID没有规律可循,无法保证主键的插入顺序型。且UUID在意外情况下(mac地址等其他生成UUID的因素相同的情况)可能会出现UUID相同。

1.3 自增Long型主键

  • 优点:自增主键保证了,插入数据的主键永远比已有的数据的主键大。(看不懂就去复习数据结构)

  • 缺点:需要等待插入完成才有主键,或者等待主键生成器返回才会有主键。不利于分布式的设计。

2、问题描述:

某次开发时前端直接给俺说ID传递到前端是失真了,俺一看果真如此,反应过来是ID过长导致失真,做个记录让遇到类似问题的小伙伴能够快速的解决。

错误如下:

3、原因分析

雪花算法生成的分布式ID长度为19位,前端JS接收数字能够达到的最大精度为16位,因此导致前端得到的ID不是真正的ID,导致后续操作无法进行。

4、解决方案

4.1 方案一

在相关需要转换的ID上加注解完成转换(需要在每一个res中的ID上加)

import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
@Data
public class BusinessTreeRes {

    /**
     * 方式一:JsonSerialize注解
     * 主键
     */
    @JsonSerialize(using = ToStringSerializer.class)
    private Long typeId;
}

4.2 在拦截器中加Long型数据转换方法(推荐使用)

@Configuration
@EnableWebMvc
public class InterceptorConfig implements WebMvcConfigurer {
    /**
     * 方式二:拦截器转换
     * web层统一处理Long转String问题
     * @param converters 需要转换的对象
     */
    public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
        MappingJackson2HttpMessageConverter jackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter();
        ObjectMapper objectMapper = jackson2HttpMessageConverter.getObjectMapper();
        SimpleModule simpleModule = new SimpleModule();
        //将Long转为string 解决id过大 js显示问题
        simpleModule.addSerializer(Long.class, ToStringSerializer.instance);
        simpleModule.addSerializer(Long.TYPE, ToStringSerializer.instance);
        objectMapper.registerModule(simpleModule);
        jackson2HttpMessageConverter.setObjectMapper(objectMapper);
        converters.add(0, jackson2HttpMessageConverter);
    }
}

4.3 自定义配置类

/**
 * 类型转换配置
 *
 * @author xiefei15
 * @version 1.0
 * @date 2020/6/5 15:20
 */
@Configuration
public class DataTypeConvertConfig{
    /**
     *
     * 方式三:采用objectMapper注入
     */
    @Bean
    public ObjectMapper objectMapper (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;
    }
}
  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
前后端分离的架构中,前端和后端是独立部署和运行的,因此需要在后端项目中使用spring-boot-starter-actuator来对后端应用进行监控和管理。前端项目可以通过HTTP接口调用actuator的端点来获取应用程序的信息。 首先,你需要在后端的Spring Boot项目中添加spring-boot-starter-actuator的依赖。在你的pom.xml文件中,添加以下依赖: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> ``` 然后,你需要在应用程序的配置文件(例如application.properties或application.yml)中配置actuator的相关属性。例如,你可以设置管理端点的访问路径和权限: ```properties # 设置管理端点的访问路径 management.endpoints.web.base-path=/actuator # 开启所有的管理端点,默认只开启了/health和/info management.endpoints.web.exposure.include=* ``` 配置完成后,你可以启动后端应用程序,并通过HTTP请求访问actuator提供的各种端点来获取应用程序的信息。例如: - `/actuator/health`:应用程序的健康状况 - `/actuator/info`:应用程序的信息 - `/actuator/metrics`:度量指标信息 - `/actuator/env`:运行时环境信息 你可以根据具体需求,选择性地暴露和配置这些端点。同时,你还可以自定义自己的管理端点,以满足特定的监控和管理需求。 在前端项目中,你可以通过发送HTTP请求来调用这些管理端点,获取后端应用程序的信息,从而实现前端对后端应用程序的监控和管理功能。 希望这些信息对你有帮助!如果还有其他问题,请随时提问。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值