Spring Boot项目前后端Long类型数据传递失真问题的处理方式

场景介绍:

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

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

雪花算法
优点:雪花算法id是一个64bits的Long数据,第一位为零表示其为正数,最后12位为其序列号,生成的id既能完美契合分布式ID的需求,同时后12位序列号也能够保证主键的有序性。
缺点:雪花算法的长度是19(long型最多19位)位的,前端能够接收的数字最多只能是16位的,因此就会造成精度丢失,导致相关业务无法处理。

2 . UUID
UUID : 是指在一台机器上生成的数字,它保证对在同一时空中的所有机器都是唯一的。在UUID的算法中,可能会用到诸如网卡MAC地址,IP,主机名,进程ID等信息以保证其独立性。
优点:UUID不是通过数据库的主键生成器生成的,在入库之前就能够获取到其主键,非常符合分布式主键的设计。
缺点:UUID没有规律可循,无法保证主键的插入顺序型。且UUID在意外情况下(mac地址等其他生成UUID的因素相同的情况)可能会出现UUID相同。

3 .自增Long型主键
优点:自增主键保证了,插入数据的主键永远比已有的数据的主键大。(看不懂就去复习数据结构)
缺点:需要等待插入完成才有主键,或者等待主键生成器返回才会有主键。不利于分布式的设计。


问题描述:

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


原因分析:

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

    private static final long serialVersionUID = 1L;
	/** 雪花算法生成分布式ID */
    @TableId(value = "id",type = IdType.ID_WORKER)
    private Long id;

解决方案:

解决的方式很简单,我们只需要将数据库中雪花算法生成的ID转换为String传递给前端就能够保证数据的可靠性!

  • 在相关需要转换的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;
}
  • 在拦截器中加Long型数据转换方法(推荐使用)
    第一种方法非常稳健,但比较繁琐,需要在和前端交互的每一个res中的ID上加入次注解,对于我这种十分懒惰的哥们儿是不实用滴,于是俺采用这一种在web层统一配置的懒人操作。
@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);
    }
}
  • 自定义配置类
    如果你既没有在ID上加注释,也没有配置拦截器,也妹关系,直接写一个简单的配置类就完事儿了,因为这个转String的核心类就是:ObjectMapper 而已
/**
 * 类型转换配置
 *
 * @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;
    }
}

总结:

萝卜青菜,各有所爱,兄弟萌用自己喜欢的姿势完成Long类型转换即可。

  • 7
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Spring Boot 是一个开源的 JavaEE 框架,可以快速构建 Web 应用程序和微服务。在 Spring Boot 中,前后端不分离的项目通常是使用模板引擎来渲染页面,后端将数据传递给模板引擎,然后模板引擎将数据填充到 HTML 页面中。 在 Spring Boot 中,常见的模板引擎包括 Thymeleaf、Freemarker、JSP 等。使用模板引擎,可以方便地将数据填充到 HTML 页面中,并实现动态页面的渲染。 下面是一个使用 Thymeleaf 模板引擎的 Spring Boot 示例: 1. 添加 Thymeleaf 依赖: ```xml <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> ``` 2. 创建一个简单的控制器类: ```java @Controller public class HelloController { @GetMapping("/hello") public String hello(Model model) { model.addAttribute("name", "World"); return "hello"; } } ``` 3. 创建一个名为 hello.html 的模板文件: ```html <!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"> <title>Hello</title> </head> <body> <h1 th:text="'Hello, ' + ${name} + '!'"></h1> </body> </html> ``` 4. 运行程序,访问 http://localhost:8080/hello,即可看到页面上显示了“Hello, World!”。 通过使用模板引擎,可以很方便地将数据填充到 HTML 页面中,实现动态页面的渲染。但是,使用模板引擎的前后端不分离项目开发效率低下,难以实现前后端分离、复用和可维护性。因此,在实际开发中,建议使用前后端分离的架构。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值