Android使用Gson反序列化LocalDateTime出现空指针异常怎么解决?
问题原因
Gson默认没有内置对java.time包下时间类型(包括LocalDateTime)的序列化/反序列化适配逻辑:
- 服务端Spring Boot如果没有专门配置Gson的Java时间模块,序列化LocalDateTime时会直接把类的内部字段拆解成嵌套的date、time对象输出,就是你看到的结构
- Android端的Gson在反序列化这个嵌套结构时,无法正确映射到LocalDateTime的内部构造逻辑,只会生成一个空壳LocalDateTime对象,内部的LocalDate、LocalTime属性都是null,调用相关方法时就会触发空指针。
解决方案
方案1:统一使用ISO标准时间字符串/时间戳序列化(推荐,兼容性最好)
修改服务端Spring Boot的Gson配置,注册Java时间适配逻辑,让LocalDateTime序列化为标准的ISO时间字符串(比如2024-05-20T12:34:56)或者13位时间戳,格式统一后两端都容易适配。
服务端配置示例:
- 引入对应版本的Gson依赖(如果未引入):
<!-- Maven 依赖 --> <dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> <version>2.10.1</version> </dependency>
- 自定义Gson序列化配置:
@Configuration public class GsonConfig { @Bean public Gson gson() { return new GsonBuilder() .registerTypeAdapter(LocalDateTime.class, (JsonSerializer<LocalDateTime>) (src, typeOfSrc, context) -> new JsonPrimitive(src.toString())) .create(); } }
Android端同步注册对应的反序列化器即可:
val customGson = GsonBuilder() .registerTypeAdapter(LocalDateTime::class.java, JsonDeserializer { json, _, _ -> LocalDateTime.parse(json.asString) }) .create()
方案2:不修改服务端输出结构,Android端自定义适配现有嵌套结构
如果服务端不能调整输出格式,就给Android端的Gson添加LocalDateTime的自定义反序列化器,手动解析嵌套的date、time字段构造LocalDateTime对象:
val customGson = GsonBuilder() .registerTypeAdapter(LocalDateTime::class.java, JsonDeserializer { json, _, _ -> val rootObj = json.asJsonObject // 解析日期字段 val dateObj = rootObj.getAsJsonObject("date") val day = dateObj.get("day").asInt val month = dateObj.get("month").asInt val year = dateObj.get("year").asInt // 解析时间字段 val timeObj = rootObj.getAsJsonObject("time") val hour = timeObj.get("hours").asInt val minute = timeObj.get("minutes").asInt val second = timeObj.get("seconds").asInt // 构造完整LocalDateTime实例 LocalDateTime.of(year, month, day, hour, minute, second) }) .create()
后续使用这个自定义配置的Gson实例去反序列化接口返回数据即可,不会再出现内部属性为空的问题。
内容的提问来源于stack exchange,提问作者Goncalo Condeco
相关产品推荐
相关产品推荐

