Hi,
I'm having problems deserializing v3 REST responses containing arrays using gson in a Java desktop application.
I have created classes that conforms to the Clover v3 REST specifications and I can successfully send requests using the jsonized objects of those classes to the REST service.
However, I can't deserialize the response from the REST service when it contains arrays, because every arrays in the response is encapsulated in a "elements" object, while the request json does not require the arrays to be inside a "elements" object.
Below is the code trying to deserialize the response returned from the request to get all the modifier groups with all the modifiers included:
JsonParser parser = new JsonParser();
JsonObject rootObject = parser.parse(response).getAsJsonObject();
JsonElement listElement = rootObject.get("elements");
Type listType = new TypeToken<List<ModifierGroup>>() {}.getType();
List<ModifierGroup> modifierGroups= new Gson().fromJson(listElement, listType);
The error message that I get from gson is as follows:
com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was BEGIN_OBJECT
I can workaround this problem by creating classes just for responses that have the arrays inside a "elements" object, or implement some kind of custom deserializer, but it would be much better if deserialization worked the same way as the serialization.
The following deserializer works for deserializing the responses correctly for the modifier group:
public static class ModifierGroupDeserializer implements JsonDeserializer<ModifierGroup> {
@Override
public ModifierGroup deserialize(JsonElement je, Type type,
JsonDeserializationContext context) throws JsonParseException {
JsonObject jo = je.getAsJsonObject();
ModifierGroup mg = new ModifierGroup();
mg.setAlternateName(getSafeString(jo.get("alternateName")));
mg.setId(getSafeString(jo.get("id")));
if(jo.get("items") != null)
{
JsonObject joItems = jo.get("items").getAsJsonObject();
Type itemListType = new TypeToken<List<Item>>() {}.getType();
mg.setItems((List<Item>)context.deserialize(joItems.get("elements"), itemListType));
}
mg.setMaxAllowed(getSafeString(jo.get("maxAllowed")));
mg.setMinRequired(getSafeString(jo.get("maxRequired")));
mg.setModifierIds(getSafeString(jo.get("modifierIds")));
if(jo.get("modifiers") != null)
{
JsonObject joModifiers = jo.get("modifiers").getAsJsonObject();
Type modifierListType = new TypeToken<List<Modifier>>() {}.getType();
mg.setModifiers((List<Modifier>)context.deserialize(joModifiers.get("elements"), modifierListType));
}
mg.setName(getSafeString(jo.get("name")));
mg.setShowByDefault(getSafeBoolean(jo.get("showByDefault"), true));
return mg;
}
private boolean getSafeBoolean(JsonElement el, boolean def_val)
{
if(el != null)
{
return el.getAsBoolean();
}
return def_val;
}
private String getSafeString(JsonElement el)
{
if(el == null)
{
return "";
}
else
{
return el.getAsString();
}
}
}
Below is the pastebin link for the REST response for GET modifier_groups:
Is there any recommendation on how to deserialize REST responses containing arrays?