diff --git a/src/main/java/com/youlai/boot/config/JacksonConfig.java b/src/main/java/com/youlai/boot/config/JacksonConfig.java new file mode 100644 index 00000000..f9ed47af --- /dev/null +++ b/src/main/java/com/youlai/boot/config/JacksonConfig.java @@ -0,0 +1,47 @@ +package com.youlai.boot.config; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import tools.jackson.databind.cfg.DateTimeFeature; +import tools.jackson.databind.json.JsonMapper; +import tools.jackson.databind.module.SimpleModule; +import tools.jackson.databind.ser.std.ToStringSerializer; + +import java.math.BigInteger; +import java.text.SimpleDateFormat; +import java.util.TimeZone; + +/** + * Jackson 全局序列化配置 + * + *

本项目的统一序列化策略: + *
- 统一时区 GMT+8 统一日期格式 yyyy-MM-dd HH:mm:ss + *
- Long/BigInteger 序列化为字符串,避免前端精度丢失 + *
- 禁用 WRITE_DATES_AS_TIMESTAMPS,避免日期输出为时间戳

+ * + * @author Ray.Hao + * @since 2026/1/12 + */ +@Configuration +public class JacksonConfig { + + /** + * 全局 JsonMapper + * + *

由 Spring Boot 自动装配到 Jackson 相关的 HttpMessageConverter 中,作为全局 JSON 序列化/反序列化 + * 行为的唯一入口。

+ */ + @Bean + public JsonMapper objectMapper() { + return JsonMapper.builder() + .disable(DateTimeFeature.WRITE_DATES_AS_TIMESTAMPS) + .defaultDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")) + .defaultTimeZone(TimeZone.getTimeZone("GMT+8")) + .addModule(new SimpleModule() + .addSerializer(Long.class, ToStringSerializer.instance) + .addSerializer(BigInteger.class, ToStringSerializer.instance) + ) + .build(); + } + +} diff --git a/src/main/java/com/youlai/boot/config/WebMvcConfig.java b/src/main/java/com/youlai/boot/config/WebMvcConfig.java deleted file mode 100644 index a2b6f572..00000000 --- a/src/main/java/com/youlai/boot/config/WebMvcConfig.java +++ /dev/null @@ -1,79 +0,0 @@ -package com.youlai.boot.config; - -import jakarta.validation.Validation; -import jakarta.validation.Validator; -import jakarta.validation.ValidatorFactory; -import lombok.extern.slf4j.Slf4j; -import org.hibernate.validator.HibernateValidator; -import org.springframework.beans.factory.config.AutowireCapableBeanFactory; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.http.converter.HttpMessageConverters; -import org.springframework.http.converter.json.JacksonJsonHttpMessageConverter; -import org.springframework.validation.beanvalidation.SpringConstraintValidatorFactory; -import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; -import tools.jackson.databind.cfg.DateTimeFeature; -import tools.jackson.databind.json.JsonMapper; -import tools.jackson.databind.module.SimpleModule; -import tools.jackson.databind.ser.std.ToStringSerializer; - -import java.math.BigInteger; -import java.text.SimpleDateFormat; -import java.time.format.DateTimeFormatter; -import java.util.TimeZone; - -/** - * Web 配置 - * - * @author Ray.Hao - * @since 2020/10/16 - */ -@Configuration -@Slf4j -public class WebMvcConfig implements WebMvcConfigurer { - - private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); - - /** - * Spring Boot 4.x 已经使用Jackson 3.x - * Jackson 3.x已经自带JavaTimeModule,不再需要手工注册 - * - * @param converterBuilder the builder to configure - */ - @Override - public void configureMessageConverters(HttpMessageConverters.ServerBuilder converterBuilder) { - JsonMapper.Builder builder = JsonMapper.builder(); - - // 配置全局日期格式和时区 - builder.disable(DateTimeFeature.WRITE_DATES_AS_TIMESTAMPS); - builder.defaultDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")); - builder.defaultTimeZone(TimeZone.getTimeZone("GMT+8")); - - // 处理 Long/BigInteger 的精度问题 - SimpleModule simpleModule = new SimpleModule(); - simpleModule.addSerializer(Long.class, ToStringSerializer.instance); - simpleModule.addSerializer(BigInteger.class, ToStringSerializer.instance); - builder.addModule(simpleModule); - - converterBuilder.addCustomConverter(new JacksonJsonHttpMessageConverter(builder)); - } - - /** - * 配置校验器 - * - * @param autowireCapableBeanFactory 用于注入 SpringConstraintValidatorFactory - * @return Validator 实例 - */ - @Bean - public Validator validator(final AutowireCapableBeanFactory autowireCapableBeanFactory) { - try (ValidatorFactory validatorFactory = Validation.byProvider(HibernateValidator.class) - .configure() - .failFast(true) // failFast=true 时,遇到第一个校验失败则立即返回,false 表示校验所有参数 - .constraintValidatorFactory(new SpringConstraintValidatorFactory(autowireCapableBeanFactory)) - .buildValidatorFactory()) { - - // 使用 try-with-resources 确保 ValidatorFactory 被正确关闭 - return validatorFactory.getValidator(); - } - } -}