如何解决 java.lang 对象多态性的 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

DESER之后= 1.533802404071E12

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

这种"豆子"的目的是充当"运输"工具。这意味着您应该真正知道运输的是什么。如果需要处理多种类型,请将该接口作为 Bean 类提供的一部分。

意义:

  • 确定将一个类用作该字段的类型。我会选择字符串以获得灵活性。Object不是一个好主意!
  • 提供 getter/setter,允许您设置/检索 Date 对象

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

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

最新更新