[英]Custom gson serialization for an abstract class
也許我正朝着錯誤的方向奔跑,但我有一份我想讀的元素清單。
我有一個抽象基類讓我們稱它為Person
:
public abstract class Person {
public int id;
public String name;
}
現在我有兩種可能的實現:
public class Hunter implements Person {
public int skill;
// and some more stuff
}
public class Zombie implements Person {
public int uglyness;
// and some more stuff
}
現在我有了這個例子JSON:
[
{"id":1, "type":"zombie", "name":"Ugly Tom", "uglyness":42},
{"id":2, "type":"hunter", "name":"Shoot in leg Joe", "skill":0}
]
如何將此JSON讀作List<Person>
?
我正在玩TypeAdapterFactory
一段時間,並試圖使用一個名為CustomizedTypeAdapterFactory
的類,因為我的真實結構比上面的有趣例子稍微復雜一點。
我結束了,我想用這個調用委托序列化:
return gson.getDelegateAdapter(this, resultType);
但是我不知道如何在運行時創建此調用所需的TypeToken<T>
。 有任何想法嗎?
如何將此JSON讀作List?
一種可能性是創建一個像工廠一樣的自定義反序列化器。
第一步是定義這個解串器
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");
}
}
}
它獲取與鍵“type”關聯的值,並選擇正確的類型來反序列化您當前正在讀取的對象。
然后,您需要在解析器中插入此反序列化器。
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);
}
}
}
用你的例子運行它,我得到:
Zombie{id=1; name=Ugly Tom; uglyness=42}
Hunter{id=2; name=Shoot in leg Joe; skill=0}
如果類型的值已經與類名對應,您可能還想使用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);
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.