Error deserializing RealList <RealmString> to list <String>

Due to Realm's inability to work with promoted types, including String s, I am trying to implement JsonDeserializer , as in this question .

The problem is that I do not understand why I am getting the following error:

W / System.err: com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: expected BEGIN_OBJECT, but STRING

This is part of Json: "tags": ["GLUTEN FREE", "NUT FREE"],

My RealmString:

 public class RealmString extends RealmObject { private String value; public RealmString() { } public RealmString(String value) { this.value = value; } public String getValue() { return value; } public void setValue(String value) { this.value = value; } } 

Part of a modified Pojo:

 public class Entity extends RealmObject { @SerializedName("tags") private RealmList<RealmString> tags = null; } 

.. and Deserializer:

 public class StringRealmListConverter implements JsonDeserializer<RealmList<RealmString>> { @Override public RealmList<RealmString> deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { RealmList<RealmString> realmStrings = new RealmList<>(); JsonArray ja = json.getAsJsonArray(); for (JsonElement je : ja) { realmStrings.add((RealmString) context.deserialize(je, RealmString.class)); } return realmStrings; } } 

And I will register it here:

 public Gson provideGson() { return new GsonBuilder() .registerTypeAdapter(Food.class, new FoodDeserializer()) .registerTypeAdapter(new TypeToken<RealmList<RealmString>>() {}.getType(), new StringRealmListConverter()) .create(); } 

edit Here FoodDeserializer. This is in this mess because we needed to use composition over inheritance to please the gods of the Kings:

 public class FoodDeserializer implements JsonDeserializer<Food> { public static final String TAG = FoodDeserializer.class.getSimpleName(); Gson mHelperGson; public FoodDeserializer() { mHelperGson = new GsonBuilder().create(); } @Override public Food deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { String type = json.getAsJsonObject().get("responseType").getAsString(); switch (type) { case "Platter": return parsePlatter(json); case "FoodItem": return parseFoodItem(json); default: return null; } } private PlatterEntity parsePlatter(JsonElement json) { FoodEntity food = mHelperGson.fromJson(json, new TypeToken<FoodEntity>() { }.getType()); ArrayList<FoodItemEntity> items = new ArrayList<>(); JsonElement je1 = json.getAsJsonObject().get("items"); if (je1 != null) { JsonArray list = je1.getAsJsonArray(); if (list != null) { items = mHelperGson.fromJson(list.toString(), new TypeToken<List<FoodItemEntity>>() { }.getType()); } } return new PlatterEntity(food, items); } private FoodItemEntity parseFoodItem(JsonElement json) { FoodEntity food = mHelperGson.fromJson(json, new TypeToken<FoodEntity>() { }.getType()); Boolean readyToEat = null; JsonElement je1 = json.getAsJsonObject().get("readyToEat"); if (je1 != null) { readyToEat = je1.getAsBoolean(); } String heatingInstructions = null; JsonElement je2 = json.getAsJsonObject().get("heatingInstructions"); if (je2 != null) { heatingInstructions = je2.getAsString(); } ArrayList<IngredientEntity> ingredients = new ArrayList<>(); JsonElement je3 = json.getAsJsonObject().get("ingredients"); if (je3 != null) { JsonArray list = je3.getAsJsonArray(); if (list != null) { ingredients = mHelperGson.fromJson(list.toString(), new TypeToken<List<IngredientEntity>>() { }.getType()); } } NutritionEntity foodNutritions = mHelperGson.fromJson(json, new TypeToken<NutritionEntity>() { }.getType()); return new FoodItemEntity(food, readyToEat, heatingInstructions, ingredients, foodNutritions); } } 

I would like to use JsonDeserializer over TypeAdapter , but any help would be appreciated, thanks!

+1
android realm
source share
2 answers

It turns out my feelings were right. I had to add the StringRealmListConverter constructor to the FoodDeserializable constructor, for example:

  public FoodDeserializer() { mHelperGson = new GsonBuilder() .registerTypeAdapter(new TypeToken<RealmList<RealmString>>() { }.getType(), new StringRealmListConverter()) .create(); } 
0
source share

You can use the JsonDeserializationContext (passed as the second parameter to your deserialize function) to deserialize the RealmString correctly. context knows how to deserialize all your custom types registered in the current Gson instance. See the documentation for the JsonDeserializationContext here: https://google.imtqy.com/gson/apidocs/com/google/gson/JsonDeserializationContext.html .

The reason it doesn't work with your current code is because you are creating a new Gson instance in FoodDeserializer that does not know about the custom deserializer for RealmString .

0
source share

All Articles