From 13f094e2e4bba501918716513c7e0f42965b4dd6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B5=B5=E5=BF=A0=E6=9E=97?= <170083662@qq.com> Date: Tue, 9 Sep 2025 11:01:11 +0800 Subject: [PATCH] =?UTF-8?q?refactor(jackson):=20=E9=87=8D=E6=9E=84=20Jacks?= =?UTF-8?q?on=20=E9=85=8D=E7=BD=AE=E5=B9=B6=E6=B7=BB=E5=8A=A0=E6=B5=8B?= =?UTF-8?q?=E8=AF=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 简化了 JacksonConfig 类,移除了自定义时间格式配置 - 添加了 JacksonConfigChecker组件,用于检查 Jackson 配置是否正确 - 新增 JacksonTestController,用于测试 LocalDateTime 序列 --- .../common/core/config/JacksonConfig.java | 50 +++-------- .../core/config/JacksonConfigChecker.java | 59 ++++++++++++ .../controller/JacksonTestController.java | 90 +++++++++++++++++++ src/main/resources/application.yml | 4 - 4 files changed, 161 insertions(+), 42 deletions(-) create mode 100644 src/main/java/com/gxwebsoft/common/core/config/JacksonConfigChecker.java create mode 100644 src/main/java/com/gxwebsoft/common/core/controller/JacksonTestController.java diff --git a/src/main/java/com/gxwebsoft/common/core/config/JacksonConfig.java b/src/main/java/com/gxwebsoft/common/core/config/JacksonConfig.java index 87bb915..f1a87d0 100644 --- a/src/main/java/com/gxwebsoft/common/core/config/JacksonConfig.java +++ b/src/main/java/com/gxwebsoft/common/core/config/JacksonConfig.java @@ -4,71 +4,45 @@ import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; -import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer; -import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; -import java.time.LocalDateTime; -import java.time.format.DateTimeFormatter; - /** - * Jackson配置类 - * 确保JSR310模块被正确注册到ObjectMapper中,并配置自定义时间格式 + * Jackson配置类 - 强制配置版本 + * 确保JavaTimeModule被正确注册并覆盖Spring Boot的自动配置 * * @author WebSoft - * @since 2025-01-12 + * @since 2025-09-08 */ @Configuration public class JacksonConfig { - private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); - /** - * 配置ObjectMapper,确保JSR310模块被正确注册并设置自定义时间格式 + * 强制配置ObjectMapper,确保JavaTimeModule被正确注册 */ @Bean @Primary - @ConditionalOnMissingBean public ObjectMapper objectMapper() { ObjectMapper mapper = new ObjectMapper(); - - // 创建自定义的JavaTimeModule - JavaTimeModule javaTimeModule = new JavaTimeModule(); - - // 配置LocalDateTime的序列化和反序列化格式 - javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DATE_TIME_FORMATTER)); - javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DATE_TIME_FORMATTER)); - - // 注册自定义的JSR310模块 - mapper.registerModule(javaTimeModule); - + + // 注册JavaTimeModule - 这是关键 + mapper.registerModule(new JavaTimeModule()); + // 禁用将日期写为时间戳 mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); - + // 忽略未知属性 mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); - - // 允许空字符串作为null对象 - mapper.configure(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT, true); - + return mapper; } /** - * 确保JavaTimeModule被注册(保留原有Bean) + * 备用JavaTimeModule Bean */ @Bean - @ConditionalOnMissingBean public JavaTimeModule javaTimeModule() { - JavaTimeModule module = new JavaTimeModule(); - - // 配置LocalDateTime的序列化和反序列化格式 - module.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DATE_TIME_FORMATTER)); - module.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DATE_TIME_FORMATTER)); - - return module; + return new JavaTimeModule(); } } diff --git a/src/main/java/com/gxwebsoft/common/core/config/JacksonConfigChecker.java b/src/main/java/com/gxwebsoft/common/core/config/JacksonConfigChecker.java new file mode 100644 index 0000000..6af29f2 --- /dev/null +++ b/src/main/java/com/gxwebsoft/common/core/config/JacksonConfigChecker.java @@ -0,0 +1,59 @@ +package com.gxwebsoft.common.core.config; + +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.CommandLineRunner; +import org.springframework.stereotype.Component; + +import java.time.LocalDateTime; +import java.util.HashMap; +import java.util.Map; + +/** + * Jackson配置检查器 + * 在应用启动时检查Jackson配置是否正确 + * + * @author WebSoft + * @since 2025-09-08 + */ +@Component +public class JacksonConfigChecker implements CommandLineRunner { + + private static final Logger logger = LoggerFactory.getLogger(JacksonConfigChecker.class); + + @Autowired + private ObjectMapper objectMapper; + + @Override + public void run(String... args) throws Exception { + logger.info("=== Jackson配置检查开始 ==="); + + try { + // 检查JavaTimeModule是否注册 + boolean hasJavaTimeModule = objectMapper.getRegisteredModuleIds() + .contains(JavaTimeModule.class.getName()); + logger.info("JavaTimeModule是否注册: {}", hasJavaTimeModule); + + // 测试LocalDateTime序列化 + Map testData = new HashMap<>(); + testData.put("currentTime", LocalDateTime.now()); + testData.put("message", "Jackson配置测试"); + + String json = objectMapper.writeValueAsString(testData); + logger.info("LocalDateTime序列化测试成功: {}", json); + + // 测试反序列化 + Map result = objectMapper.readValue(json, Map.class); + logger.info("反序列化测试成功: {}", result); + + logger.info("=== Jackson配置检查完成 - 配置正常 ==="); + + } catch (Exception e) { + logger.error("=== Jackson配置检查失败 ===", e); + logger.error("请检查Jackson配置是否正确"); + } + } +} diff --git a/src/main/java/com/gxwebsoft/common/core/controller/JacksonTestController.java b/src/main/java/com/gxwebsoft/common/core/controller/JacksonTestController.java new file mode 100644 index 0000000..2a58aea --- /dev/null +++ b/src/main/java/com/gxwebsoft/common/core/controller/JacksonTestController.java @@ -0,0 +1,90 @@ +package com.gxwebsoft.common.core.controller; + +import com.gxwebsoft.common.core.web.ApiResult; +import com.gxwebsoft.common.core.web.BaseController; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.time.LocalDateTime; +import java.util.HashMap; +import java.util.Map; + +/** + * Jackson序列化测试控制器 + * 用于测试LocalDateTime序列化是否正常工作 + * + * @author WebSoft + * @since 2025-09-08 + */ +@Tag(name = "Jackson测试") +@RestController +@RequestMapping("/api/test/jackson") +public class JacksonTestController extends BaseController { + + @Operation(summary = "测试LocalDateTime序列化") + @GetMapping("/datetime") + public ApiResult> testDateTime() { + Map result = new HashMap<>(); + result.put("currentTime", LocalDateTime.now()); + result.put("message", "如果您能看到格式化的时间,说明Jackson配置正常"); + result.put("timestamp", System.currentTimeMillis()); + return success(result); + } + + @Operation(summary = "测试实体类序列化") + @GetMapping("/entity") + public ApiResult testEntity() { + TestEntity entity = new TestEntity(); + entity.setId(1); + entity.setName("测试实体"); + entity.setCreateTime(LocalDateTime.now()); + entity.setUpdateTime(LocalDateTime.now()); + return success(entity); + } + + /** + * 测试实体类 + */ + public static class TestEntity { + private Integer id; + private String name; + private LocalDateTime createTime; + private LocalDateTime updateTime; + + // Getters and Setters + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public LocalDateTime getCreateTime() { + return createTime; + } + + public void setCreateTime(LocalDateTime createTime) { + this.createTime = createTime; + } + + public LocalDateTime getUpdateTime() { + return updateTime; + } + + public void setUpdateTime(LocalDateTime updateTime) { + this.updateTime = updateTime; + } + } +} diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index c1bb2ce..7d9426e 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -24,12 +24,8 @@ spring: date-format: yyyy-MM-dd HH:mm:ss serialization: write-dates-as-timestamps: false - write-null-map-values: false deserialization: fail-on-unknown-properties: false - fail-on-null-for-primitives: false - accept-empty-string-as-null-object: true - default-property-inclusion: non_null # 连接池配置 datasource: