使用gson的Java 8本地日期时间反序列化

eqqqjvef  于 2022-11-06  发布在  Java
关注(0)|答案(2)|浏览(180)

我想使用gson将一个包含LocalDateTime字段的json String反序列化到一个类。
但这会引发空指针异常。
我的JSON:

metrics": {
"measurements": [
{
"serviceName": "myService",
"start": {
"year": 2018,
"month": "APRIL",
"dayOfMonth": 26,
"dayOfWeek": "THURSDAY",
"dayOfYear": 116,
"monthValue": 4,
"hour": 18,
"minute": 53,
"second": 51,
"nano": 243000000,
"chronology": {
"id": "ISO",
"calendarType": "iso8601"
}
},
"stop": {
"year": 2018,
"month": "APRIL",
"dayOfMonth": 26,
"dayOfWeek": "THURSDAY",
"dayOfYear": 116,
"monthValue": 4,
"hour": 18,
"minute": 53,
"second": 51,
"nano": 841000000,
"chronology": {
"id": "ISO",
"calendarType": "iso8601"
}
},
"processingTime": 598
}

我用来获取对象的代码:

Metrics metrics = gson.fromJson(jsonString, Metrics.class);

但是gson只能反序列化我的对象的processingTime字段。
我也试过这个:
Java 8 LocalDateTime deserialized using Gson
但这导致

Caused by: java.lang.IllegalStateException: This is not a JSON Primitive.
    at com.google.gson.JsonElement.getAsJsonPrimitive(JsonElement.java:122)
    at com.foo.config.AppConfig.lambda$gson$1(AppConfig.java:63)

有什么想法吗?
谢谢

xfb7svmp

xfb7svmp1#

我能够通过帮助LocalDateTime类型适配器自己解决这个问题:

@Bean
    public Gson gson() {
        return new GsonBuilder()
                .registerTypeAdapter(LocalDateTime.class, new JsonDeserializer<LocalDateTime>() {
                    @Override
                    public LocalDateTime deserialize(JsonElement json, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException {
                        JsonObject jo = json.getAsJsonObject();
                        return LocalDateTime.of(jo.get("year").getAsInt(),
                                jo.get("monthValue").getAsInt(),
                                jo.get("dayOfMonth").getAsInt(),
                                jo.get("hour").getAsInt(),
                                jo.get("minute").getAsInt(),
                                jo.get("second").getAsInt(),
                                jo.get("nano").getAsInt());
                    }
                }).create();
zfciruhq

zfciruhq2#

如果您遇到了同样的问题,但您还需要字符串格式的日期(例如2019-11-18),您可以使用try catch块,如下所示:

private static final Gson gson = new GsonBuilder().registerTypeAdapter(LocalDate.class, new JsonDeserializer<LocalDate>() {
    @Override
    public LocalDate deserialize(JsonElement json, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException {
        try {
            return LocalDate.parse(json.getAsJsonPrimitive().getAsString());
        } catch (IllegalStateException e) {
            JsonObject jo = json.getAsJsonObject();
            return LocalDate.of(jo.get("year").getAsInt(), jo.get("monthValue").getAsInt(), jo.get("dayOfMonth").getAsInt());
        }
    }
}).create();

相关问题