Désérialisation de Gson de List dans realmList

J’utilise retrofit avec gson pour désérialiser mon json en objects du royaume. Cela fonctionne très bien pour la plupart. Des problèmes surgissent lorsqu’il s’agit de

RealmList (Ssortingng (ou tout autre type de données de base))

Etant donné que Realm ne prend pas en charge RealmList où E n’étend pas l’object Realm, j’enveloppe Ssortingng dans un RealmObject.

public class RealmSsortingng extends RealmObject { private Ssortingng val; public Ssortingng getValue() { return val; } public void setValue(Ssortingng value) { this.val = value; } } 

Mon royaume object est comme ci-dessous

  public class RealmPerson extends RealmObject { @PrimaryKey private Ssortingng userId; ... private RealmList ssortingngStuff; private RealmList otherStuff;  } 

SimpleRealmObj fonctionne bien car il ne contient que des éléments Ssortingng

  public class SimpleRealmObj extends RealmObject { private Ssortingng foo; private Ssortingng bar; ... } 

Comment puis-je désérialiser ssortingngStuff? J’ai essayé d’utiliser un gson TypeAdapter

 public class RealmPersonAdapter extends TypeAdapter { @Override public void write(JsonWriter out, RealmPerson value) throws IOException { out.beginObject(); Log.e("DBG " + value.getLastName(), ""); out.endObject(); } @Override public RealmPerson read(JsonReader in) throws IOException { QLRealmPerson rList = new RealmPerson(); in.beginObject(); while (in.hasNext()) { Log.e("DBG " + in.nextSsortingng(), ""); } in.endObject(); return rList; } 

Cependant, je frappe toujours à IllegalStateException

2334-2334 / com.qualcomm.qlearn.app E // PersonService.java: 71 ﹕ main com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: chaîne attendue, mais NOM à la ligne 1 colonne 3 chemin $.

J’ai essayé RealmList, l’adaptateur RealmSsortingng plus tôt, en vain. La seule solution de rechange que j’ai réussi à trouver jusqu’à présent est https://github.com/realm/realm-java/issues/620#issuecomment-66640786 Des options plus performantes?

Le message d’erreur ” Expected a ssortingng but was NAME ” peut être résolu en récupérant le nom de l’object JsonReader dans JsonReader avant l’object JsonReader réel (qui est une Ssortingng dans votre cas).

Vous pouvez consulter la documentation Android pour JsonReader . Il a une explication détaillée et un extrait de code. Vous pouvez également consulter la méthode readMessage dans le readMessage de code fourni dans la documentation.

J’ai modifié votre méthode de read à ce que je pense qu’elle devrait être. Remarque: je n’ai pas testé le code, il peut donc y avoir quelques erreurs mineures.

 @Override public RealmPerson read(JsonReader in) throws IOException { RealmPerson rList = new RealmPerson(); in.beginObject(); Ssortingng name = ""; while (in.hasNext()) { name = in.nextName(); if (name.equals("userId")) { Ssortingng userId = in.nextSsortingng(); // update rList here } else if (name.equals("otherStuff")) { // since otherStuff is a RealmList of RealmSsortingngs, // your json data would be an array // You would need to loop through the array to resortingeve // the json objects in.beginArray(); while (in.hasNext()) { // begin each object in the array in.beginObject(); name = in.nextName(); // the RealmSsortingng object has just one property called "value" // (according to the code snippet in your question) if (name.equals("val")) { Ssortingng val = in.nextSsortingng(); // update rList here } else { in.skipValue(); } in.endObject(); } in.endArray(); } else { in.skipValue(); } } in.endObject(); return rList; } 

Faites-moi savoir si cela aide.

Il est préférable d’utiliser JsonSerializer et JsonDeserializer plutôt que TypeAdapter pour votre RealmObject , pour deux raisons:

  1. Ils vous permettent de déléguer la (dé) sérialisation de votre object RealmObject au RealmObject Gson (de) par défaut, ce qui signifie que vous n’avez pas besoin d’écrire vous-même .

  2. Il y a un bogue étrange dans Gson 2.3.1 qui pourrait causer une StackOverflowError lors de la désérialisation (j’ai moi-même essayé l’approche TypeAdapter et rencontré ce bogue).

Voici comment (remplacez Tag par votre classe RealmObject ):

( gson.toJson que gson.toJson et gson.fromJson ci-dessous sont équivalents à gson.toJson et gson.fromJson , ce qui signifie que nous n’avons pas besoin d’parsingr la classe Tag -même.)

Analyseur + sérialiseur pour RealmList :

 public class TagRealmListConverter implements JsonSerializer>, JsonDeserializer> { @Override public JsonElement serialize(RealmList src, Type typeOfSrc, JsonSerializationContext context) { JsonArray ja = new JsonArray(); for (Tag tag : src) { ja.add(context.serialize(tag)); } return ja; } @Override public RealmList deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { RealmList tags = new RealmList<>(); JsonArray ja = json.getAsJsonArray(); for (JsonElement je : ja) { tags.add((Tag) context.deserialize(je, Tag.class)); } return tags; } } 

Classe de tag:

 @RealmClass public class Tag extends RealmObject { private Ssortingng value; public Ssortingng getValue() { return value; } public void setValue(Ssortingng value) { this.value = value; } } 

Ensuite, enregistrez votre classe de convertisseur avec Gson:

 Gson gson = new GsonBuilder() .registerTypeAdapter(new TypeToken>() {}.getType(), new TagRealmListConverter()) .create(); 

Mon type gson TypeAdapter était le coupable. L’erreur ci-dessus a été vue car je ne désérialisais pas correctement le json dans RealmPerson, le premier champ n’est pas une chaîne, d’où

in.nextSsortingng ()

était borking.

J’ai regardé un exemple de code et cela m’a frappé, je n’ai pas eu à utiliser

in.beginObject () et in.endObject ()

désérialiser une chaîne. Le code ci-dessous fonctionne.

 public class QLRealmSsortingngAdapter extends TypeAdapter { @Override public void write(JsonWriter out, QLRealmSsortingng value) throws IOException { Log.e("DBG " + value.getValue(), ""); out.value(value.getValue()); } @Override public RealmSsortingng read(JsonReader in) throws IOException { RealmSsortingng rSsortingng = new RealmSsortingng(); if (in.hasNext()) { Ssortingng nextStr = in.nextSsortingng(); System.out.println("DBG " + nextStr); rSsortingng.setValue(nextStr); } return rSsortingng; } 

}

J’espère que cela aide quelqu’un.

j’ai besoin d’un sérialiseur et d’un désérialiseur jackson pour la conversion d’arrayliste en liste de domaines