android - implementar - Retrofit callback obtener respuesta cuerpo
retrofit post (9)
Estoy probando Retrofit para compararlo con Volley y estoy luchando para obtener la respuesta de mis solicitudes. Por ejemplo, hago algo como esto:
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) {}
});
Funciona, el objeto toto
está establecido, pero para propósitos de prueba, también quiero mostrar la respuesta JSON devuelta por el servidor.
Así que estoy tratando de leer el InputStream
de response.getBody()
que es un TypedInputStream
. Desafortunadamente, siempre recibo una IOException : Stream is closed
.
Intenté usar la clase Utils de Retrofit pero obtengo el mismo error IOException
.
Con la versión 2.1.0, puede obtener el contenido como
public void onResponse(Call<T> call, Response<T> response) {
String errorString = response.errorBody().string();
}
Dentro de los paréntesis angulares de devolución de llamada, escriba "Respuesta" y luego extraiga la secuencia de esta respuesta.
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) {
}
});
Otra solución sería hacer algo como lo siguiente:
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);
}
}
Por favor, no use streams y straemReaders para esto. Use soluciones inteligentes como el cuadrado:
private Response logAndReplaceResponse(String url, Response response, long elapsedTime)
ejemplo:
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;
}
Recientemente me encontré con un problema similar. Quería ver a algunos json en el cuerpo de respuesta, pero no quería tratar con el TypedByteArray de Retrofit. Descubrí que la forma más rápida de solucionarlo era hacer un Pojo (objeto Java antiguo liso) con un solo campo de cadena. Más Generalmente, usted haría un Pojo con un campo correspondiente a cualquier dato que quisiera ver.
Por ejemplo, digamos que estaba haciendo una solicitud en la que la respuesta del servidor era una única cadena en el cuerpo de la respuesta llamada "access_token"
Mi Pojo se vería así:
public class AccessToken{
String accessToken;
public AccessToken() {}
public String getAccessToken() {
return accessToken;
}
}
y luego mi devolución de llamada se vería así
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());
}
};
Esto le permitirá ver lo que recibió en la respuesta.
Si configura .setLogLevel(RestAdapter.LogLevel.FULL)
en el RestAdapter
que usa para crear el servicio, debería obtener el resultado de respuesta JSON sin procesar en la consola de depuración.
RestAdapter restAdapter = new RestAdapter.Builder()
.setServer("http://my_lovely_api.com")
.setLogLevel(RestAdapter.LogLevel.FULL)
.build();
mService = restAdapter.create(MyService.class);
Si desea hacer algo diferente con esta respuesta sin procesar, aún puede usar el código que tiene en su bloque de éxito para crear una cadena JSON asumiendo que mantiene LogLevel.FULL
en el método setLogLevel
, si no, no analizará el InputStream desde response.getBody().in()
In response.getBody().in()
porque ya se ha leído y cerrado.
Solo hazlo así:
ModelClass modelclass=response.response.body()
System.out.println("****************-----retro rsp----1-------"+modelclass.getMessage());
en su modelo de respuesta presione cmd + n y anule el método "toString" y solo llame como response.toString ();
@Override
public String toString() {
return "{" +
"key_one=''" + var_keyone + ''/''' +
", key_two=''" + var_keytwo + ''/''' +
''}'';
}
Antes de la actualización 2.0
String bodyString = new String(((TypedByteArray) response.getBody()).getBytes());
Retrofit 2.0
String bodyString = new String(response.body().bytes());