Java 11中Jackson自定义格式反序列化LocalDateTime失败求助
问题解析与解决方案
问题根源
你遇到的错误核心原因是:LocalDateTime类型要求必须包含日期+时间完整信息,但你传入的字符串只有日期(2021-10-15),缺少时分秒部分,Jackson默认的LocalDateTimeDeserializer无法将仅日期的字符串转换为LocalDateTime实例。
解决方案
根据业务需求,你可以选择以下两种方案:
方案1:改用LocalDate类型(推荐,符合数据实际格式)
如果业务中该字段只需要日期信息,直接将实体类的属性类型从LocalDateTime改为LocalDate,配合现有注解即可正常反序列化:
@JsonProperty("created") @JsonFormat(shape = Shape.STRING, pattern = "yyyy-MM-dd") private LocalDate created;
方案2:保留LocalDateTime,补充默认时间部分
如果必须使用LocalDateTime,需要自定义解析逻辑,为仅日期的字符串补充默认的时分秒(比如00:00:00)。
方式一:自定义反序列化器
创建自定义反序列化器,处理仅日期的字符串:
public class CustomLocalDateTimeDeserializer extends LocalDateTimeDeserializer { public CustomLocalDateTimeDeserializer() { super(DateTimeFormatter.ofPattern("yyyy-MM-dd")); } @Override public LocalDateTime deserialize(JsonParser parser, DeserializationContext context) throws IOException { String dateStr = parser.getText().trim(); try { // 为仅日期的字符串补充当日起始时间 return LocalDate.parse(dateStr, DateTimeFormatter.ofPattern("yyyy-MM-dd")).atStartOfDay(); } catch (DateTimeParseException e) { // 兼容带时间的格式(如yyyy-MM-dd HH:mm:ss) return super.deserialize(parser, context); } } }
然后在实体类属性上配置该反序列化器:
@JsonProperty("created") @JsonFormat(shape = Shape.STRING, pattern = "yyyy-MM-dd") @JsonDeserialize(using = CustomLocalDateTimeDeserializer.class) private LocalDateTime created;
方式二:在JavaTimeModule中配置全局解析规则
直接在ObjectMapper的模块中注册带默认时间的反序列化器:
// 定义日期格式化器 DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); // 自定义反序列化器,补充时间部分 LocalDateTimeDeserializer dateTimeDeserializer = new LocalDateTimeDeserializer(dateFormatter) { @Override public LocalDateTime deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { String value = p.getText().trim(); if (value.length() == 10) { // 仅日期格式,补充当日00:00:00 return LocalDate.parse(value, dateFormatter).atStartOfDay(); } // 处理带时间的格式 return super.deserialize(p, ctxt); } }; // 注册模块 JavaTimeModule jtm = new JavaTimeModule(); jtm.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(dateFormatter)); jtm.addDeserializer(LocalDateTime.class, dateTimeDeserializer); ObjectMapper mapper = new ObjectMapper() .registerModule(new ParameterNamesModule()) .registerModule(new Jdk8Module()) .registerModule(jtm);
你之前的操作遗漏点
你之前只配置了LocalDateTime的序列化器,但没有配置对应的反序列化器,或者使用了默认的LocalDateTimeDeserializer却没有指定适配yyyy-MM-dd格式的参数,导致反序列化时依然使用默认的完整日期时间解析规则,从而报错。
内容的提问来源于stack exchange,提问作者Jeff Vincent
相关产品推荐
相关产品推荐

