J'ai essayé d'implémenter un intercepteur (OkHttp 3.2 & Retrofit 2) pour éditer la réponse JSON avant qu'elle ne soit renvoyée comme réponse. Le serveur auquel nous demandons des données renvoie des données différentes dépend du succès ou de l'erreur et cela rend difficile de mapper les objets.
J'essayais de le faire en ajoutant l'intercepteur à Retrofit en tant que NetworkInterceptor, mais la chaîne renvoyée n'avait pas de format.
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
Response response = chain.proceed(request);
try {
final String responseString = new String(response.body().bytes() );
LOGD("OkHttp-NET-Interceptor", "Response: " + responseString);
String newResponseString = editResponse( responseString );
LOGD("OkHttp-NET-Interceptor", "Response edited: " + newResponseString);
return response.newBuilder()
.body(ResponseBody.create(response.body().contentType(), newResponseString))
.build();
}catch (Exception ex){
return response;
}
}
responseString avait une chaîne sans aucun format compréhensible.
Après être passée à l'intercepteur normal, la chaîne avait un format qu'elle a pu convertir en JSONObject.
Pourriez-vous me dire quel sont les différences entre les réponses?
pourquoi cette ligne new String (response.body (). bytes ()); retourne un contenu différent?
Les différences sont dans les noms. NetworkInterceptor
se connecte au niveau du réseau et est un endroit idéal pour mettre la logique de nouvelle tentative et tout ce qui ne dépend pas du contenu réel de la réponse.
Si ce que vous faites dépend du contenu de la réponse (comme dans votre cas), l'utilisation d'un ApplicationInterceptor
est plus utile, car elle vous donne la réponse après qu'elle a été traitée par d'autres pièces mobiles que vous pourriez avoir telles que un désérialiseur JSON. Sinon, vous devrez implémenter le JSON vous désérialisant à l'intérieur de NetworkInterceptor
, ce qui n'a pas beaucoup de sens étant donné que c'est fait pour vous par Retrofit.
Clarification
Square a ce diagramme utile sur son wiki qui montre où se trouve chaque type d'intercepteur
Ainsi, la raison pour laquelle vous recevez une chaîne lisible dans le ApplicationInterceptor
est parce que Square essaie de découpler les objectifs des deux types d'intercepteurs. Ils ne pensent pas que vous devriez prendre des décisions dépendantes de l'application dans le NetworkInterceptor
, et ils ne vous fournissent donc pas un moyen facile d'accéder à la chaîne de réponse. Il est possible de les saisir, mais comme je l'ai dit, ils ne veulent pas que vous preniez des décisions qui dépendent du contenu de la réponse - ils veulent plutôt que vous preniez des décisions en fonction de l'état du réseau, des en-têtes, etc.
Le ApplicationInterceptor
est l'endroit où ils veulent que vous preniez des décisions en fonction du contenu de la réponse, afin qu'ils fournissent des méthodes plus faciles d'accès au contenu de la réponse afin que vous puissiez prendre des décisions éclairées pour réessayer, ou comme ils le détaillent dans leur wiki, réécrire les réponses (ce qui, je crois, est ce que vous essayez de faire).