我正在使用Gson,我有一个对象,其中一个字段是Class
class A {
…
private Class aClass;
… }
当我使用默认的Gson对象将实例解析为Json时,aClass变为空。
知道为什么吗?
答案 0 :(得分:5)
您需要自定义类型适配器。这是一个例子:
package com.sopovs.moradanen;
import java.lang.reflect.Type;
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;
public class GsonClassTest {
public static void main(String[] args) {
Gson gson = new GsonBuilder()
.registerTypeAdapter(Class.class, new ClassTypeAdapter())
.setPrettyPrinting()
.create();
String json = gson.toJson(new Foo());
System.out.println(json);
Foo fromJson = gson.fromJson(json, Foo.class);
System.out.println(fromJson.boo.getName());
}
public static class ClassTypeAdapter implements JsonSerializer<Class<?>>, JsonDeserializer<Class<?>> {
@Override
public JsonElement serialize(Class<?> src, Type typeOfSrc, JsonSerializationContext context) {
return new JsonPrimitive(src.getName());
}
@Override
public Class<?> deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
throws JsonParseException {
try {
return Class.forName(json.getAsString());
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
}
public static class Foo {
Class<?> boo = String.class;
}
}
此代码的输出为:
{
"boo": "java.lang.String"
}
java.lang.String
答案 1 :(得分:3)
当我使用默认的Gson对象将实例解析为Json时,aClass变为空。
知道为什么吗?
在a comment in issue 340中,Gson项目经理解释道:
序列化类型实际上是一个安全问题,所以我们不希望默认支持它。恶意的.json文件可能会导致您的应用程序加载其他情况下不会加载的类;根据您的类路径加载某些类可能会对您的应用程序造成影响。
但是在你自己的应用程序中编写一个类型适配器以支持它是非常简单的。
当然,由于序列化与反序列化不同,我不明白这是对禁用序列化的解释,除非未提及的概念在某种意义上“平衡”序列化与反序列化的默认行为。