无法将 OkHttp 的 response.body.toString() 转换为 return 字符串
Can't get OkHttp's response.body.toString() to return a string
我正在尝试使用 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);
我不知道我做错了什么。我如何获得响应字符串?
您已使用 .string()
函数在 System.out.println()
中打印响应。但最后在 Log.i()
你使用的是 .toString()
.
因此请在响应正文中使用 .string()
来打印并获取您的请求响应,例如:
response.body().string();
注意:
.toString()
: 这个returns你的字符串格式的对象。
.string()
:这 returns 您的回复。
我认为这可以解决您的问题...对。
以防万一有人遇到和我一样奇怪的事情。我 运行 我的代码在开发期间处于 调试模式 并且显然是因为 OKHttp 2.4
..the response body is a one-shot value that may be consumed only once
因此,在调试时,检查员会调用 "behind the scene" 并且正文始终为空。参见:https://square.github.io/okhttp/3.x/okhttp/okhttp3/ResponseBody.html
response.body.string()
只能消耗一次。
请按以下方式使用:
String responseBodyString = response.body.string();
根据需要在您的应用程序中使用 responseBodyString。
试着改变它,例如:
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;
}
鉴于在大文件的情况下响应可能会产生 OutOfMemoryError
,您可以改为“查看”body 的字节数并调用 string()
方法.
请注意,这将消耗 body。
response.peekBody(500).string());
使用字符串后重新创建响应对象
val responseBodyString = response.body()!!.string()
响应=response.newBuilder()
.body(ResponseBody.create(responseBody?.contentType(), responseBodyString.toByteArray()))
.build()
以下是我修改的CurlInterceptor。检查拦截函数的结尾,我在使用旧的 Response 后重新创建 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){}
}
}
而不是使用 .toString() returns 一个对象
String results = response.body().toString();
你可以使用
String results = response.body().string();
Call call = client.newCall(request);
return call.execute().body().string();
我们可以从这些
中得到 return 的回复
Kotlin 程序员我在这里等你
response.body?.charStream()?.readText()?.let {
//Where it refers to Response string
callBack.onAPISuccess(it)
}
在这里您不能使用 .toString() 函数,并且 .string() 函数在 Kotlin 中不可用,您可以使用 charStream() 并将该 charStream 转换为 readText() 但您必须解包整个值在通过 it.But 之前,它永远不会产生问题。
我没有在 java 中探讨这些 charStream() 和 readText() 函数,但我认为它应该在那里,如果这些函数可用,您可以在 java 中使用它,因为我只是知道 java 已弃用 .string() 函数。
我正在尝试使用 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);
我不知道我做错了什么。我如何获得响应字符串?
您已使用 .string()
函数在 System.out.println()
中打印响应。但最后在 Log.i()
你使用的是 .toString()
.
因此请在响应正文中使用 .string()
来打印并获取您的请求响应,例如:
response.body().string();
注意:
.toString()
: 这个returns你的字符串格式的对象。.string()
:这 returns 您的回复。
我认为这可以解决您的问题...对。
以防万一有人遇到和我一样奇怪的事情。我 运行 我的代码在开发期间处于 调试模式 并且显然是因为 OKHttp 2.4
..the response body is a one-shot value that may be consumed only once
因此,在调试时,检查员会调用 "behind the scene" 并且正文始终为空。参见:https://square.github.io/okhttp/3.x/okhttp/okhttp3/ResponseBody.html
response.body.string()
只能消耗一次。
请按以下方式使用:
String responseBodyString = response.body.string();
根据需要在您的应用程序中使用 responseBodyString。
试着改变它,例如:
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;
}
鉴于在大文件的情况下响应可能会产生 OutOfMemoryError
,您可以改为“查看”body 的字节数并调用 string()
方法.
请注意,这将消耗 body。
response.peekBody(500).string());
使用字符串后重新创建响应对象
val responseBodyString = response.body()!!.string()
响应=response.newBuilder() .body(ResponseBody.create(responseBody?.contentType(), responseBodyString.toByteArray())) .build()
以下是我修改的CurlInterceptor。检查拦截函数的结尾,我在使用旧的 Response 后重新创建 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){}
}
}
而不是使用 .toString() returns 一个对象
String results = response.body().toString();
你可以使用
String results = response.body().string();
Call call = client.newCall(request);
return call.execute().body().string();
我们可以从这些
中得到 return 的回复Kotlin 程序员我在这里等你
response.body?.charStream()?.readText()?.let {
//Where it refers to Response string
callBack.onAPISuccess(it)
}
在这里您不能使用 .toString() 函数,并且 .string() 函数在 Kotlin 中不可用,您可以使用 charStream() 并将该 charStream 转换为 readText() 但您必须解包整个值在通过 it.But 之前,它永远不会产生问题。
我没有在 java 中探讨这些 charStream() 和 readText() 函数,但我认为它应该在那里,如果这些函数可用,您可以在 java 中使用它,因为我只是知道 java 已弃用 .string() 函数。