Swagger生成模型场景下Spring Boot LocalDate被序列化为数组的解决
问题根因
出现"firstDate": [2021, 3, 1]的数组输出,本质是Jackson对Java 8时间类的默认配置问题:默认情况下Jackson会把LocalDate的年、月、日拆解为数组结构序列化,没有走通用的字符串日期格式。因为你的响应模型是Swagger自动生成的,没法直接在字段上加@JsonFormat,所以必须做全局配置,完全不用碰生成的模型代码就能解决。
解决方案
方案1:通过Spring Boot自动配置参数快速调整
Spring Boot本身就内置了Jackson的适配开关,不需要写自定义代码就能调整规则,直接在application.properties或者application.yml里加几行配置就行:
# 关闭Java时间类型的数组/时间戳格式序列化 spring.jackson.serialization.write-dates-as-timestamps=false # 统一指定日期序列化格式 spring.jackson.date-format=yyyy-MM-dd
配置完成后重启项目,所有LocalDate类型的字段会自动输出为yyyy-MM-dd格式的字符串。
方案2:自定义全局Jackson定制类(适配复杂场景)
如果加了配置参数还是没生效,大概率是项目里其他配置(比如自定义的ObjectMapper)覆盖了Spring Boot的默认规则,这时候直接写个定制配置类,通过Spring Boot提供的Jackson扩展点注册全局规则就行,不会影响原来的自动装配逻辑:
- 新增Jackson配置类,为指定时间类型绑定全局序列化、反序列化规则:
@Configuration public class GlobalJacksonConfig { @Bean public Jackson2ObjectMapperBuilderCustomizer timeTypeCustomizer() { return builder -> { // 为LocalDate绑定全局序列化规则 DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd"); builder.serializerByType(LocalDate.class, new LocalDateSerializer(dateFormatter)); builder.deserializerByType(LocalDate.class, new LocalDateDeserializer(dateFormatter)); // 可按需顺带统一其他Java时间类型的序列化规则,避免后续适配问题 DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); builder.serializerByType(LocalDateTime.class, new LocalDateTimeSerializer(dateTimeFormatter)); builder.deserializerByType(LocalDateTime.class, new LocalDateTimeDeserializer(dateTimeFormatter)); }; } } - 配置注意事项:
- 这种注册方式是按类型全局匹配的,不管实体是不是自动生成的,只要字段类型是
LocalDate,就会自动应用对应的序列化规则,根本不需要改生成的代码。 - 千万别为了定制规则直接手动new一个完整的
ObjectMapperBean 覆盖默认配置,那样会把Spring Boot自带的所有Jackson适配逻辑都冲掉,很容易引发其他接口的序列化兼容问题。
- 这种注册方式是按类型全局匹配的,不管实体是不是自动生成的,只要字段类型是
效果验证
配置生效前后的响应对比如下:
- 配置前的异常格式:
"firstDate": [2021, 3, 1]
- 配置后的标准格式:
"firstDate": "2021-03-01"
API消费方可以直接把DTO里的对应字段改成字符串类型,不需要再适配数组结构。
内容的提问来源于stack exchange,提问作者Rubis
相关产品推荐
相关产品推荐

