You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SpringBoot多格式LocalDateTime兼容单值/集合/Map反序列化方案咨询

问题根本原因

  1. 原反序列化器实现存在Bug:直接将JsonParser传递给新建的LocalDateTimeDeserializer解析,第一次解析失败后JsonParser的读取指针已偏移,后续格式尝试都会读取空值或错误内容,永远匹配不到第二个格式。
  2. 原ObjectMapper配置使用modules()方法会覆盖Spring Boot默认注册的JavaTimeModule等内置模块,且未明确自定义反序列化器的优先级,导致默认的LocalDateTime反序列化器仍被优先调用。
  3. 原自定义注解仅配置了@JsonDeserialize(using = xxx),仅对单个LocalDateTime属性生效,集合/Map的元素反序列化需要额外配置contentUsing属性。

可行解决方案

方案1:全局配置(无需加注解,全应用生效)

步骤1:修复自定义反序列化器

先读取完整的日期字符串再逐格式匹配,避免JsonParser指针偏移问题:

public class CustomDateTimeDeser extends JsonDeserializer<LocalDateTime> {
    private static final String[] DATE_FORMATS = {"MM/dd/yyyy HH:mm", "yyyy-MM-dd'T'HH:mm:ss"};
    private static final ZoneId ZONE_ID = TimeZone.getTimeZone("America/New_York").toZoneId();

    @Override
    public LocalDateTime deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
        String dateStr = jsonParser.getValueAsString();
        for (String format : DATE_FORMATS) {
            try {
                DateTimeFormatter formatter = DateTimeFormatter.ofPattern(format).withZone(ZONE_ID);
                return LocalDateTime.parse(dateStr, formatter);
            } catch (Exception ignored) {
            }
        }
        throw new JsonParseException(jsonParser, "Unable to parse date: [" + dateStr + "]. Supported formats: " + Arrays.toString(DATE_FORMATS));
    }
}

步骤2:正确配置ObjectMapper

使用modulesToInstall追加自定义模块,不会覆盖默认模块,确保自定义反序列化器优先生效:

@Bean
@Primary
public ObjectMapper objectMapper() {
    SimpleModule customModule = new SimpleModule();
    customModule.addDeserializer(LocalDateTime.class, new CustomDateTimeDeser());
    return Jackson2ObjectMapperBuilder.json()
            .modulesToInstall(customModule)
            .featuresToDisable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
            .build();
}

该配置自动覆盖所有LocalDateTime相关的反序列化场景,包括单个属性、List、Set、Map值的反序列化,无需额外加注解。


方案2:自定义注解方案(仅标注的属性生效)

如果不需要全局生效,仅希望加注解的属性支持多格式,修改自定义注解同时配置using和contentUsing:

@JacksonAnnotationsInside
@Retention(RetentionPolicy.RUNTIME)
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss", timezone = "America/New_York")
// 同时配置单个类型反序列化和集合内容反序列化
@JsonDeserialize(using = CustomDateTimeDeser.class, contentUsing = CustomDateTimeDeser.class)
public @interface CustomDateTimeFormat {}

使用时直接在对应属性上加@CustomDateTimeFormat即可,不管是单个LocalDateTime还是集合、Map类型的属性都能正常反序列化。


内容的提问来源于stack exchange,提问作者ASPEN3

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 09:24:06