rek*_*ire 3 java serialization gson
也许我跑错了方向,但我有一个我想阅读的元素列表。
我有一个抽象基类,我们称之为Person:
public abstract class Person {
public int id;
public String name;
}
Run Code Online (Sandbox Code Playgroud)
现在我有两种可能的实现:
public class Hunter implements Person {
public int skill;
// and some more stuff
}
public class Zombie implements Person {
public int uglyness;
// and some more stuff
}
Run Code Online (Sandbox Code Playgroud)
现在我有这个示例 JSON:
[
{"id":1, "type":"zombie", "name":"Ugly Tom", "uglyness":42},
{"id":2, "type":"hunter", "name":"Shoot in leg Joe", "skill":0}
]
Run Code Online (Sandbox Code Playgroud)
我怎样才能读这个 JSON 为List<Person>?
我玩了一段时间TypeAdapterFactory并尝试使用一个名为的类,CustomizedTypeAdapterFactory因为我的真实结构比上面有趣的例子要复杂一些。
我最后说我想通过这个调用委托序列化:
return gson.getDelegateAdapter(this, resultType);
Run Code Online (Sandbox Code Playgroud)
但是,我不知道如何在运行时创建TypeToken<T>此调用所需的内容。有任何想法吗?
如何将此 JSON 作为列表读取?
一种可能性是创建一个像工厂一样的自定义解串器。
第一步是定义这个解串器
class PersonJsonDeserializer implements JsonDeserializer<Person> {
@Override
public Person deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
String type = json.getAsJsonObject().get("type").getAsString();
switch(type) {
case "zombie":
return context.deserialize(json, Zombie.class);
case "hunter":
return context.deserialize(json, Hunter.class);
default:
throw new IllegalArgumentException("Neither zombie or hunter");
}
}
}
Run Code Online (Sandbox Code Playgroud)
它获取与键“类型”关联的值并选择正确的类型来反序列化您当前正在读取的对象。
然后,您需要在解析器中插入这个反序列化器。
public class GsonTest {
public static void main(String[] args) {
String json = "[\n" +
" {\"id\":1, \"type\":\"zombie\", \"name\":\"Ugly Tom\", \"uglyness\":42},\n" +
" {\"id\":2, \"type\":\"hunter\", \"name\":\"Shoot in leg Joe\", \"skill\":0}\n" +
"]";
Gson gson = new GsonBuilder().registerTypeAdapter(Person.class, new PersonJsonDeserializer()).create();
Type type = new TypeToken<List<Person>>(){}.getType();
List<Person> list = gson.fromJson(json, type);
for(Person p : list) {
System.out.println(p);
}
}
}
Run Code Online (Sandbox Code Playgroud)
用你的例子运行它,我得到:
Zombie{id=1; name=Ugly Tom; uglyness=42}
Hunter{id=2; name=Shoot in leg Joe; skill=0}
Run Code Online (Sandbox Code Playgroud)
如果类型的值已经对应于类名,您可能还想使用Class.forName:
class PersonJsonDeserializer implements JsonDeserializer<Person> {
@Override
public Person deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
String className = json.getAsJsonObject().get("type").getAsString();
className = Character.toUpperCase(className.charAt(0)) + className.substring(1);
try {
return context.deserialize(json, Class.forName(className));
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1509 次 |
| 最近记录: |