You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Gson自定义LocalDate序列化反序列化适配器运行报错问题咨询

问题定位

你遇到的报错和自定义Gson适配器本身无关,核心问题有2个:

  • 多余的JSONObject中转逻辑破坏了序列化流程
    你在代码里先执行了JSONObject json=new JSONObject(task),这一步用的是org.json库的反射序列化逻辑,完全不会读取你给Gson注册的自定义类型适配器。org.json会强行反射拆解LocalDate的内部私有字段,Java 9及以上版本的模块系统默认禁止外部代码访问JDK核心类的私有成员,所以直接抛出了字段不可访问的错误——你看到报错里提到LocalDateTime#date字段,就是org.json反射拆解时间类内部结构时触发的,这时候Gson的序列化逻辑还没开始执行。
  • 序列化器的日期格式化配置存在区域不匹配隐患
    你写的LocalDateSerializer里初始化DateTimeFormatter没有指定Locale,在中文等非英文系统环境下,序列化出来的月份是本地语言缩写,和反序列化器指定的英文Locale规则不匹配,就算解决了前面的反射报错,也会触发日期解析失败。
修复步骤
  1. 删除多余的JSONObject中转,直接用Gson序列化原始Task对象,让你注册的自定义适配器正常生效。
  2. 统一序列化和反序列化器的DateTimeFormatter Locale配置,避免跨环境解析失败。

修正后的LocalDateSerializer

public class LocalDateSerializer implements JsonSerializer<LocalDate> {
    // 和反序列化器保持一致,指定英文Locale
    private static final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("d-MMM-yyyy", Locale.ENGLISH);

    @Override
    public JsonElement serialize(LocalDate localDate, Type srcType, JsonSerializationContext context) {
        return new JsonPrimitive(formatter.format(localDate));
    }
}

修正后的测试代码

GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.registerTypeAdapter(LocalDate.class, new LocalDateSerializer());
gsonBuilder.registerTypeAdapter(LocalDate.class, new LocalDateDeserializer());
Gson gson = gsonBuilder.setPrettyPrinting().create();

LocalDate now = LocalDate.now();
Task task = new Task();
task.setID(1);
task.setDuration(2);
task.setID_Proiect(1);
task.setStarttime(now);

// 直接序列化原始对象,移除JSONObject中转逻辑
String aux1 = gson.toJson(task);
System.out.println(aux1);
Task t2 = gson.fromJson(aux1, Task.class);
优化建议

如果项目中大量使用Java 8引入的时间类型(LocalDate、LocalDateTime、LocalTime等),不需要手写每个类型的适配器,可以直接使用Gson官方维护的Java时间类型适配模块,一次性注册所有时间类型的标准适配器,减少手写代码的出错概率。


内容的提问来源于stack exchange,提问作者Hudini

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.04 16:18:27