java - 如何解决java.lang对象多态性的Gson反序列化问题

标签 java gson

我使用 gson 进行反序列化。我的类有一个实例字段,它是对象类型,因为有时它可以用字符串或日期对象实例化。但在反序列化时,我无法将其获取为日期或字符串类型。 我知道有一个使用 RuntimeTypeAdapterFactory 的解决方案,但我无法使用它,因为我无法添加 RuntimeTypeAdapterFactory 解决方案( https://futurestud.io/tutorials/how-to-deserialize-a-list-of-polymorphic-objects-with-gson ),因为我无法将“type”字段添加到 java.lang.String 或 java.util.Date。

有什么办法可以解决这个问题吗?

请参阅此问题的示例代码

import java.lang.reflect.Type;
import java.text.SimpleDateFormat;

import java.util.Date;


import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonParseException;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import com.google.gson.reflect.TypeToken;

public class GsonSer {

    String name;
     Object dob;

    public GsonSer(String name, Date dob) {
        this.name = name;
        this.dob = dob;
    }

    static class JsonDateSerDeserializer implements JsonSerializer<Date>, JsonDeserializer<Date> {

        @Override
        public JsonElement serialize(Date src, Type typeOfSrc, JsonSerializationContext context) {

            return new JsonPrimitive(src.getTime());
        }

        @Override
        public Date deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
                throws JsonParseException {
            Date parsed = new Date(json.getAsLong());
            return parsed;
        }

    }

    public static void main(String[] args) {
        GsonSer ser = new GsonSer("name", new Date());
     Type DATE_TYPE = new TypeToken<Date>() {
        }.getType();
        Gson gson = new GsonBuilder().registerTypeAdapter(DATE_TYPE, new JsonDateSerDeserializer())
                .create();
        String date = gson.toJson(ser);
        System.out.println("Original = " + ser.dob + "\n");
        GsonSer deser = gson.fromJson(date, GsonSer.class);
        System.out.println("after deser = " + deser.dob + "\n");

    }
}

//输出

原始 = 2018 年 8 月 9 日星期四 10:13:24 CEST

得瑟之后 = 1.533802404071E12

最佳答案

一个明显的非答案:不要这样做。

这种“ bean ”的目的是充当“运输”工具。这意味着您应该确切真正了解所传输的内容。如果您需要处理多种类型,请将其作为 bean 类提供的接口(interface)的一部分。

含义:

  • 决定使用一个类作为该字段的类型。为了灵活性,我会选择 String。 对象不是一个好主意!
  • 提供 getter/setter,允许您设置/检索 Date 对象

换句话说:不要试图让 gson 为你解决歧义。

简单地避免 bean 内的歧义,因此您无需任何特殊设置即可使用 gson。让 bean 包含一个字符串(理想情况下,您可以非正式地指定允许的格式),并使 bean 还接受代表日期/时间的 Date/Instant/Whatever 对象)。

关于java - 如何解决java.lang对象多态性的Gson反序列化问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51761218/

相关文章:

android - 自定义序列化程序 - 使用 GSON 反序列化 BasicNameValuePair 列表

spring-boot - 无法写入 JSON : JsonObject; nested exception is com. fastxml.jackson.databind.JsonMappingException: JsonObject

java - 在泛型类中实现 compareTo() 方法

Java FreeMarker : Replacing a ${variable} with a collection instead of an instance of an object

java - 防止扫描仪读取 Java 中的剩余输入

java - 如何使用 BlackBerry SDK API 缩放图像

Json 到 Gson - 建模

java - Gson - TypeAdapterFactory 中的 JsonSerializer 或 TypeAdapter 中的通用类型

android - 自定义对象的 ArrayList 不使用 GSON 保存到 SharedPreferences

java - 如何使用gradle type:exec下载apollo模式