Can't Get Okhttp's Response.Body.Tostring() to Return a String

Can't get OkHttp's response.body.toString() to return a string

Just in case someone bumps into the same weird thing as I have. I run my code during development in Debug Mode and apparently since OKHttp 2.4

..the response body is a one-shot value that may be consumed only once

So when in debug there is a call "behind the scene" from the inspector and the body is always empty. See: https://square.github.io/okhttp/3.x/okhttp/okhttp3/ResponseBody.html

Accessing OKHttp Response Body

I think we can call response.body().string() only once .... so save that data to a string variable first .. and access it wherever you need it.

String response_data;
..............
response_data = response.body().string();

You are calling response.body().string() twice ...

More info
https://stackoverflow.com/a/27922818/3552066

return response.body().string() is empty with okhttp3

I found a solution which sounds weird, at least to me.

I changed the end of the class as following:

String MyResult = response.body().string();
System.out.println("postJSONRequest response.body : "+MyResult);
return MyResult ;

So instead of calling twice response.body().string(), I put it in a variable.
And it works !

can't get data out of response.body().string() in okhttp?

Try

try {
JSONObject json = new JSONObject(response.body().string());
String name = json.getString("name");
String city = json.getString("city");
int age = json.getInt("age");

} catch (JSONException e) {
e.printStackTrace();
}

OkHttp: A simple GET request: response.body().string() returns unreadable escaped unicode symbols inside json can't convert to gson

It is because the response object can be consumed only once. OKHTTP says that in their documentation. After the execute is invoked, you are calling the response object twice. Store the result of response.body().string() to a variable and then do the convert into GSON.

If I were to use a hello world example...

private void testOkHttpClient() {
OkHttpClient httpClient = new OkHttpClient();
try {
Request request = new Request.Builder()
.url("https://www.google.com")
.build();
Call call = httpClient.newCall(request);
Response response = call.execute();
System.out.println("First time " + response.body().string()); // I get the response
System.out.println("Second time " + response.body().string()); // This will be empty
} catch (IOException e) {
e.printStackTrace();
}
}

The reason it is empty the second time is because the response object can be consumed only once. So you either

Return the response as it is. Do not do a sysOut

System.out.println(response.body().string()); // Instead of doing a sysOut return the value.

Or

Store the value of the response to a JSON then convert it to GSON and then return the value.

EDIT: Concerning Unicode characters. It turned out since my location is not an English-speaking country, the json i was accepting was not in English as well. I added this header:

.addHeader("Accept-Language", Locale.US.getLanguage())

to the request to fix that.

Accessing body string of an OkHttp Response twice results in IllegalStateException: closed

The string method on the response will read the input (network) stream and convert it into a string. So it dynamically builds the string and returns it to you. The second time you call it, the network stream has already been consumed and is no longer available.

You should save the result of string into a String variable, and then access it as many times as needed.

How does OkHttp get Json string?

try {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url(urls[0])
.build();
Response responses = null;

try {
responses = client.newCall(request).execute();
} catch (IOException e) {
e.printStackTrace();
}
String jsonData = responses.body().string();
JSONObject Jobject = new JSONObject(jsonData);
JSONArray Jarray = Jobject.getJSONArray("employees");

for (int i = 0; i < Jarray.length(); i++) {
JSONObject object = Jarray.getJSONObject(i);
}
}

Example add to your columns:

JCol employees  = new employees();
colums.Setid(object.getInt("firstName"));
columnlist.add(lastName);

Caused by: com.fasterxml.jackson.core.JsonParseException: Unrecognized token 'okhttp3': was expecting (JSON String')

Issue

The call of response.body().toString() method is inherited from Object class and returns the full class-name with instance's hexadecimal hash-code:

this method returns a string equal to the value of:

getClass().getName() + '@' + Integer.toHexString(hashCode())

as "okhttp3.internal.http.RealResponseBody@466f95e8".
Because this string is no valid JSON, Jackson throws this exception:

com.fasterxml.jackson.core.JsonParseException: Unrecognized token 'okhttp3': was expecting (JSON String

This is not what you and Jackson's ObjectMapper.readValue() method expected as JSON representation.

Solution

Instead use response.body().string() method to get the response body's textual representation as String (here JSON):

Returns the response as a string.

See also:

  • Decode an OkHttp JSON Response | Baeldung


Related Topics



Leave a reply



Submit