我正在进行下面的简单实验测试。
public class MyTest {
@Test
public void testing() {
GsonBuilder builder = new GsonBuilder();
builder.registerTypeAdapter(SubData.class, new SubDataImplInstanceCreator());
Gson gson = builder.create();
Dataclass data = new Dataclass();
data.key1 = "abc";
SubDataImpl subData = new SubDataImpl();
subData.hello = "ttt";
data.sub = subData;
String jsonValue = gson.toJson(data);
System.out.println(jsonValue);
Dataclass data2 = gson.fromJson(jsonValue, Dataclass.class);
System.out.println(gson.toJson(data2));
}
class Dataclass implements Serializable {
String key1;
SubData sub;
}
interface SubData {
String getHello();
}
class SubDataImpl implements SubData, Serializable {
String hello;
@Override
public String getHello() {
return hello;
}
}
public class SubDataImplInstanceCreator implements InstanceCreator<SubDataImpl> {
@Override
public SubDataImpl createInstance(Type type) {
return new SubDataImpl();
}
}
}
我希望它能够回归
{"key1":"abc","sub":{"hello":"ttt"}}
{"key1":"abc","sub":{"hello":"ttt"}}
因为它们基本上是序列化和反序列化的相同数据。
但是,当我运行它时,我得到了
{"key1":"abc","sub":{"hello":"ttt"}}
{"key1":"abc","sub":{}}
为什么在反序列化Json字符串后,我放弃了SubData
值?我的代码中遗漏了什么吗?
答案 0 :(得分:2)
您似乎已经点击此bug,建议的解决方案是使用TypeAdapter作为界面。
快速而肮脏的实施(使用它代替SubDataImplInstanceTypeAdapter)
public class SubDataImplInstanceTypeAdapter implements JsonDeserializer<SubDataImpl>, JsonSerializer<SubDataImpl> {
@Override
public SubDataImpl deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
SubDataImpl impl = new SubDataImpl();
JsonObject object = json.getAsJsonObject();
impl.setHello(object.get("hello").getAsString());
return impl;
}
@Override
public JsonElement serialize(SubDataImpl src, Type typeOfSrc, JsonSerializationContext context) {
return context.serialize(src);
}
}
答案 1 :(得分:0)
我使用以下
public class MyTest {
@Test
public void testing() {
GsonBuilder builder = new GsonBuilder();
builder.registerTypeAdapter(SubData.class, new SubDataTypeAdapter());
Gson gson = builder.create();
Dataclass data = new Dataclass();
data.key1 = "abc";
SubDataImpl subData = new SubDataImpl();
subData.hello = "ttt";
data.sub = subData;
String jsonValue = gson.toJson(data);
System.out.println(jsonValue);
Dataclass data2 = gson.fromJson(jsonValue, Dataclass.class);
System.out.println(gson.toJson(data2));
}
class SubDataTypeAdapter extends TypeAdapter<SubDataImpl> {
@Override
public void write(JsonWriter out, final SubDataImpl subData) throws IOException {
out.beginObject();
out.name("hello").value(subData.getHello());
out.endObject();
}
@Override
public SubDataImpl read(JsonReader in) throws IOException {
final SubDataImpl subData = new SubDataImpl();
in.beginObject();
while (in.hasNext()) {
switch (in.nextName()) {
case "hello":
subData.hello = in.nextString();
break;
}
}
in.endObject();
return subData;
}
}
class Dataclass implements Serializable {
String key1;
SubData sub;
}
abstract class SubData {
abstract String getHello();
}
class SubDataImpl extends SubData implements Serializable {
String hello;
@Override
public String getHello() {
return hello;
}
}
}