@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user