I'm trying to use a JSON object to convert to a Java object (build with AutoValue) using Gson. The JSON object looks like:
{
"id": 1,
"name": "Nutella Pie",
"ingredients": [
{
"quantity": 2,
"measure": "CUP",
"ingredient": "Graham Cracker crumbs"
},
...
],
"steps": [
{
"id": 5,
"shortDescription": "Finish filling prep"
},
...
]
}
So the Java class (built with AutoValue) looks like:
@AutoValue
public abstract class Recipe {
@SerializedName("id")
abstract int id();
@SerializedName("name")
abstract String name();
@SerializedName("ingredients")
abstract List<Ingredient> ingredients();
@SerializedName("steps")
abstract List<Step> steps();
public static TypeAdapter<Recipe> typeAdapter(Gson gson) {
return new AutoValue_Recipe.GsonTypeAdapter(gson);
}
}
The create method in the TypeAdapterFactory is:
public <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
Class<? super T> rawType = type.getRawType();
if (rawType.equals(Ingredient.class)) {
return (TypeAdapter<T>) Ingredient.typeAdapter(gson);
}
if (rawType.equals(Recipe.class)) {
return (TypeAdapter<T>) Recipe.typeAdapter(gson);
}
if (rawType.equals(Step.class)) {
return (TypeAdapter<T>) Step.typeAdapter(gson);
}
return null;
}
However, I'm having the error:
NoSuchMethodError: No static method getParameterized
This getParameterized is a GsonTypeAdapter method, and apparently is not implemented.
If I change the JSON and the Java classes to a nested object instead of a nested object list, it works fine.
I don't know what is going on. Any ideas?
EDIT: I made some progress. Acording to the AutoValue GSON Extension docs:
To have support for fields with generic parameters (eg. List) you need to upgrade your Gson dependency to at least 2.8.0, which introduces the helper TypeToken.getParameterized() see Gson Changelog.
This way, my code to generate the Type adapter is:
public static <Ingredient,Step> TypeAdapter<Recipe<Ingredient,Step>> typeAdapter(Gson gson,
TypeToken<? extends Recipe<Ingredient,Step>> typeToken) {
return new AutoValue_Recipe.GsonTypeAdapter(gson,typeToken);
}
However, Im having a problem using that on the TypeAdapterFactory, since it has to return a TypeAdapter<T>, not a TypeAdapter<Recipe<Ingredient,Step>>. Tried casting, but no success.
What do I do? Add a new TypeAdapterFactory?