Je teste Retrofit pour le comparer à Volley et j'ai du mal à obtenir la réponse à mes demandes. Par exemple, je fais quelque chose comme ça:
RestAdapter restAdapter = new RestAdapter.Builder()
.setEndpoint("http://localhost:8080")
.build();
MyService service = restAdapter.create(MyService.class);
service.getToto("toto", new Callback<Toto>() {
@Override
public void success(Toto toto, Response response) {
// Try to get response body
BufferedReader reader = null;
StringBuilder sb = new StringBuilder();
try {
reader = new BufferedReader(
new InputStreamReader(response.getBody().in()));
String line;
try {
while ((line = reader.readLine()) != null) {
sb.append(line);
}
} catch (IOException e) {
e.printStackTrace();
}
} catch (IOException e) {
e.printStackTrace();
}
String result = sb.toString();
}
@Override
public void failure(RetrofitError error) {}
});
Cela fonctionne, l'objet toto
est défini, mais à des fins de test, je souhaite également afficher la réponse JSON renvoyée par le serveur.
J'essaie donc de lire le InputStream
de response.getBody()
qui est un TypedInputStream
. Malheureusement, je reçois toujours un IOException : Stream is closed
.
J'ai essayé d'utiliser la classe tils de Retrofit mais j'obtiens la même erreur IOException
.
Les crochets angulaires de callback à l'intérieur écrivent "Réponse" puis extraient le flux de cette réponse.
service.getToto("toto", new Callback<Response>() {
@Override
public void success(Response result, Response response) {
//Try to get response body
BufferedReader reader = null;
StringBuilder sb = new StringBuilder();
try {
reader = new BufferedReader(new InputStreamReader(result.getBody().in()));
String line;
try {
while ((line = reader.readLine()) != null) {
sb.append(line);
}
} catch (IOException e) {
e.printStackTrace();
}
} catch (IOException e) {
e.printStackTrace();
}
String result = sb.toString();
}
@Override
public void failure(RetrofitError error) {
}
});
Avant la modernisation 2.
String bodyString = new String(((TypedByteArray) response.getBody()).getBytes());
Retrofit 2.
String bodyString = new String(response.body().bytes());
Si vous définissez .setLogLevel(RestAdapter.LogLevel.FULL)
sur le RestAdapter
que vous utilisez pour créer le service, vous devez obtenir le résultat de la réponse JSON brut dans la console de débogage.
RestAdapter restAdapter = new RestAdapter.Builder()
.setServer("http://my_lovely_api.com")
.setLogLevel(RestAdapter.LogLevel.FULL)
.build();
mService = restAdapter.create(MyService.class);
Si vous voulez faire quelque chose de différent avec cette réponse brute, vous pouvez toujours utiliser le code que vous avez dans votre bloc de succès pour créer une chaîne JSON, en supposant que vous conserviez le LogLevel.FULL
Dans la méthode setLogLevel
, si pas alors il ne sera pas analyser le InputStream de response.getBody().in()
comme il a déjà été lu et fermé.
J'ai récemment rencontré un problème similaire. Je voulais regarder un json dans le corps de la réponse, mais je ne voulais pas traiter avec le TypedByteArray de Retrofit. J'ai trouvé que le moyen le plus rapide de contourner ce problème était de créer un Pojo (Plain Old Java Object)) avec un seul champ String. Plus généralement, vous feriez un Pojo avec un seul champ correspondant aux données que vous voulu regarder.
Par exemple, disons que je faisais une demande dans laquelle la réponse du serveur était une seule chaîne dans le corps de la réponse, appelée "access_token".
Mon Pojo ressemblerait à ceci:
public class AccessToken{
String accessToken;
public AccessToken() {}
public String getAccessToken() {
return accessToken;
}
}
et puis mon rappel ressemblerait à ceci
Callback<AccessToken> callback = new Callback<AccessToken>() {
@Override
public void success(AccessToken accessToken, Response response) {
Log.d(TAG,"access token: "+ accessToken.getAccessToken());
}
@Override
public void failure(RetrofitError error) {
Log.E(TAG,"error: "+ error.toString());
}
};
Cela vous permettra de regarder ce que vous avez reçu dans la réponse.
S'il vous plaît, n'utilisez pas les flux et straemReaders pour cela. Utilisez des solutions intelligentes comme le fait le carré:
private Response logAndReplaceResponse(String url, Response response, long elapsedTime)
exemple:
private String getResponseBody(Response response) {
String result = "";
//Try to get response body
if (response.getBody() instanceof TypedByteArray) {
TypedByteArray b = (TypedByteArray) response.getBody();
result = new String(b.getBytes());
}
return result;
}
Une autre solution serait de faire quelque chose comme ceci:
private static String bodyAsString(RequestBody body) {
try {
Buffer buffer = new Buffer();
body.writeTo(buffer);
return buffer.readString(body.contentType().charset());
} catch (IOException e) {
throw new RuntimeException(e);
}
}
Avec la version 2.1.0, vous pouvez obtenir le contenu en tant que
public void onResponse(Call<T> call, Response<T> response) {
String errorString = response.errorBody().string();
}
Fais-le comme ça:
ModelClass modelclass=response.response.body()
System.out.println("****************-----retro rsp----1-------"+modelclass.getMessage());