Reputation: 1198
I am testing Retrofit to compare it with Volley and I am struggling to get the response from my requests. For example, I do something like this:
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) {}
});
It works, the object toto
is set, but for testing purposes, I also want to display the JSON response returned by the server.
So I am trying to read the InputStream
from response.getBody()
which is a TypedInputStream
.
Unfortunately, I always get an IOException : Stream is closed
.
I tried to use the Utils class from Retrofit but I get the same IOException
error.
Upvotes: 46
Views: 78009
Reputation: 290
Just do it like this:
ModelClass modelclass=response.response.body()
System.out.println("****************-----retro rsp----1-------"+modelclass.getMessage());
Upvotes: 0
Reputation: 7264
Before Retrofit 2.0
String bodyString = new String(((TypedByteArray) response.getBody()).getBytes());
Retrofit 2.0
String bodyString = new String(response.body().bytes());
Upvotes: 29
Reputation: 547
With version 2.1.0, you can get the content as
public void onResponse(Call<T> call, Response<T> response) {
String errorString = response.errorBody().string();
}
Upvotes: 1
Reputation: 127
in your model of response press cmd+n and override "toString" method and only call as response.toString();
@Override
public String toString() {
return "{" +
"key_one='" + var_keyone + '\'' +
", key_two='" + var_keytwo + '\'' +
'}';
}
Upvotes: -1
Reputation: 1619
Please, don't use streams and straemReaders for this. Use smart solutions like square does:
private Response logAndReplaceResponse(String url, Response response, long elapsedTime)
example:
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;
}
Upvotes: 3
Reputation: 30581
Another solution would be to do something like the following:
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);
}
}
Upvotes: 1
Reputation: 481
If you set .setLogLevel(RestAdapter.LogLevel.FULL)
on the RestAdapter
that you use to create the service you should get the raw JSON response output in the debug console.
RestAdapter restAdapter = new RestAdapter.Builder()
.setServer("http://my_lovely_api.com")
.setLogLevel(RestAdapter.LogLevel.FULL)
.build();
mService = restAdapter.create(MyService.class);
If you want to do something different with this raw response you can still use the code you have in your success block to create a JSON string assuming that you keep the LogLevel.FULL
in the setLogLevel
method, if not then it won't parse the InputStream from response.getBody().in()
as it's already been read and closed.
Upvotes: 23
Reputation: 3512
I recently encountered a similar problem. I wanted to look at some json in the response body but didn't want to deal with the TypedByteArray from Retrofit. I found the quickest way to get around it was to make a Pojo(Plain Old Java Object) with a single String field. More Generally you would make a Pojo with one field corresponding to whatever data you wanted to look at.
For example, say I was making a request in which the response from the server was a single string in the response's body called "access_token"
My Pojo would look like this:
public class AccessToken{
String accessToken;
public AccessToken() {}
public String getAccessToken() {
return accessToken;
}
}
and then my callback would look like this
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());
}
};
This will enable you to look at what you received in the response.
Upvotes: 3
Reputation: 5440
Inside callback's angle brackets write "Response" and then extract the stream from this response.
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) {
}
});
Upvotes: 53