Scala Case Class使用Jackson JsonFormat序列化日期失效问题
解决Scala Case Class中Joda DateTime的@JsonFormat注解失效问题
问题分析
你遇到的问题是Jackson序列化Joda DateTime时,未应用@JsonFormat指定的格式,反而输出了完整的对象结构。核心原因是未在ObjectMapper中注册JodaModule——虽然已引入jackson-datatype-joda依赖,但该模块不会自动生效,必须显式添加到ObjectMapper中,否则Jackson无法识别Joda时间类型的序列化规则,只能用默认的对象序列化逻辑。
解决方案
1. 修正ObjectMapper配置
创建ObjectMapper时必须注册JodaModule,同时保留Scala模块的注册,调整后的序列化代码如下:
val mapper = new ObjectMapper() with ScalaObjectMapper // 注册Joda模块与Scala模块(顺序不影响,但两者必须同时存在) mapper.registerModule(new JodaModule()) mapper.registerModule(DefaultScalaModule) mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS) // 可选:全局设置时区,避免格式中的时区偏移不一致 mapper.setTimeZone(TimeZone.getTimeZone("UTC")) val inputJson = new StringReader(mapper.writeValueAsString(sampleCaseClass))
2. 优化Case Class注解(可选)
你的Case Class注解已基本正确,可补充时区参数避免默认时区导致的格式差异:
import com.fasterxml.jackson.annotation.{JsonProperty, JsonFormat} import org.joda.time.DateTime case class SampleCaseClass( @JsonProperty("a") @JsonFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss.SSSZ", timezone = "UTC") // 显式指定时区 a: DateTime, @JsonProperty("b_id") b: String, @JsonProperty("c_id") c: String )
3. Spring Boot全局配置(适配你的环境)
在Spring Boot 2.7.6项目中,可通过配置类统一配置Jackson,避免手动重复创建ObjectMapper:
import com.fasterxml.jackson.databind.ObjectMapper import com.fasterxml.jackson.module.scala.DefaultScalaModule import com.fasterxml.jackson.datatype.joda.JodaModule import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration @Configuration class JacksonConfig { @Bean def objectMapper(): ObjectMapper = { val mapper = new ObjectMapper() mapper.registerModule(new JodaModule()) mapper.registerModule(DefaultScalaModule) mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS) mapper.setTimeZone(java.util.TimeZone.getTimeZone("UTC")) mapper } }
验证效果
修改后序列化SampleCaseClass实例,日期字段会输出指定格式的字符串,示例如下:
{"a":"1970-01-01T00:00:00.010+0000","b_id":"abc","c_id":"efg"}
反序列化也会自动识别该格式字符串并转换为Joda DateTime对象,完全适配Elasticsearch 7.17的字段要求。
内容的提问来源于stack exchange,提问作者nutim
相关产品推荐
相关产品推荐

