【问题标题】:Can't get OkHttp's response.body.toString() to return a string无法让 OkHttp 的 response.body.toString() 返回字符串
【发布时间】:2015-04-02 17:37:19
【问题描述】:

我正在尝试使用 OkHttp 获取一些 json 数据,但无法弄清楚为什么当我尝试记录 response.body().toString() 时,我得到的是 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);

我不知道我在这里做错了什么。如何获取响应字符串?

【问题讨论】:

标签: java android okhttp


【解决方案1】:

您已使用.string() 函数在System.out.println() 中打印响应。但最后在Log.i() 你使用的是.toString()

所以请在响应正文中使用.string() 打印并获取您的请求响应,例如:

response.body().string();

注意:

  1. .toString():这会以字符串格式返回您的对象。

  2. .string():这将返回您的响应。

我认为这可以解决您的问题...对。

【讨论】:

  • 没有 string() 函数了,现在怎么办?
  • @eCDroid "没有更多的 string() 函数" 你确定吗?
  • 根据文档`自动关闭ResponseBody。`您需要记住,调用此方法后您将无法读取响应
【解决方案2】:

以防万一有人碰到和我一样奇怪的东西。我在 Debug Mode 的开发过程中运行我的代码,显然是从 OKHttp 2.4

..响应正文是一次性值,只能使用一次

因此,在调试时,检查员会在“幕后”进行调用,并且正文始终为空。见:https://square.github.io/okhttp/3.x/okhttp/okhttp3/ResponseBody.html

【讨论】:

  • 如何在不消耗响应正文的情况下调用.string()
  • 不确定是否可以在不消耗响应正文的情况下调用 .string(),但可以作为一种解决方法,但您可以按照 okhttp 的日志拦截器执行此操作的模式:github.com/square/okhttp/blob/master/okhttp-logging-interceptor/…
  • 表示我们无法调试Okhttp响应体
  • 您可以在禁用调试的情况下将响应正文打印到日志
  • 多么邪恶的行为!我知道这种cmets有多么无用,不过还是要谢谢你
【解决方案3】:

response.body,.string() 只能使用一次。 请按如下方式使用:

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

【讨论】:

  • 这可能会触发一个 OutOfMemoryError 用于大型响应(即 zip 文件)
【解决方案4】:

而不是使用 .toString() 返回一个对象

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

你可以使用

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

【讨论】:

    【解决方案5】:

    以下是我修改后的 CurlInterceptor。检查拦截函数的结尾,我在使用旧的响应后重新创建响应对象。

    var responseBodyString = responseBody?.string()

    响应 = response.newBuilder() 。身体( 响应体.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){}
    }
    }
    

    【讨论】:

      【解决方案6】:

      尝试像这样改变它,例如:

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

      【讨论】:

      • 不鼓励仅使用代码的答案。请单击edit 并添加一些词来总结您的代码如何解决问题,或者解释您的答案与之前的答案/答案有何不同。谢谢
      【解决方案7】:

      鉴于在大文件的情况下响应可能会产生OutOfMemoryError,您可以改为“查看”带有字节数的正文并调用string() 方法。

      注意这会消耗身体。

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

      【讨论】:

        【解决方案8】:

        消费字符串后重新创建响应对象

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

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

        【讨论】:

          猜你喜欢
          • 2021-10-22
          • 2016-06-16
          • 2013-03-31
          • 2015-02-25
          • 1970-01-01
          • 2022-01-23
          • 2014-06-28
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多