Модифицировать обратный вызов

Я тестирую Retrofit, чтобы сравнить его с Volley, и я изо всех сил пытаюсь получить ответ от моих запросов. Например, я делаю что-то вроде этого:

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) {} }); 

Он работает, объект toto установлен, но для целей тестирования я также хочу отобразить ответ JSON, возвращаемый сервером.

Поэтому я пытаюсь прочитать InputStream из response.getBody() который является TypedInputStream . К сожалению, я всегда получаю IOException : Stream is closed .

Я попытался использовать класс Utils из Retrofit, но получаю ту же ошибку IOException .

Solutions Collecting From Web of "Модифицировать обратный вызов"

Внутри угловых кронштейнов обратного вызова записывается «Ответ», а затем извлекается поток из этого ответа.

 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) { } }); 

Перед обновлением 2.0

  String bodyString = new String(((TypedByteArray) response.getBody()).getBytes()); 

Дооснащение 2.0

  String bodyString = new String(response.body().bytes()); 

Если вы установили параметр .setLogLevel(RestAdapter.LogLevel.FULL) в RestAdapter который вы используете для создания службы, вы должны получить исходный ответ JSON на консоли отладки.

 RestAdapter restAdapter = new RestAdapter.Builder() .setServer("http://my_lovely_api.com") .setLogLevel(RestAdapter.LogLevel.FULL) .build(); mService = restAdapter.create(MyService.class); 

Если вы хотите сделать что-то другое с этим сырым ответом, вы все равно можете использовать код, который у вас есть в своем блоке успеха, чтобы создать строку JSON, предполагая, что вы сохраняете LogLevel.FULL в методе setLogLevel , если нет, то он не будет анализировать InputStream из response.getBody().in() In response.getBody().in() поскольку он уже был прочитан и закрыт.

Я недавно столкнулся с аналогичной проблемой. Я хотел посмотреть на json в теле ответа, но не хотел иметь дело с TypedByteArray от Retrofit. Я нашел самый быстрый способ обойти это, чтобы создать Pojo (обычный старый объект Java) с одним строковым полем. Более того, вы бы сделали Pojo с одним полем, соответствующим любым данным, на которые вы хотели посмотреть.

Например, скажем, я делал запрос, в котором ответ с сервера был одной строкой в ​​теле ответа, называемой «access_token»,

Мое Pojo будет выглядеть так:

 public class AccessToken{ String accessToken; public AccessToken() {} public String getAccessToken() { return accessToken; } } 

И тогда мой обратный вызов будет выглядеть следующим образом:

 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()); } }; 

Это позволит вам посмотреть, что вы получили в ответ.

Пожалуйста, не используйте для этого потоки и straemReaders. Используйте интеллектуальные решения, такие как квадрат:

 private Response logAndReplaceResponse(String url, Response response, long elapsedTime) 

http://www.programcreek.com/java-api-examples/index.php?source_dir=retrofit-jaxrs-master/retrofit/src/main/java/retrofit/RestAdapter.java

пример:

 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; } 

Другим решением было бы сделать что-то вроде следующего:

  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); } } 

Взято из https://github.com/square/okhttp/blob/master/okcurl/src/test/java/com/squareup/okhttp/curl/MainTest.java#L93-L101

С версией 2.1.0 вы можете получить контент как

 public void onResponse(Call<T> call, Response<T> response) { String errorString = response.errorBody().string(); } 

Просто сделайте это так:

 ModelClass modelclass=response.response.body() System.out.println("****************-----retro rsp----1-------"+modelclass.getMessage()); 

В вашей модели ответа нажмите cmd + n и переопределите метод toString и вызовите только response.toString ();

 @Override public String toString() { return "{" + "key_one='" + var_keyone + '\'' + ", key_two='" + var_keytwo + '\'' + '}'; }