返回顶部
首页 > 资讯 > 后端开发 > Python >SpringBoot主键ID传到前端后精度丢失的问题解决
  • 908
分享到

SpringBoot主键ID传到前端后精度丢失的问题解决

2024-04-02 19:04:59 908人浏览 薄情痞子

Python 官方文档:入门教程 => 点击学习

摘要

目录简介问题描述项目场景问题描述实例问题复现解决方案全局处理局部处理简介 本文用示例介绍SpringBoot如何解决雪花算法主键ID传到前端后精度丢失问题。 问题描述 Java后端L

简介

本文用示例介绍SpringBoot如何解决雪花算法主键ID传到前端后精度丢失问题。

问题描述

Java后端Long类型的范围

-2^63~2^63,即:-9223372036854775808~9223372036854775807,它是19位的。

这个数字可以通过方法获得:Long.MAX_VALUE、Long_MIN_VALUE。

前端JS的数字类型的范围

-2^53~2^53,即:-9007199254740991~9007199254740991,它是16位的。

这个数字可以通过方法获得:Number.MAX_SAFE_INTEGER、Number.MIN_SAFE_INTEGER。

结论

可见,Java后端的Long宽度大于前端的。雪花算法一般会生成18位或者19位宽度的数字,那么这时就会出问题。

项目场景

1.表结构

主键类型是BIGINT,存储雪花算法生成的ID。

CREATE TABLE `user` (
  `id` BIGINT(32) NOT NULL COMMENT '用户id',
	...
  PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户表';

2.Entity

用Long 类型对应数据库ID的BIGINT类型。

这里使用 mybatisPlus 的雪花算法自动生成19位长度的纯数字作为主键ID。(当然也可以手动用雪花算法生成ID)

import lombok.Data;
 
@Data
public class User {
    @TableId(type = IdType.ASSIGN_ID)
    private Long id;
	
    //其他成员
}

3.响应给前端

JSON数据响应给前端正常

{
  "id": 1352166380631257089,
   ...
}

问题描述

实例

Controller

package com.knife.controller;
 
import com.knife.entity.UserVO;
import org.springframework.WEB.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
 
@RestController
@RequestMapping("user")
public class UserController {
 
    @GetMapping("find")
    public UserVO find(Long id) {
        UserVO userVO = new UserVO();
        userVO.setId(id);
        userVO.setUsername("Tony");
 
        return userVO;
    }
}

Entity

package com.knife.entity;
 
import lombok.Data;
 
@Data
public class UserVO {
    private Long id;
 
    private String username;
}

测试

访问:Http://localhost:8080/user/find?id=1352213368413982722

结果

问题复现

从上边可以看到,并没有问题。

为什么没有出问题?

前端传入后端:Spingmvc会自动将String类型的ID转为Long类型,不会出问题

后端响应给前端:是jsON格式,与JS没有关系,不会出问题

什么时候会出问题?

前端接收到JSON之后,将其序列化为JS对象,然后进行其他操作。在JSON转JS对象时就会出问题,如下:

可以看到,原来id为1352213368413982722,序列化为JS对象后变成了 1352213368413982700

代码为:

const json = '{"id": 1352213368413982722, "name": "Tony"}';
const obj = JSON.parse(json);
 
console.log(obj.id);
console.log(obj.name);

解决方案

有如下两种方案

1.将数据库表设计的id字段由 Long 类型改成 String 类型。

2.前端用String类型来保存ID保持精度,后端及数据库继续使用Long(BigINT)类型

方案1使用String 类型做数据库ID,查询性能会大幅度下降。所以应该采用方案2。本文介绍方案2。

全局处理

简介

自定义ObjectMapper。

方案1:ToStringSerializer(推荐)

package com.knife.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;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
 
@Configuration
public class JacksonConfig {
 
    @Bean
    public ObjectMapper jacksonObjectMapper(Jackson2ObjectMapperBuilder builder) {
        ObjectMapper objectMapper = builder.createXmlMapper(false).build();
 
        // 全局配置序列化返回 JSON 处理
        SimpleModule simpleModule = new SimpleModule();
        // 将使用String来序列化Long类型
        simpleModule.addSerializer(Long.class, ToStringSerializer.instance);
        simpleModule.addSerializer(Long.TYPE, ToStringSerializer.instance);
        objectMapper.reGISterModule(simpleModule);
        return objectMapper;
    }
}

测试 

访问:http://localhost:8080/user/find?id=1352213368413982722

方案2:自定义序列化器(不推荐)

序列化器

package com.knife.config;
 
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.annotation.JacksonStdImpl;
import com.fasterxml.jackson.databind.ser.std.NumberSerializer;
 
import java.io.IOException;
 

@JacksonStdImpl
public class BigNumberSerializer extends NumberSerializer {
 
	
	private static final long MAX_SAFE_INTEGER = 9007199254740991L;
	private static final long MIN_SAFE_INTEGER = -9007199254740991L;
 
	
	public static final BigNumberSerializer instance = new BigNumberSerializer(Number.class);
 
	public BigNumberSerializer(Class<? extends Number> rawType) {
		super(rawType);
	}
 
	@Override
	public void serialize(Number value, JsonGenerator gen, SerializerProvider provider) throws IOException {
		// 超出范围 序列化位字符串
		if (value.longValue() > MIN_SAFE_INTEGER && value.longValue() < MAX_SAFE_INTEGER) {
			super.serialize(value, gen, provider);
		} else {
			gen.writeString(value.toString());
		}
	}
}

ObjectMapper配置

package com.knife.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;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
 
@Configuration
public class JacksonConfig {
 
    @Bean
    public ObjectMapper jacksonObjectMapper(Jackson2ObjectMapperBuilder builder) {
        ObjectMapper objectMapper = builder.createXmlMapper(false).build();
 
        // 全局配置序列化返回 JSON 处理
        SimpleModule simpleModule = new SimpleModule();
        // 将使用自定义序列化器来序列化Long类型
        simpleModule.addSerializer(Long.class, BigNumberSerializer.instance);
        simpleModule.addSerializer(Long.TYPE, BigNumberSerializer.instance);
        objectMapper.registerModule(simpleModule);
        return objectMapper;
    }
}

测试 

访问:http://localhost:8080/user/find?id=1352213368413982722

局部处理

说明

在字段上加:@JsonSerialize(using= ToStringSerializer.class)。

实例

package com.knife.entity;
 
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import lombok.Data;
 
@Data
public class UserVO {
    @JsonSerialize(using= ToStringSerializer.class)
    private Long id;
 
    private String username;
}

测试 

访问:http://localhost:8080/user/find?id=1352213368413982722

到此这篇关于SpringBoot主键ID传到前端后精度丢失的问题解决的文章就介绍到这了,更多相关SpringBoot主键ID精度丢失内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: SpringBoot主键ID传到前端后精度丢失的问题解决

本文链接: https://lsjlt.com/news/149446.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • SpringBoot主键ID传到前端后精度丢失的问题解决
    目录简介问题描述项目场景问题描述实例问题复现解决方案全局处理局部处理简介 本文用示例介绍SpringBoot如何解决雪花算法主键ID传到前端后精度丢失问题。 问题描述 Java后端L...
    99+
    2024-04-02
  • SpringBoot雪花算法主键ID传到前端后精度丢失问题的解决
    目录简介问题描述项目场景问题描述问题复现解决方案法1:全局处理法2:局部处理简介 本文用示例介绍SpringBoot如何解决雪花算法主键ID传到前端后精度丢失问题。 问题描述 Jav...
    99+
    2022-11-13
    SpringBoot雪花算法主键ID精度丢失 SpringBoot 主键ID精度丢失
  • SpringBoot解决BigDecimal传到前端后精度丢失问题
    目录简介问题描述实例问题复现Java后端BigDecimal的范围解决方案方案1:全局处理方案2:局部处理简介 本文用示例介绍SpringBoot如何解决BigDecimal传到前端...
    99+
    2024-04-02
  • SpringBoot如何解决BigDecimal传到前端后精度丢失问题
    这篇文章主要介绍“SpringBoot如何解决BigDecimal传到前端后精度丢失问题”,在日常操作中,相信很多人在SpringBoot如何解决BigDecimal传到前端后精度丢失问题问题上存在疑惑,小编查阅了各式资料,整理出简单好用的...
    99+
    2023-07-01
  • Java雪花算法生成的ID传输前端后精度丢失问题怎么解决
    本文小编为大家详细介绍“Java雪花算法生成的ID传输前端后精度丢失问题怎么解决”,内容详细,步骤清晰,细节处理妥当,希望这篇“Java雪花算法生成的ID传输前端后精度丢失问题怎么解决”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一...
    99+
    2023-07-05
  • springboot Long 精度丢失问题解决
    目录前言解决方法基于注解@JsonSerialize(不推荐)基于jackson全局配置(不推荐)使用JsonComponent 序列化配置WebMvcConfigurationSu...
    99+
    2024-04-02
  • 解决java.sql.Timestamp丢失精度的问题
    目录java.sql.Timestamp丢失精度需要重新补偿java.sql.Timestamp类的使用1. 获取当前时间2.String类型转换为Timestamp3.Timest...
    99+
    2024-04-02
  • SpringBoot分页的实现与long型id精度丢失问题的解决方案介绍
    目录一.分页查询的实现二.禁/启用员工账号三.数值转换器的使用一.分页查询的实现 在做分页查询时流程如下: 页面发送ajax请求,将分页查询参数(page、pageSize、nam...
    99+
    2022-11-13
    SpringBoot分页 SpringBoot long型id精度丢失
  • SpringBoot全局配置long转String丢失精度的问题解决
    目录第一种方式 第二种方式 第三种方式 第四种方式(缺点:将所有的数字类型都会转为字符串) web项目中,Java后端传过来的Long/long类型,前端JS接收会丢失精度。 本文推...
    99+
    2024-04-02
  • 解决前后端交互数据出现精度丢失的多种方式
    目录问题:情景复现:解决方式1.前端解决2.后端解决注意:问题: 发送Ajax请求,请求后端接口创建订单并且返回订单号出现订单号精度丢失的情况 情景复现: 前端发送请求到后端接口 ...
    99+
    2024-04-02
  • js浮点数精度丢失的问题及解决方法
    本篇内容介绍了“js浮点数精度丢失的问题及解决方法”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!说明在数学计算中,小数会有一定的误差,这是计...
    99+
    2023-06-20
  • C语言中浮点数的精度丢失问题解决
    目录一 先来看一段代码运行结果:二 如何解决(1)浮点数的大小比较(2)含浮点数的表达式和0.0的比较总结一 先来看一段代码 #include<stdio.h> int ...
    99+
    2024-04-02
  • 分析和解决 Golang 中数值精度丢失的问题
    Golang 精度丢失问题分析与解决方法 在使用 Golang 编程语言进行数学运算时,一些情况下会遇到精度丢失的问题。这种问题通常发生在浮点数运算中,特别是涉及到大数值、小数值或者需...
    99+
    2024-02-24
    golang 解决方法 精度问题 标准库
  • 如何解决C语言中浮点数的精度丢失问题
    小编给大家分享一下如何解决C语言中浮点数的精度丢失问题,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!一 先来看一段代码#include<stdio.h>...
    99+
    2023-06-26
  • Golang浮点数精度丢失问题扩展包的解决方法
    小编给大家分享一下Golang浮点数精度丢失问题扩展包的解决方法,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!PS: 今天在做项目进行精度处理的时候出现精度丢失问题,在这里跟大家分享下扩展包解决方案, 注意:这个问题是可能...
    99+
    2023-06-08
  • springboot解决前后端分离时的跨域问题
    目录一、为什么会跨域? 二、什么是跨域? 三、处理跨域 1、在controller的类上或方法上添加注解 2、在启动类配置全局cors(springboot2.0已经过时)3、注册c...
    99+
    2024-04-02
  • SpringBoot怎么解决Long型数据转换成json格式时丢失精度问题
    这篇“SpringBoot怎么解决Long型数据转换成json格式时丢失精度问题”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇...
    99+
    2023-07-02
  • 解决Springboot项目打包后的页面丢失问题(thymeleaf报错)
    目录Springboot项目打包后的页面丢失遇到的问题目前找到两种Springboot打包ThymeLeaf报错原因解决办法Springboot项目打包后的页面丢失 遇到的问题目前找...
    99+
    2024-04-02
  • 如何解决Mysql更新自增主键id遇到的问题
    这篇文章主要为大家展示了“如何解决Mysql更新自增主键id遇到的问题”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“如何解决Mysql更新自增主键id遇到的问题”这篇文章吧。为什么要更新自增id...
    99+
    2023-06-21
  • springboot怎么解决前后端分离时的跨域问题
    这篇文章主要介绍springboot怎么解决前后端分离时的跨域问题,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!springboot是什么springboot一种全新的编程规范,其设计目的是用来简化新Spring应用...
    99+
    2023-06-14
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作