2017-01-31 1 views
0

Voir la solution à la fin.Analyse de Gson dans un objet contenant un JsonArray

question originale

je l'objet suivant dans mon code que je suis en train de désérialiser avec Gson.

public class Foo { 
    public Map<String, JSONArray> bar = new HashMap<>(); 
    public ... other stuff 
} 

J'ai aussi essayé avec:

public class Foo { 
    public Map<String, String> bar = new HashMap<>(); 
    public ... other stuff 
} 

La raison en est ici parce que le Map sera alimentation dans les sous-modules qui pourraient être tout type de données. En interne chaque module sait comment analyser ses propres données.

sur la version JsonArray je reçois cette erreur:

com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: 
    Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 3 column 18 path $.trigger. 

et dans la version String je reçois cette erreur:

com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: 
    Expected a string but was BEGIN_ARRAY at line 3 column 18 path $.trigger. 

Ma question est:

Puis-je analyser cela sans le besoin d'un désérialisateur personnalisé? Comment?

Edit: ci-dessous sont les bits correspondants du code:

// Gson is singleton provided by Dagger2 
Gson gson = new GsonBuilder().create(); 

// retrofit is also singleton provided by dagger 
Retrofit restAdapter = new Retrofit.Builder() 
    .baseUrl(baseUrl) 
    .client(buildOkHttpClient(context)) 
    .addConverterFactory(ScalarsConverterFactory.create()) 
    .addConverterFactory(GsonConverterFactory.create(gson)) 
    .addCallAdapterFactory(RxJava2CallAdapterFactory.create()) 
    .build(); 
return restAdapter.create(ApiService.class); 

// then the Retrofit API 
@GET("our path") 
Observable<Foo> getFoo(a couple of values); 

J'ai aussi essayé d'utiliser un MockTransport qui est directement invoquait Gson, comme suit:

Observable 
    .just(fooResponse) 
    .delay(101, TimeUnit.MILLISECONDS) 
    .map(new Function<String, Foo>() { 
     @Override public Interactions apply(String s) throws Exception { 
      return gson.fromJson(s, Foo.class); 
     } 
    }); 

et au-dessous pertinentes parties du JSON:

{ 
    "bar": { 
    "type0": [ 
     { 
     ... object 0 
     } 
    ], 
    "type1": [ 
     { 
     ... object 0 
     }, 
     { 
     ... object 1 
     } 
    ] 
    }, 
    "otherStuff" : { 
    } 
} 

Le j fils est sûr correctement formaté, il vient de nos serveurs et je l'ai re-vérifié sur jsonlint.com

solution :

il semble que ce n'est pas possible de le faire sans désérialiseur sur mesure. J'ai donc écrit un sérialiseur pour String, ce qui sonne mal, mais j'accepte volontiers les suggestions d'une meilleure façon de le gérer.

.registerTypeAdapter(String.class, new JsonDeserializer<String>() { 
    @Override 
    public String deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { 
     if (json.isJsonPrimitive()) { 
      return json.getAsJsonPrimitive().getAsString(); 
     } else { 
      return json.toString(); 
     } 
    } 
}) 
+0

Comment désérialiser cas 'foo'? Quelque chose comme 'gson.from (..., Foo.class)'? –

+0

@LyubomyrShaydariv oui. exactement comme ça. Je vais mettre à jour la question avec ces détails. – Budius

+0

Sera également utile si vous avez ajouté un exemple de json de ce que vous voulez désérialiser –

Répondre

1

Vous avez obtenu cette erreur parce que vous essayez d'analyser JsonArray mais vous devez analyser JsonObject à la ligne mentionnée ci-dessus. J'espère que ça va aider !! :)

+0

J'ai toujours "BEGIN_OBJECT attendu mais BEGIN_ARRAY à la ligne 3 de la colonne 18 chemin $ .trigger" – Budius

0

Quand j'ai essayé cela, il fonctionnait très bien pour moi,

public class Foo { 

    Map<String, List<Map>> bar = new HashMap<String, List<Map>>() ; 

} 
+0

Oui, cela fonctionnera sans crash. Mais cela ne résout pas la question, car les données à l'intérieur de la carte sont "abstraites" et seront analysées plus tard. Sur ma description: "La raison en est que la carte sera alimentée en sous-modules qui pourraient être n'importe quel type de données." En interne chaque module sait comment analyser ses propres données " – Budius