From 7899b31c083beea6e22864f3f55559620949e38b Mon Sep 17 00:00:00 2001 From: Joshi <3040996759@qq.com> Date: Mon, 8 Jun 2026 13:19:19 +0800 Subject: [PATCH] =?UTF-8?q?feat(jackson):=20=E6=B7=BB=E5=8A=A0=E5=A4=A7?= =?UTF-8?q?=E6=95=B0=E5=AD=97=E5=BA=8F=E5=88=97=E5=8C=96=E5=A4=84=E7=90=86?= =?UTF-8?q?=E9=81=BF=E5=85=8D=E5=89=8D=E7=AB=AF=E7=B2=BE=E5=BA=A6=E4=B8=A2?= =?UTF-8?q?=E5=A4=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增大数字序列化器 BigNumberSerializer 处理超出 JS 安全整数范围的 Long/BigInteger - 配置 Jackson 全局设置将超长数字自动转换为字符串格式 - 添加 BigDecimal 直接序列化为字符串确保精度完整 - 统一 LocalDateTime 时间格式化为 yyyy-MM-dd HH:mm:ss 格式 --- .../ruoyi/framework/config/JacksonConfig.java | 49 +++++++++++++++++++ .../jackson/BigNumberSerializer.java | 45 +++++++++++++++++ 2 files changed, 94 insertions(+) create mode 100644 ruoyi-framework/src/main/java/com/ruoyi/framework/config/JacksonConfig.java create mode 100644 ruoyi-framework/src/main/java/com/ruoyi/framework/jackson/BigNumberSerializer.java diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/JacksonConfig.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/JacksonConfig.java new file mode 100644 index 00000000..d3457612 --- /dev/null +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/JacksonConfig.java @@ -0,0 +1,49 @@ +package com.ruoyi.framework.config; + +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; +import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; +import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; +import com.ruoyi.framework.jackson.BigNumberSerializer; +import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import java.math.BigDecimal; +import java.math.BigInteger; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; +import java.util.TimeZone; + +/** + * jackson 全局配置 + *

+ * 支持 Long/BigInteger 超出 JS 安全整数范围时自动转为字符串, + * 避免前端精度丢失。 + * + * @author Lion Li + */ +@Configuration +public class JacksonConfig { + + @Bean + public Jackson2ObjectMapperBuilderCustomizer customizer() { + return builder -> { + // 全局配置序列化返回 JSON 处理 + JavaTimeModule javaTimeModule = new JavaTimeModule(); + // Long 类型:超出 JS 安全范围时序列化为字符串 + javaTimeModule.addSerializer(Long.class, BigNumberSerializer.INSTANCE); + javaTimeModule.addSerializer(Long.TYPE, BigNumberSerializer.INSTANCE); + // BigInteger 类型:超出 JS 安全范围时序列化为字符串 + javaTimeModule.addSerializer(BigInteger.class, BigNumberSerializer.INSTANCE); + // BigDecimal 类型:直接序列化为字符串(精度原因) + javaTimeModule.addSerializer(BigDecimal.class, com.fasterxml.jackson.databind.ser.std.ToStringSerializer.instance); + // LocalDateTime 统一格式化 + DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); + javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(formatter)); + javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(formatter)); + builder.modules(javaTimeModule); + builder.timeZone(TimeZone.getDefault()); + }; + } + +} diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/jackson/BigNumberSerializer.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/jackson/BigNumberSerializer.java new file mode 100644 index 00000000..ad40c644 --- /dev/null +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/jackson/BigNumberSerializer.java @@ -0,0 +1,45 @@ +package com.ruoyi.framework.jackson; + +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; + +/** + * 超出 JS 最大最小值 处理 + * 将超出 Number.MAX_SAFE_INTEGER 范围的 Long/BigInteger 序列化为字符串, + * 避免前端 JavaScript 精度丢失。 + * + * @author Lion Li + */ +@JacksonStdImpl +public class BigNumberSerializer extends NumberSerializer { + + /** + * 根据 JS Number.MAX_SAFE_INTEGER 与 Number.MIN_SAFE_INTEGER 得来 + */ + 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 rawType) { + super(rawType); + } + + @Override + public void serialize(Number value, JsonGenerator gen, SerializerProvider provider) throws IOException { + // 在 JS 安全整数范围内 → 正常序列化为 Number + if (value.longValue() >= MIN_SAFE_INTEGER && value.longValue() <= MAX_SAFE_INTEGER) { + super.serialize(value, gen, provider); + } else { + // 超出范围 → 序列化为字符串,前端不会丢精度 + gen.writeString(value.toString()); + } + } +}