使用Gson对Java 8 LocalDateTime进行反序列化



我有一个json的日期-时间属性,格式为"2014-03-10T18:46:40.000Z",我想使用Gson将其反序列化为java.time.LocalDateTime字段。

当我试图反序列化时,我得到错误:

java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING

在对LocalDateTime属性进行反序列化时发生错误,因为GSON无法解析该属性的值,因为它不知道LocalDateTime对象。

使用GsonBuilder的registerTypeAdapter方法来定义自定义LocalDateTime适配器。下面的代码片段将帮助您反序列化LocalDateTime属性。

Gson gson = new GsonBuilder().registerTypeAdapter(LocalDateTime.class, new JsonDeserializer<LocalDateTime>() {
    @Override
    public LocalDateTime deserialize(JsonElement json, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException {
        Instant instant = Instant.ofEpochMilli(json.getAsJsonPrimitive().getAsLong());
        return LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
    }
}).create();

扩展@Randula的答案,将分区日期时间字符串(2014-03-10T18:46:40.000Z)解析为JSON:

Gson gson = new GsonBuilder().registerTypeAdapter(LocalDateTime.class, new JsonDeserializer<LocalDateTime>() {
@Override
public LocalDateTime deserialize(JsonElement json, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException {
    return ZonedDateTime.parse(json.getAsJsonPrimitive().getAsString()).toLocalDateTime();
}
}).create();

进一步扩展@Evers的回答:

你可以用lambda进一步简化:

GSON GSON = new GsonBuilder().registerTypeAdapter(LocalDateTime.class, (JsonDeserializer<LocalDateTime>) (json, type, jsonDeserializationContext) ->
    ZonedDateTime.parse(json.getAsJsonPrimitive().getAsString()).toLocalDateTime()).create();

以下方法对我有效。

Java:

Gson gson = new GsonBuilder().registerTypeAdapter(LocalDateTime.class, new JsonDeserializer<LocalDateTime>() { 
@Override 
public LocalDateTime deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { 
return LocalDateTime.parse(json.getAsString(), DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm")); } 
}).create();
Test test = gson.fromJson(stringJson, Test.class);

其中stringJson是一个Json,存储为String类型

Json:

"dateField":"2020-01-30 15:00"

其中dateFieldLocalDateTime类型,存在于stringJson字符串变量中

如上所述,您也可以使用已经可用的序列化器。

https://github.com/gkopff/gson-javatime-serialisers

你把它包含在你的项目中。

<dependency>
  <groupId>com.fatboyindustrial.gson-javatime-serialisers</groupId>
  <artifactId>gson-javatime-serialisers</artifactId>
  <version>1.1.2</version>
</dependency>

然后将其包含到GsonBuilder进程

final Gson gson = Converters.registerOffsetDateTime(new GsonBuilder()).create();
final OffsetDateTime original = OffsetDateTime.now();
final String json = gson.toJson(original);
final OffsetDateTime reconstituted = gson.fromJson(json, OffsetDateTime.class);

为避免不清楚,不同的类类型有不同的方法

进一步放大@Nicholas Terry的回答:

你可能还需要一个序列化器:

String dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(dateFormat);
GSON gson = new GsonBuilder()
    .registerTypeAdapter(
        LocalDateTime.class,
        (JsonDeserializer<LocalDateTime>) (json, type, jsonDeserializationContext) ->
            ZonedDateTime.parse(json.getAsJsonPrimitive().getAsString()).toLocalDateTime()
    )
    .registerTypeAdapter(
        LocalDateTime.class,
        (JsonSerializer<LocalDateTime>) (localDate, type, jsonSerializationContext) ->
            new JsonPrimitive(formatter.format(localDate)
    )
    .create();

或kotlin版本:

val dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"
val formatter = DateTimeFormatter.ofPattern(dateFormat)
val gson: Gson = GsonBuilder()
    .registerTypeAdapter(
        LocalDateTime::class.java,
        JsonDeserializer { json, type, jsonDeserializationContext -> 
            ZonedDateTime.parse(json.asJsonPrimitive.asString).toLocalDateTime()
        } as JsonDeserializer<LocalDateTime?>
    )
    .registerTypeAdapter(
        LocalDateTime::class.java,
        JsonSerializer<LocalDateTime?> { localDate, type, jsonDeserializationContext ->
            JsonPrimitive(formatter.format(localDate))
        }
    )
    .create()

相关内容

  • 没有找到相关文章

最新更新