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

时间:2018-08-09 07:32:12

标签: java gson

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

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

请参阅此问题的示例代码

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

deser之后= 1.533802404071E12

1 个答案:

答案 0 :(得分:2)

一个独特的非答案:不要那样做。

这类“豆子”的重点是充当“运输”工具。这意味着您应该真正确切地知道要运输的内容。如果您需要处理多种类型,请将其作为bean类提供的 interface 的一部分。

含义:

  • 确定要用作该字段类型的一个类。我会选择String来提高灵活性。 Object不是一个好主意!
  • 提供允许您设置/检索Date对象的getter / setters

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

简单地避免在bean内 产生歧义,因此您可以使用gson而不进行任何特殊设置。让bean包含一个String(理想情况下,您将非正式地指定允许的 formats ),并使bean也接受Date / Instant /代表日期/时间的任何对象)。