【问题标题】:Java 8 LocalDateTime Deserialization using gson使用 gson 的 Java 8 LocalDateTime 反序列化
【发布时间】:2018-04-26 17:34:22
【问题描述】:

我想使用 gson 将包含 LocalDateTime 字段的 json 字符串反序列化到一个类中。

但这会引发空指针异常。

我的 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)

有什么想法吗?

谢谢

【问题讨论】:

    标签: java json gson


    【解决方案1】:

    通过帮助 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();
    

    【讨论】:

      【解决方案2】:

      如果您遇到同样的问题,但您还期望字符串格式的日期(例如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();
      

      【讨论】:

      • 注意:这是针对LocalDate,但可以使用@appel500 的答案轻松修改为LocalDateTime。
      猜你喜欢
      • 2023-04-04
      • 2017-03-12
      • 1970-01-01
      • 1970-01-01
      • 2019-11-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多