gpt4 book ai didi

java - Gson反序列化接口(interface)到它的类实现

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

我正在使用 Retrofit 2.1.0converter-gson:2.1.0 并单独使用 gson:2.6.2 以便自定义序列化/反序列化。问题是我的 POJO 应该隐藏在接口(interface)后面,我想告诉 Gson 哪个类应该是反序列化接口(interface)。反序列化/序列化后Retrofit应该可以返回接口(interface)。如果我可以利用泛型并轻松创建一种方法来告诉 Gson 或 Retrofit 将 FooInterface 序列化/反序列化为 FooClass,那就太好了。

最佳答案

我假设您想为所有接口(interface)及其各自的实现创建一个反序列化器。请按照以下步骤操作:

1. 创建一个将由您的其他应用程序界面扩展的基本界面。需要为您的所有接口(interface)和实现类创建一个反序列化器。

public interface Convertable {
String getClassName();
}

2. 创建您的功能接口(interface)和实现类。例如,我们将它们命名为 FooInterface 和 FooClass。 FooInterface 应该扩展 Convertable 接口(interface)。

FooInterface

public interface FooInterface extends Convertable {

}

FooClass

public class FooClass implements FooInterface {

// DISCRIMINATOR FIELD
private final String className;

private String field1;

private String field2;

public FooClass() {
this.className = getClass().getName();
}

public String getClassName() {
return className;
}

public String getField1() {
return field1;
}

public void setField1(String field1) {
this.field1 = field1;
}

public String getField2() {
return field2;
}

public void setField2(String field2) {
this.field2 = field2;
}

}

请注意,getClassName() 返回的值用作鉴别器字段,将在 Gson 反序列化器(下一步)中用于初始化可返回实例。 我假设你的序列化器和反序列化器类将驻留在同一个包中,即使它们位于不同的客户端和服务器应用程序中也是如此。如果不是,那么你将需要更改 getClassInstance() 实现,但会是这样做非常简单。

3.为您的所有应用程序实现自定义 Gson 序列化器

import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParseException;
import com.google.gson.JsonPrimitive;

public class ConvertableDeserializer<T extends Convertable> implements JsonDeserializer<T> {

private static final String CLASSNAME = "className";

public T deserialize(final JsonElement jsonElement, final Type type,
final JsonDeserializationContext deserializationContext
) throws JsonParseException {

final JsonObject jsonObject = jsonElement.getAsJsonObject();
final JsonPrimitive prim = (JsonPrimitive) jsonObject.get(CLASSNAME);
final String className = prim.getAsString();
final Class<T> clazz = getClassInstance(className);
return deserializationContext.deserialize(jsonObject, clazz);
}

@SuppressWarnings("unchecked")
public Class<T> getClassInstance(String className) {
try {
return (Class<T>) Class.forName(className);
} catch (ClassNotFoundException cnfe) {
throw new JsonParseException(cnfe.getMessage());
}
}

}

4.向Gson注册Deserializer并初始化retrofit

 private static GsonConverterFactory buildGsonConverter() {

final GsonBuilder builder = new GsonBuilder();

// Adding custom deserializers
builder.registerTypeAdapter(FooInterface.class,
new ConvertableDeserializer<FooInterface>());
final Gson gson = builder.create();

return GsonConverterFactory.create(myGson);
}


public void initRetrofit() {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("REST_ENDPOINT")
.addConverterFactory(buildGsonConverter())
.client(httpClient)
.build();
}

如果需要,您可以为所有实现注册适配器,使用:

builder.registerTypeAdapter(Convertable.class, new ConvertableDeserializer<Convertable>());

关于java - Gson反序列化接口(interface)到它的类实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38071530/

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