處理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.pswp.cn/diannao/79030.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/79030.shtml
英文地址,請注明出處:http://en.pswp.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;從最小電路設…