I am trying to deserialize a JSON array using GSON. All of my nested objects are embedded inside an "embedded" object.
{
"Book": {
"name": "Book 1",
"published": 1999,
"links": {
"url": "www.book1.com"
},
"embedded": {
"Author": {
"name": "John Doe",
"links": {
"url": "www.johndoe.com"
}
}
}
}
}
I could also have a situation like this:
{
"Book": {
"name": "Book 1",
"published": 1999,
"links": {
"url": "www.book1.com"
},
"embedded": {
"Publisher": {
"name": "Publishing Company",
"links": {
"url": "www.publishingcompany.com"
}
}
}
}
}
This is an extremely simple example. Some of my objects may be nested 2 or 3 levels deep, and all are in an "embedded" object. Also, each object has a nested "url" inside a "links" object. I have around 20 different model objects, each with several fields, and everyone of them have the "embedded" object. I started to write custom deserializers for each model, but that seems to miss the whole point of using gson, and I may not always know what the embedded object is.
I found this answer, but it was for serializing objects. I have been trying to figure this out for a while now and have not found anything that works.
My Book model looks like this:
public class Book {
String name;
int published;
String url;
Author author;
Publisher publisher;
}
Author class:
public class Author {
String name;
String url;
}
Publisher class:
public class Publisher {
String name;
String url;
}
And here is my Book deserializer so far:
public class BookDeserializer implements JsonDeserializer<Book> {
@Override
public Book deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
final JsonObject jsonObject = json.getAsJsonObject();
Book book = new Book();
book.setName(jsonObject.get("name").getAsString());
book.setPublished(jsonObject.get("published").getAsInt());
String url = jsonObject.getAsJsonObject("links").get("url").getAsString();
book.setUrl(url);
// 1) How to get rid of this and skip to the "real" nested object?
final JsonObject embeddedObject = jsonObject.getAsJsonObject("embedded");
// 2) See what the "embedded" object actually is.
String embeddedModel;
Set<Map.Entry<String, JsonElement>> entrySet = embeddedObject.entrySet();
for (Map.Entry<String, JsonElement> entry : entrySet) {
// Author or Publisher
embeddedModel = entry.getKey();
}
// We have the model's key, now add code here to deserialize whatever the object is
return book;
}
}
I still have to parse the json and set each field for Book. Then, I would have to add code to determine and use the correct deserializer for the nested object. Looks like I still would need a custom deserializer for each object to get the "url". I am fairly new to gson, so maybe there is just something that I am overlooking, but it seems that I might as well just manually parse all of the json and not even use gson. Maybe there is a way to flatten out json?
Any ideas on how to parse this and still use the convenience of gson, or is this even possible? Maybe Jackson could handle this better?