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

如何解决java.lang对象多态性的Gson反序列化问题,java,gson,Java,Gson,我使用gson进行反序列化。我的类有一个实例字段,它是一个对象类型,因为有时它可以用String或Date对象实例化。但在反序列化之后,我无法将其作为日期或字符串类型。 我知道有一个使用RuntimeTypeAdapterFactory的解决方案,但我不能使用它,因为我不能添加RuntimeTypeAdapterFactory解决方案(),因为我不能将“type”字段添加到java.lang.String或java.util.Date 我有办法解决这个问题吗 请参阅此问题的示例代码 import

我使用gson进行反序列化。我的类有一个实例字段,它是一个对象类型,因为有时它可以用String或Date对象实例化。但在反序列化之后,我无法将其作为日期或字符串类型。 我知道有一个使用RuntimeTypeAdapterFactory的解决方案,但我不能使用它,因为我不能添加RuntimeTypeAdapterFactory解决方案(),因为我不能将“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");

    }
}
import java.lang.reflect.Type;
导入java.text.simpleDataFormat;
导入java.util.Date;
导入com.google.gson.gson;
导入com.google.gson.GsonBuilder;
导入com.google.gson.JsonDeserializationContext;
导入com.google.gson.JsonDeserializer;
导入com.google.gson.JsonElement;
导入com.google.gson.JsonParseException;
导入com.google.gson.JsonPrimitive;
导入com.google.gson.JsonSerializationContext;
导入com.google.gson.JsonSerializer;
导入com.google.gson.reflect.TypeToken;
公共类GsonSer{
字符串名;
对象dob;
公共GsonSer(字符串名称、日期dob){
this.name=名称;
this.dob=dob;
}
静态类JsonDateSerDeserializer实现JsonSerializer,JsonDeserializer{
@凌驾
公共JsonElement序列化(日期src、类型typeOfSrc、JsonSerializationContext){
返回新的JsonPrimitive(src.getTime());
}
@凌驾
公共日期反序列化(JsonElement json,类型typeOfT,JsonDeserializationContext)
抛出JsonParseException{
解析日期=新日期(json.getAsLong());
返回解析;
}
}
公共静态void main(字符串[]args){
GsonSer ser=新GsonSer(“名称”,新日期());
类型日期\类型=新类型令牌(){
}.getType();
Gson Gson=new GsonBuilder().registerTypeAdapter(日期类型,新的JsonDateSerDeserializer())
.create();
字符串date=gson.toJson(ser);
System.out.println(“Original=“+ser.dob+”\n”);
GsonSer-desr=gson.fromJson(日期,GsonSer.class);
System.out.println(“在desr=“+desr.dob+”\n”)之后;
}
}
//输出

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


在desr=1.533802404071E12之后,一个明显的非答案:不要这样做

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

意思是:

  • 决定使用一个类作为该字段的类型。为了灵活性,我会用绳子<代码>对象不是一个好主意
  • 提供允许您设置/检索日期对象的getter/setter
换句话说:不要试图让gson为您解决歧义


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

您能添加代码给出的输出吗?它在反序列化后将dob显示为一个双倍值。我感谢您的快速恢复!