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

JavaAndroidOkhttp

Java Problem Overview


I'm trying to get some json data using OkHttp and can't figure out why when i try logging the response.body().toString() what i get is Results:﹕ com.squareup.okhttp.Call$RealResponseBody@41c16aa8

try {
        URL url = new URL(BaseUrl);
        OkHttpClient client = new OkHttpClient();
        Request request = new Request.Builder()
                .url(url)
                .header(/****/)
                .build();

        Call call = client.newCall(request);
        Response response = call.execute();

        **//for some reason this successfully prints out the response**
        System.out.println("YEAH: " + response.body().string());

        if(!response.isSuccessful()) {
            Log.i("Response code", " " + response.code());
        }

        Log.i("Response code", response.code() + " ");
        String results = response.body().toString();

        Log.i("OkHTTP Results: ", results);

Log

I don't know what i'm doing wrong here. How do i get the response string?

Java Solutions


Solution 1 - Java

You have use .string() function to print the response in System.out.println(). But at last in Log.i() you are using .toString().

So please use .string() on response body to print and get your request's response, like:

response.body().string();

NOTE:

  1. .toString(): This returns your object in string format.

  2. .string(): This returns your response.

I think this solve your problem... Right.

Solution 2 - Java

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

Solution 3 - Java

The response.body,.string() can be consumed only once. Please use as below:

String responseBodyString = response.body.string();
use the responseBodyString as needed in your application.

Solution 4 - Java

Following is my modified CurlInterceptor. Check the end of the intercept function where I m recreating the Response object after consuming the old Response.

> var responseBodyString = responseBody?.string() > > response = response.newBuilder() > .body( > ResponseBody.create( > responseBody?.contentType(), > responseBodyString.toByteArray() > ) > ) > .build()

class CurlInterceptor: Interceptor
{

    var gson = GsonBuilder().setPrettyPrinting().create()

    override fun intercept(chain: Interceptor.Chain): Response {

    Timber.d(" **** ->>Request to server -> ****")

    val request = chain.request()
    var response = chain.proceed(request)

    var curl = "curl -v -X  ${request.method()}"

    val headers = request.headers()

    for ( i in 0..(headers.size() -1) ){
        curl = "${curl} -H \"${headers.name(i)}: ${headers.value(i)}\""
    }

    val requestBody = request.body()
    if (requestBody != null) {
        val buffer = Buffer()
        requestBody.writeTo(buffer)
        var charset: Charset =
            Charset.forName("UTF-8")
        curl = "${curl} --data '${buffer.readString(charset).replace("\n", "\\n")}'"
    }

    Timber.d("$curl ${request.url()}")
    Timber.d("response status code ${response.code()} message: ${response.message()}")

    
    dumbHeaders(response)

    var responseBody = response?.body()

    if(responseBody != null )
    {
        var responseBodyString = responseBody?.string()

            response = response.newBuilder()
                .body(
                    ResponseBody.create(
                        responseBody?.contentType(),
                        responseBodyString.toByteArray()
                    )
                )
                .build()


        responseBodyString = gson.toJson(responseBodyString)

        Timber.d("response json -> \n $responseBodyString")

    }

    Timber.d(" **** << Response from server ****")

    return response
}



fun dumbHeaders(response: Response) {
    try {
        if (response.headers() != null) {

            for (headerName in response.headers().names()) {
                for (headerValue in response.headers(headerName)) {
                    Timber.d("Header $headerName : $headerValue")
                }
            }
        }
    }
catch (ex: Exception){}
}
}

Solution 5 - Java

Instead of using .toString() which returns an object

String results = response.body().toString();

you can use

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

Solution 6 - Java

Given that a response can potentially produce an OutOfMemoryError in cases of large files, you can instead "peek" the body with the number of bytes and call the string() method.

Note that this will consume the body.

response.peekBody(500).string());

Solution 7 - Java

try to change it like that for example:

protected String doInBackground(String... params) {
            try {
                JSONObject root = new JSONObject();
                JSONObject data = new JSONObject();
                data.put("type", type);
                data.put("message", message);
                data.put("title", title);
                data.put("image_url", imageUrl);
                data.put("uid",uid);
                data.put("id", id);
                data.put("message_id", messageId);
                data.put("display_name", displayName);
                root.put("data", data);
                root.put("registration_ids", new JSONArray(receipts));
                RequestBody body = RequestBody.create(JSON, root.toString());
                Request request = new Request.Builder()
                        .url(URL)
                        .post(body)
                        .addHeader("Authorization", "key=" + serverKey)
                        .build();
                Response response = mClient.newCall(request).execute();
                String result = response.body().string();
                Log.d(TAG, "Result: " + result);
                return result;
            } catch (Exception ex) {
                Log.e(TAG,"Exception -> "+ex.getMessage());
            }
            return null;
        }

Solution 8 - Java

Recreate the response object after consuming the string

val responseBodyString = response.body()!!.string()

response = response.newBuilder() .body(ResponseBody.create(responseBody?.contentType(), responseBodyString.toByteArray())) .build()

Solution 9 - Java

   Call call = client.newCall(request);
   return call.execute().body().string();

we can get response as a return fromby these

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionfreddieptfView Question on Stackoverflow
Solution 1 - JavaV.J.View Answer on Stackoverflow
Solution 2 - JavaOded RegevView Answer on Stackoverflow
Solution 3 - JavaNethaji NarasimaluView Answer on Stackoverflow
Solution 4 - JavaImran BaigView Answer on Stackoverflow
Solution 5 - JavaMarko SlijepčevićView Answer on Stackoverflow
Solution 6 - JavavphilipnycView Answer on Stackoverflow
Solution 7 - JavaAoun allah BillelView Answer on Stackoverflow
Solution 8 - JavaImran BaigView Answer on Stackoverflow
Solution 9 - JavaUtkarsh chakrwartiView Answer on Stackoverflow