处理Long类型长度超长导致前端精度丢失问题

1,问题场景

         后端返回的Long类型的数据,超10000000000000000,前端处理的时候,数据被截断了。比如tchId: 11073477511443988481, 前端根据tchId获取下一环节信息的时候,传的tchId变成了11073477511443988400,导致报错。

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

        因此当Long类型超过的时候,需要把Long类型,转成字符串返回给前端。

2,处理:

1,处理方法1:字段加注解

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

import com.fasterxml.jackson.annotation.JsonFormat;public class Tache {@JsonFormat(shape = JsonFormat.Shape.STRING)private Long tchld;
}

这种就只适合指定的字段,不通用。如果要设置未全局要怎么做?

2,处理方法2:全局处理

        为了更加便捷地解决这个问题,使用全局配置,将所有Long类型的数据都转换为字符串类型。通过配置Jackson的ObjectMapper来实现

引用:

implementation 'com.fasterxml.jackson.core:jackson-core:2.13.5'

判断处理:
public class StringSerializer extends StdSerializer<Object> {private static Logger logger = LoggerFactory.getLogger(StringSerializer.class);public final static StringSerializer instance = new StringSerializer();public StringSerializer() {super(Object.class);}public StringSerializer(Class<?> handledType) {super(handledType, false);}@Overridepublic void serialize(Object value, JsonGenerator gen, SerializerProvider provider) throws IOException {if (value != null && value instanceof Long) {if (((Long) value).longValue() >= 10000000000000000L) {gen.writeString(value.toString());} else {gen.writeNumber((Long) value);}}}
}

配置:
@Configuration
@EnableWebMvc
public class WebMvcConfiguration implements WebMvcConfigurer {@Overridepublic void addResourceHandlers(ResourceHandlerRegistry registry) {registry.addResourceHandler("/**").addResourceLocations("classpath:/static/");registry.addResourceHandler("/**").addResourceLocations("classpath:/META-INF/resources/");registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/");}@Beanpublic ObjectMapper jacksonObjectMapperCustomization() {TimeZone timeZone = TimeZone.getTimeZone("Asia/Shanghai");Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder().timeZone(timeZone);return builder.build();}@Overridepublic void configureMessageConverters(List<HttpMessageConverter<?>> converters) {converters.removeIf(c -> c instanceof MappingJackson2HttpMessageConverter);MappingJackson2HttpMessageConverter jackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter(jacksonObjectMapperCustomization());ObjectMapper objectMapper = new ObjectMapper();SimpleModule simpleModule = new SimpleModule();simpleModule.addSerializer(Long.class, StringSerializer.instance);simpleModule.addSerializer(Long.TYPE, StringSerializer.instance);objectMapper.registerModule(simpleModule);objectMapper.setTimeZone(TimeZone.getTimeZone("GMT+8"));objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);jackson2HttpMessageConverter.setObjectMapper(objectMapper);converters.add(jackson2HttpMessageConverter);converters.add(new ByteArrayHttpMessageConverter());converters.add(new FormHttpMessageConverter());converters.add(new StringHttpMessageConverter(Charset.forName("UTF-8")));}@Beanpublic LocaleChangeInterceptor localeChangeInterceptor() {LocaleChangeInterceptor localeChangeInterceptor = new LocaleChangeInterceptor();localeChangeInterceptor.setParamName("LOCALE");return localeChangeInterceptor;}@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(localeChangeInterceptor());}@Beanprotected RequestMappingHandlerMapping createRequestMappingHandlerMapping() {return new RequestMappingHandlerMapping() {@Overrideprotected boolean isHandler(Class<?> beanType) {return (AnnotatedElementUtils.hasAnnotation(beanType, Controller.class)|| (AnnotatedElementUtils.hasAnnotation(beanType, RequestMapping.class)&& !AnnotatedElementUtils.hasAnnotation(beanType, FeignClient.class)));}};}@Beanpublic WebMvcEndpointHandlerMapping webEndpointServletHandlerMapping(WebEndpointsSupplier webEndpointsSupplier, ServletEndpointsSupplier servletEndpointsSupplier, ControllerEndpointsSupplier controllerEndpointsSupplier, EndpointMediaTypes endpointMediaTypes, CorsEndpointProperties corsProperties, WebEndpointProperties webEndpointProperties, Environment environment) {List<ExposableEndpoint<?>> allEndpoints = new ArrayList<>();Collection<ExposableWebEndpoint> webEndpoints = webEndpointsSupplier.getEndpoints();allEndpoints.addAll(webEndpoints);allEndpoints.addAll(servletEndpointsSupplier.getEndpoints());allEndpoints.addAll(controllerEndpointsSupplier.getEndpoints());String basePath = webEndpointProperties.getBasePath();EndpointMapping endpointMapping = new EndpointMapping(basePath);boolean shouldRegisterLinksMapping = this.shouldRegisterLinksMapping(webEndpointProperties, environment, basePath);return new WebMvcEndpointHandlerMapping(endpointMapping, webEndpoints, endpointMediaTypes, corsProperties.toCorsConfiguration(), new EndpointLinksResolver(allEndpoints, basePath), shouldRegisterLinksMapping, null);}private boolean shouldRegisterLinksMapping(WebEndpointProperties webEndpointProperties, Environment environment, String basePath) {return webEndpointProperties.getDiscovery().isEnabled() && (StringUtils.hasText(basePath) || ManagementPortType.get(environment).equals(ManagementPortType.DIFFERENT));}
}

处理的代码:

simpleModule.addSerializer(Long.class, StringSerializer.instance);
simpleModule.addSerializer(Long.TYPE, StringSerializer.instance);

总结:

        如果是只有某些指定数据进行转换,就直接加注解的方式,要全局的话,就用全局的配置去处理。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/79030.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ONVIF/RTSP/RTMP协议EasyCVR视频汇聚平台RTMP协议配置全攻略 | 直播推流实战教程

在现代化的视频管理和应急指挥系统中&#xff0c;RTMP协议作为一种高效的视频流传输方式&#xff0c;正变得越来越重要。无论是安防监控、应急指挥&#xff0c;还是物联网视频融合&#xff0c;掌握RTMP协议的接入和配置方法&#xff0c;都是提升系统性能和效率的关键一步。 今天…

安徽京准:GPS北斗卫星时空信号安全防护装置(授时)介绍

安徽京准&#xff1a;GPS北斗卫星时空信号安全防护装置&#xff08;授时&#xff09;介绍 1、主要特点 ★信号加固功能&#xff1a; GPS/BDS单系统信号拒止情况下&#xff08;包含受到GPS L1欺骗干扰、GPS L1压制干扰、BDS B1欺骗干扰、BDS B1压制干扰&#xff09;&#xff…

探索原生JS的力量:自定义实现类似于React的useState功能

1.写在前面 本方案特别适合希望在历史遗留的原生JavaScript项目中实现简单轻量级数据驱动机制的开发者。无需引入任何框架或第三方库&#xff0c;即可按照此方法封装出类似于React中useState的功能&#xff0c;轻松为项目添加状态管理能力&#xff0c;既保持了项目的轻量性&am…

02.使用cline(VSCode插件)、continue(IDEA插件)、cherry-studio玩转MCP

文章目录 安装环境uv&#xff08;python&#xff09;为什么不用pip&#xff1f;安装 nvm&#xff08;nodejs&#xff09; cline插件window配置如下linux配置如下测试MCP&#xff1a;time现在几点了&#xff1f;伦敦现在几点了&#xff1f;当纽约是下午四点&#xff0c;那伦敦是…

CSS padding(填充)学习笔记

CSS 中的 padding&#xff08;填充&#xff09;是一个非常重要的属性&#xff0c;它用于定义元素边框与元素内容之间的空间&#xff0c;即上下左右的内边距。合理使用 padding 可以让页面布局更加美观、清晰。以下是对 CSS padding 的详细学习笔记。 一、padding 的作用 padd…

Spring 单元测试核心注解全解:@InjectMocks、@MockBean、@Mock、@Autowired 的区别与实战

在编写 Spring Boot 应用的单元测试过程中,@InjectMocks、@MockBean、@Mock 和 @Autowired 是最常用的几个注解,但它们经常被混淆或误用,导致测试失败或注入错误。 本文将从本质区别、使用场景、示例代码、对比表格等多个维度,全面解析这几者的使用方法与差异,助你写出结…

Themeleaf复用功能

Themeleaf复用功能 Thymeleaf 的复用功能能够有效减少代码冗余&#xff0c;提升开发效率&#xff0c;让代码更易于维护。以下为你详细介绍几种常见的复用功能&#xff1a; 1. 片段复用&#xff08;Fragments&#xff09; 定义片段 借助 th:fragment 指令&#xff0c;可将页…

前端面试题(八):简述Vue2的响应式原理

Vue 2 的响应式原理主要基于 数据劫持 和 发布-订阅模式&#xff0c;通过 Object.defineProperty 对对象的属性进行拦截&#xff0c;实现数据的监控与视图更新。具体原理如下&#xff1a; 1. 数据劫持&#xff1a;Object.defineProperty Vue 2 在初始化过程中&#xff0c;通过…

深度学习中的数值稳定性处理详解:以SimCLR损失为例

文章目录 1. 问题背景SimCLR的原始公式 2. 数值溢出问题为什么会出现数值溢出&#xff1f;浮点数的表示范围 3. 数值稳定性处理方法核心思想数学推导 4. 代码实现分解代码与公式的对应关系 5. 具体数值示例示例&#xff1a;相似度矩阵方法1&#xff1a;直接计算exp(x)方法2&…

SQL(9):创建数据库,表,简单

1、创建数据库&#xff0c;一句SQL语句搞定 CREATE DATDBASE 数据库名 CREATE DATABASE my_db;2、创建表 CREATE TABLE 表名(字段名 类型) CREATE TABLE Persons ( PersonID int, LastName varchar(255), FirstName varchar(255), Address varchar(255), City varchar(255)…

QT Sqlite数据库-教程002 查询数据-下

【1】数据库查询的优化&#xff1a;prepare prepare语句是一种在执行之前将SQL语句编译为字节码的机制&#xff0c;可以提高执行效率并防止SQL注入攻击。 【2】使用prepare查询一张表 QString myTable "myTable" ; QString cmd QString("SELECT * FROM %1…

cline 提示词工程指南-架构篇

cline 提示词工程指南-架构篇 本篇是 cline 提示词工程指南的学习和扩展&#xff0c;可以参阅&#xff1a; https://docs.cline.bot/improving-your-prompting-skills/prompting 前言 cline 是 vscode 的插件&#xff0c;用来在 vscode 里实现 ai 编程。 它使得你可以接入…

算法---子序列[动态规划解决](最长递增子序列)

最长递增子序列 子序列包含子数组&#xff01; 说白了&#xff0c;要用到双层循环&#xff01; 用双层循环中的dp[i]和dp[j]把所有子序列情况考虑到位 class Solution { public:int lengthOfLIS(vector<int>& nums) {vector<int> dp(nums.size(),1);for(int i …

kubectl命令补全以及oc命令补全

kubectl命令补全 1.安装bash-completion 如果你用的是Bash(默认情况下是)&#xff0c;先安装补全功能支持包 sudo apt update sudo apt install bash-completion -y2.为kubectl 启用补全功能 会话中临时&#xff1a; source <(kubectl completion bash)持久化配置&#x…

48、Spring Boot 详细讲义(五)

3、集成MyBatis 3.1 MyBatis 概述 3.1.1 核心功能和优势 MyBatis 是一个 Java 持久层框架,它通过 XML 或注解配置 SQL 语句,将 Java 方法与 SQL 语句映射起来,消除了大量的 JDBC 代码,简化了数据库操作。MyBatis 的核心功能和优势包括: ORM(对象关系映射):通过 XML …

BERT - Bert模型框架复现

本节将实现一个基于Transformer架构的BERT模型。 1. MultiHeadAttention 类 这个类实现了多头自注意力机制&#xff08;Multi-Head Self-Attention&#xff09;&#xff0c;是Transformer架构的核心部分。 在前几篇文章中均有讲解&#xff0c;直接上代码 class MultiHeadAtt…

解决 Spring Boot 启动报错:数据源配置引发的启动失败

启动项目时&#xff0c;控制台输出了如下错误信息&#xff1a; Error starting ApplicationContext. To display the condition evaluation report re-run your application with debug enabled. 2025-04-14 21:13:33.005 [main] ERROR o.s.b.d.LoggingFailureAnalysisReporte…

履带小车+六轴机械臂(2)

本次介绍原理图部分 开发板部分&#xff0c;电源供电部分&#xff0c;六路舵机&#xff0c;PS2手柄接收器&#xff0c;HC-05蓝牙模块&#xff0c;蜂鸣器&#xff0c;串口&#xff0c;TB6612电机驱动模块&#xff0c;LDO线性稳压电路&#xff0c;按键部分 1、开发板部分 需要注…

【开发记录】服务外包大赛记录

参加服务外包大赛的A07赛道中&#xff0c;最近因为频繁的DEBUG&#xff0c;心态爆炸 记录错误 以防止再次出现错误浪费时间。。。 2025.4.13 项目在上传图片之后 会自动刷新 没有等待后端返回 Network中的fetch /upload显示canceled. 然而这是使用了VS的live Server插件才这样&…

基于FreeRTOS和LVGL的多功能低功耗智能手表(硬件篇)

目录 一、简介 二、板子构成 三、核心板 3.1 MCU最小系统板电路 3.2 电源电路 3.3 LCD电路 3.4 EEPROM电路 3.5 硬件看门狗电路 四、背板 4.1 传感器电路 4.2 充电盘 4.3 蓝牙模块电路 五、总结 一、简介 本篇开始介绍这个项目的硬件部分&#xff0c;从最小电路设…