json序列化修复
build / build-push (push) Successful in 33s

This commit is contained in:
chenxing
2026-08-26 19:08:01 +08:00
parent d9ec243926
commit ea3d5ed121
@@ -0,0 +1,75 @@
package com.yunhai.userhome.config;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.module.SimpleModule;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeParseException;
import java.util.Arrays;
import java.util.List;
/**
* Jackson 全局配置:统一 java.time.LocalDateTime 的反序列化格式。
*
* <p>背景:UserBase 跨仓接口(如 /oapi/app/list)返回的时间是 "yyyy-MM-dd HH:mm:ss"(空格分隔),
* 而 Jackson 默认的 LocalDateTimeDeserializer 只接受 ISO 格式("yyyy-MM-dd'T'HH:mm:ss"),
* 导致 OpenAPI 客户端反序列化 BoaApp.createTime 时抛 DateTimeParseException,
* 消息中心(getMessageByUserId)等接口因此报"内部服务错误"。
*
* <p>yh-openapi 的 OpenApiAutoConfiguration.openApiObjectMapper() 带 @ConditionalOnMissingBean,
* 本工程定义该 ObjectMapper bean 后即被 OpenAPI 客户端(OpenApiHttpClient / AbstractOpenApiClient)采用;
* 同时它也是 Spring MVC 使用的全局 mapper,因此同样保留 spring.jackson.* 配置(GMT+8 时区、
* java.util.Date 的 yyyy-MM-dd HH:mm:ss 格式)。
*/
@Configuration
public class JacksonConfig {
/** 兼容的 LocalDateTime 字符串格式,按优先级依次尝试:先 UserBase 的空格格式,再 ISO 格式。 */
private static final List<DateTimeFormatter> LOCAL_DATE_TIME_FORMATTERS = Arrays.asList(
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"),
DateTimeFormatter.ISO_LOCAL_DATE_TIME);
@Bean
@Primary
public ObjectMapper objectMapper(Jackson2ObjectMapperBuilder builder) {
SimpleModule module = new SimpleModule();
module.addDeserializer(LocalDateTime.class, new FlexibleLocalDateTimeDeserializer());
return builder.modulesToInstall(module).build();
}
/**
* 兼容 "yyyy-MM-dd HH:mm:ss" 与 ISO 格式的 LocalDateTime 反序列化器;
* 字符串以外的输入(如数字时间戳)沿用 Jackson 默认处理。
*/
private static class FlexibleLocalDateTimeDeserializer extends LocalDateTimeDeserializer {
private FlexibleLocalDateTimeDeserializer() {
super(DateTimeFormatter.ISO_LOCAL_DATE_TIME);
}
@Override
public LocalDateTime deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
if (p.hasToken(JsonToken.VALUE_STRING)) {
String text = p.getText();
for (DateTimeFormatter formatter : LOCAL_DATE_TIME_FORMATTERS) {
try {
return LocalDateTime.parse(text, formatter);
} catch (DateTimeParseException ignored) {
// 继续尝试下一种格式
}
}
}
return super.deserialize(p, ctxt);
}
}
}