使用Gson将Java 8本地日期序列化为yyyy-mm-dd

g6baxovj  于 2022-10-30  发布在  Java
关注(0)|答案(5)|浏览(110)

我使用的是Java 8和Gson的最新RELEASE版本(通过Maven)。

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

在这里我更喜欢"birthday": "1997-11-25"。Gson是否也支持更简洁的现成格式,或者我是否必须为LocalDate实现一个自定义的序列化程序?
(我试过gsonBuilder.setDateFormat(DateFormat.SHORT),但似乎没有什么区别。)

h4cxqtbf

h4cxqtbf1#

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

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();
0sgqnhkj

0sgqnhkj2#

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

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();

编辑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() Package 版本来添加null支持:

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

qoefvg9y3#

支持序列化和反序列化的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() Package 以获得null支持:

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

hc2pp10m5#

由于某些原因,使用上述类和.nullSafe()不起作用,因为我仍然得到这个JDK 17和Gson异常:

Unable to make field private final java.time.LocalDate java.time.LocalDateTime.date accessible: module java.base does not "opens java.time"

所以我使用了这个带有空值检查的自定义TypeAdapter:

public class LocalDateTimeTypeAdapter extends TypeAdapter<LocalDateTime> {

    @Override
    public void write(final JsonWriter jsonWriter, final LocalDateTime localDate) throws IOException {
        if (localDate == null) {
            jsonWriter.nullValue();
            return;
        }
        jsonWriter.value(localDate.toString());
    }

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

相关问题