Kotlin中Retrofit的Jackson转换器未生效问题求助
解决Retrofit+Jackson的两个核心问题:非空字段null兼容、日期格式化异常
一、非空字段接收null无报错的解决办法
你已经开启了Kotlin模块的StrictNullChecks,但还需要给ObjectMapper添加额外的反序列化配置,强制对非空字段的null值抛出异常:
- 在
ObjectMapper配置中添加以下反序列化开关:.enable(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES) .enable(DeserializationFeature.FAIL_ON_MISSING_CREATOR_PROPERTIES) .enable(DeserializationFeature.FAIL_ON_NULL_CREATOR_PROPERTIES) - 确保你的Kotlin data class字段确实声明为非空类型(比如
val date: LocalDate,而非val date: LocalDate?),且没有给默认值——如果字段有默认值,Jackson会用默认值替代null,不会触发报错。
二、日期格式化不符合预期的解决办法
你遇到的日期自动适配问题,是因为SimpleDateFormat默认是宽松模式(lenient=true),会自动忽略不匹配的格式部分。推荐两种解决思路:
方案1:使用JavaTimeModule处理Java 8+日期类型(推荐)
针对接口返回的ISO格式日期(如"2022-08-24T13:23:10Z"),用Jackson的JavaTimeModule处理更可靠:
- 确保引入依赖(Gradle示例):
implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.15.2' - 在
ObjectMapper中注册模块并配置格式:
这样接口返回的带T/Z的日期会被严格解析为private val jackson: ObjectMapper by lazy { val javaTimeModule = JavaTimeModule().apply { // 全局配置LocalDate的解析格式 addDeserializer( LocalDate::class.java, LocalDateDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")) ) } ObjectMapper() .registerModule(javaTimeModule) .disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS) .configure(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE, false) // 其他配置... }LocalDate,只保留年月日部分;如果格式完全不匹配,会直接抛出解析异常。
方案2:严格配置SimpleDateFormat(兼容java.util.Date)
如果坚持使用java.util.Date,需要关闭SimpleDateFormat的宽松模式,强制严格匹配格式:
val dateFormat = SimpleDateFormat("yyyy-MM-dd", Locale.getDefault()).apply { isLenient = false // 关闭宽松模式,格式不匹配直接报错 } objectMapper.setDateFormat(dateFormat)
如果需要兼容ISO格式并提取年月日,可以把格式改为"yyyy-MM-dd'T'HH:mm:ssX",后续再根据需求转换为仅日期的格式。
三、额外检查项
- 确保Retrofit仅添加了
JacksonConverterFactory,没有其他转换器(如Gson)被意外引入并优先使用; - 检查项目中是否有其他代码修改了
ObjectMapper的全局配置,导致你的自定义配置被覆盖。
内容的提问来源于stack exchange,提问作者Ionut J. Bejan
相关产品推荐
相关产品推荐

