Представьте себе следующее JSON для библиотеки книг:
{
"books": [{
"id": 562,
"name": "This is a booktitle"
},
{
"id": 875,
"name": "This is another booktitle"
}
]
}
Чтобы получить больше информации о первой книге, я могу просто подать запрос https://thislibrarydoesnotexists.com/books/562
, который вернет следующее JSON:
{
"name": "This is a booktitle",
"pages": 137,
"blurp": "This book is about the booktitle",
"authors": [{
"name": "Generic Author",
"id": 78
}]
}
Теперь я могу запросить дополнительную информацию об авторе, используя запрос https://thislibrarydoesnotexists.com/authors/78
, и эта игра будет включаться go довольно долго, пока я не получу всю информацию.
Сейчас моя цель состоит в том, чтобы иметь следующую java структуру класса:
class Library{
List<Book> books
}
class Book{
String name;
int pages;
String blurp;
List<Author> authors;
}
class Author{...}
Но как написать собственный десериализатор для этого? На данный момент это моя лучшая попытка:
final Gson defaultGson = new GsonBuilder.create();
GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.registerTypeAdapter(Book.class, new JsonDeserializer<Book>() {
@Override
public Skill deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
throws JsonParseException {
JsonObject jsonObject = json.getAsJsonObject();
if(jsonObject.has("id")) { //It is just a link to a book
String bookJson = getJson("https://thislibrarydoesnotexists.com/books/" + jsonObject.get("id").getAsInt());
Book book = gson.fromJson(bookJson, Book.class);
return book;
}else {
Book book = defaultGson.fromJson(json, Book.class); //#1
return book;
}
}
});
gson = gsonBuilder.create();
Это решение не выполнено на # 1, поскольку пользовательский десериализатор для авторов не будет использован.
Как правильно решить эту проблему?
- Создать объект Book вручную в другом случае? // Много работы для сложного API
- Использовать несколько Gsons с какой-то иерархией Gson? // Ужасно и не будет работать при наличии циклических c зависимостей
- Использовать класс-оболочку? // Просто безобразно, но должно работать