我有一个 netty 解码器,它使用 GSon 将来自 Web 客户端的 JSON 转换为适当的 Java 对象。
要求是:
客户端可能会发送不相关的类、A 类、B 类、C 类等,但我想在管道中使用相同 单例解码器实例进行转换(因为我使用 spring 来配置它)。我面临的问题是我需要事先知道 class
对象。
public Object decode()
{
gson.fromJson(jsonString, A.class);
}
这无法解码 B 或 C。我的库的用户现在需要为每个类编写单独的解码器,而不是稍后进行强制转换。我能看到这样做的唯一方法是从 Web 客户端的 JSON 字符串中传递类的字符串名称说“org.example.C”,在解码器中解析它然后使用 Class.forName
获取类。有更好的方法吗?
最佳答案
GSon 必须知道匹配 json 字符串的类。如果你不想用 fromJson() 提供它,你实际上可以在 Json 中指定它。一种方法是定义一个接口(interface)并在其上绑定(bind)一个适配器。
喜欢:
class A implements MyInterface {
// ...
}
public Object decode()
{
Gson gson = builder.registerTypeAdapter(MyInterface.class, new MyInterfaceAdapter());
MyInterface a = gson.fromJson(jsonString, MyInterface.class);
}
适配器可以是这样的:
public final class MYInterfaceAdapter implements JsonDeserializer<MyInterface>, JsonSerializer<MyInterface> {
private static final String PROP_NAME = "myClass";
@Override
public MyInterface deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
try {
String classPath = json.getAsJsonObject().getAsJsonPrimitive(PROP_NAME).getAsString();
Class<MyInterface> cls = (Class<MyInterface>) Class.forName(classPath);
return (MyInterface) context.deserialize(json, cls);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return null;
}
@Override
public JsonElement serialize(MyInterface src, Type typeOfSrc, JsonSerializationContext context) {
// note : won't work, you must delegate this
JsonObject jo = context.serialize(src).getAsJsonObject();
String classPath = src.getClass().getName();
jo.add(PROP_NAME, new JsonPrimitive(classPath));
return jo;
}
}
关于java - 使用 GSon 从 JSon 转换为多个未知的 java 对象类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17049684/