【问题标题】:Serialize Java 8 LocalDate as yyyy-mm-dd with Gson使用 Gson 将 Java 8 LocalDate 序列化为 yyyy-mm-dd
【发布时间】:2016-08-28 15:38:51
【问题描述】:

我正在使用 Java 8 和最新的 RELEASE 版本(通过 Maven)Gson。 如果我序列化 LocalDate 我会得到这样的结果

"birthday": {
        "year": 1997,
        "month": 11,
        "day": 25
}

我更喜欢"birthday": "1997-11-25"。 Gson 是否还支持开箱即用的更简洁格式,还是我必须为LocalDates 实现自定义序列化程序?

(我尝试过gsonBuilder.setDateFormat(DateFormat.SHORT),但这似乎没有什么不同。)

【问题讨论】:

  • stackoverflow.com/questions/6873020/gson-date-format 应该为您指明正确的方向。
  • 你很可能需要安装一个custom TypeAdapter
  • 查看com.google.gson.internal.bind 中的类,LocalDate 没有类型适配器(在 gson 2.7 中)。
  • @JornVernee 好主意。如果您想发表您的评论作为答案,我会接受。
  • @Drux,不,没关系,它并不能真正解决问题。我认为你的答案对未来的读者来说更好。

标签: java gson


【解决方案1】:

在另行通知之前,我已经实现了一个自定义序列化程序,如下所示:

class LocalDateAdapter implements JsonSerializer<LocalDate> {

    public JsonElement serialize(LocalDate date, Type typeOfSrc, JsonSerializationContext context) {
        return new JsonPrimitive(date.format(DateTimeFormatter.ISO_LOCAL_DATE)); // "yyyy-mm-dd"
    }
}

它可以安装,例如像这样:

Gson gson = new GsonBuilder()
        .setPrettyPrinting()
        .registerTypeAdapter(LocalDate.class, new LocalDateAdapter())
        .create();

【讨论】:

  • 简单而完美。谢谢:) +1
【解决方案2】:

我使用以下,支持读/写和空值:

class LocalDateAdapter extends TypeAdapter<LocalDate> {
    @Override
    public void write(final JsonWriter jsonWriter, final LocalDate localDate) throws IOException {
        if (localDate == null) {
            jsonWriter.nullValue();
        } else {
            jsonWriter.value(localDate.toString());
        }
    }

    @Override
    public LocalDate read(final JsonReader jsonReader) throws IOException {
        if (jsonReader.peek() == JsonToken.NULL) {
            jsonReader.nextNull();
            return null;
        } else {
            return LocalDate.parse(jsonReader.nextString());
        }
    }
}

注册为@Drux 说:

return new GsonBuilder()
        .registerTypeAdapter(LocalDate.class, new LocalDateAdapter())
        .create();

EDIT 2019-04-04更简单的实现

private static final class LocalDateAdapter extends TypeAdapter<LocalDate> {
    @Override
    public void write( final JsonWriter jsonWriter, final LocalDate localDate ) throws IOException {
        jsonWriter.value(localDate.toString());
    }

    @Override
    public LocalDate read( final JsonReader jsonReader ) throws IOException {
        return LocalDate.parse(jsonReader.nextString());
    }
}

您可以通过注册nullSafe() 包装版本来添加null 支持:

new GsonBuilder()
      .registerTypeAdapter(LocalDate.class, new LocalDateAdapter().nullSafe())

【讨论】:

  • 编辑:添加了对 jsonReader.nextNull() 的调用以正确使用 null 值。
  • 您的编辑尚未添加。究竟解决了什么问题?
【解决方案3】:

支持序列化和反序列化的 Kotlin 版本:

class LocalDateTypeAdapter : TypeAdapter<LocalDate>() {

    override fun write(out: JsonWriter, value: LocalDate) {
        out.value(DateTimeFormatter.ISO_LOCAL_DATE.format(value))
    }

    override fun read(input: JsonReader): LocalDate = LocalDate.parse(input.nextString())
}

向您的 GsonBuilder 注册。使用nullSafe() 换行以获得null 支持:

GsonBuilder().registerTypeAdapter(LocalDate::class.java, LocalDateTypeAdapter().nullSafe())

【讨论】:

  • 完美,这适用于 Kotlin 项目。非常感谢!
  • 不适用于子对象(例如 LocalDates 列表)
【解决方案4】:

在上游报告为 https://github.com/google/gson/issues/1059 。来自上游的当前建议是使用 https://github.com/gkopff/gson-javatime-serialisers 插件。

【讨论】:

    猜你喜欢
    • 2021-12-02
    • 1970-01-01
    • 2016-06-21
    • 1970-01-01
    • 1970-01-01
    • 2023-03-08
    • 1970-01-01
    • 1970-01-01
    • 2020-07-05
    相关资源
    最近更新 更多