Micronaut下@JsonFormat配置dd.MM.yyyy的LocalDate反序列化失败
环境信息
- Micronaut 1.3
- Jackson 2.13.1
问题复现
实体类moving_date字段为LocalDate类型,已添加Jackson注解指定日期格式为dd.MM.yyyy,代码如下:
@JsonInclude @Column(name = "moving_date") @JsonView(JsonViewSimple.class) @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "dd.MM.yyyy") private LocalDate moving_date;
POST请求传入02.06.2022作为该字段值时,抛出反序列化异常:
Failed to convert argument [obj] for value [null] due to: Cannot deserialize value of type `java.time.LocalDate` from String "02.06.2022": Failed to deserialize java.time.LocalDate: (java.time.format.DateTimeParseException) Text '02.06.2022' could not be parsed at index 0 at [Source: UNKNOWN; byte offset: #UNKNOWN]
异常特征:
- 项目中其他类使用完全相同注解配置的同类型日期字段可正常解析
- 自定义的Jackson日期序列化、反序列化器断点无法命中,报错直接触发
- 传入
yyyy-MM-dd格式的日期参数时可正常解析,无异常
根因
该问题由Micronaut 1.x版本的参数绑定优先级机制导致:
- Micronaut 1.x处理Controller入参时,内置类型转换体系的执行优先级高于Jackson反序列化,只有内置转换器无法处理的类型,才会下沉到Jackson做解析
- 内置的
String -> LocalDate转换器默认仅支持ISO标准的yyyy-MM-dd格式,不会读取字段上的@JsonFormat配置,也不会加载自定义的Jackson序列化/反序列化器,因此直接抛出解析错误 - 其他类同配置字段可正常解析,是因为这些字段所属的入参对象走了Jackson消息转换器流程(比如被
@Body注解修饰、或嵌套在其他走Jackson解析的对象结构中),没有触发Micronaut内置参数绑定逻辑。
解决方案
三种方案任选其一即可:
- 方案1:在对应Controller方法的入参上添加
@Body注解,强制整个请求体走Jackson消息解析流程,此时字段上的@JsonFormat配置、自定义序列化/反序列化器都会正常生效。 - 方案2:注册Micronaut自定义类型转换器,覆盖默认的
String -> LocalDate转换逻辑,增加对dd.MM.yyyy格式的支持,参考实现:
@Singleton public class CustomLocalDateConverter implements TypeConverter<String, LocalDate> { private static final DateTimeFormatter CUSTOM_FORMATTER = DateTimeFormatter.ofPattern("dd.MM.yyyy"); @Override public Optional<LocalDate> convert(String value, Class<LocalDate> targetType, ConversionContext context) { try { return Optional.of(LocalDate.parse(value, CUSTOM_FORMATTER)); } catch (DateTimeParseException e) { // 保留默认ISO格式兼容能力 try { return Optional.of(LocalDate.parse(value)); } catch (DateTimeParseException ex) { context.reject(ex); return Optional.empty(); } } } }
- 方案3:升级Micronaut版本到2.x及以上,高版本已调整参数绑定优先级,会优先读取Jackson注解配置完成日期解析,不存在该优先级冲突问题。
内容的提问来源于stack exchange,提问作者Alexander Khudoev
相关产品推荐
相关产品推荐

