gpt4 book ai didi

java - gson - 多态变量的自定义反序列化器

转载 作者:塔克拉玛干 更新时间:2023-11-02 19:23:11 25 4
gpt4 key购买 nike

我正在使用 gson 将 java 对象与 json 对象相互转换。我遇到了多态性问题。

我有这些看起来像这样的请求:

{
"method": "getUser",
"methodParameters": {
"a": "b",
"c": "d",
"e": "f",
"data": {
"u": "v",
"x": "y"
}
},
"version": "1.3"
}

每个请求方法都有不同类型的数据对象。自然地,每个数据对象都扩展了一个名为 RequestData 的基类。

我试图创建一个自定义反序列化器,但由于它是请求对象而不是保存该方法的数据对象,我无法找到一种方法来知道要反序列化到哪个对象。

是否有可能在反序列化数据对象时以某种方式获取方法值,或者是否有其他更好的方法来解决这个问题?谢谢。

最佳答案

我遇到了类似的问题:正如 Tomek 所指出的,您需要一个自定义反序列化器,以及一个特定的 JSON 字段,您将在运行时使用它来决定要实例化哪个子类。

考虑以下类作为基类:

// Base class for a server sent event
public class ServerEvent
{
public static final String TYPEFIELDNAME = "eventType";

// Event type is used during deserialization to choose the right subclass
private final String eventType;

public ServerEvent(String eventType)
{
this.eventType = eventType;
}

public String toString()
{
return "eventType: " + eventType;
}
}

ServerEvent 有两个子类,每个子类都有不同的属性:

public class EventA extends ServerEvent 
{
private static final String EVENTTYPE = "eventa";
private int data;

public EventA()
{
super(EVENTTYPE);
}

// Helper function to register this class with ServerEventDeserializer
public static void register(ServerEventDeserializer deserializer)
{
deserializer.registerEvent(EVENTTYPE, EventA.class);
}

public String toString()
{
return super.toString() + ", data = " + data;
}
}

public class EventB extends ServerEvent
{
private static final String EVENTTYPE = "eventb";
private String name;

public EventB()
{
super(EVENTTYPE);
}

// Helper function to register this class with ServerEventDeserializer
public static void register(ServerEventDeserializer deserializer)
{
deserializer.registerEvent(EVENTTYPE, EventB.class);
}

public String toString()
{
return super.toString() + ", name = " + name;
}
}

两种可能的输入如下:

{ "eventType" : "eventa", "data" : 15 }
{ "eventType" : "eventb", "name" : "test" }

这是多态反序列化器:

// This class handles the polymorphic deserialization of ServerEvent class
public class ServerEventDeserializer implements JsonDeserializer<ServerEvent>
{
// Gson engine
private Gson gson;

// Map of subclasses
private Map<String, Class<? extends ServerEvent>> eventRegistry;

public ServerEventDeserializer()
{
gson = new Gson();
eventRegistry = new HashMap<String, Class<? extends ServerEvent>>();
}

// Registers a ServerEvent subclass
public void registerEvent(String event, Class<? extends ServerEvent> eventInstanceClass)
{
eventRegistry.put(event, eventInstanceClass);
}

@Override
public ServerEvent deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException
{
try
{
// Get the JSON object
JsonObject commandObject = json.getAsJsonObject();

// Read the field named "ServerEvent.TYPEFIELDNAME"
JsonElement commandTypeElement = commandObject.get(ServerEvent.TYPEFIELDNAME);

// Query the eventRegistry map to instance the right subclass
Class<? extends ServerEvent> commandInstanceClass = eventRegistry.get(commandTypeElement.getAsString());
ServerEvent command = gson.fromJson(json, commandInstanceClass);

return command;
}
catch (Exception e)
{
throw new RuntimeException(e);
}
}
}

我写了一个可以下载的最小工作示例 here .

关于java - gson - 多态变量的自定义反序列化器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26015085/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com