我正在尝试使用 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()
:这会以字符串格式返回您的对象。.string()
:这将返回您的响应。 我认为这可以解决你的问题......对。
以防万一有人遇到和我一样奇怪的事情。我在开发过程中以 调试模式 运行我的代码,显然是从 OKHttp 2.4 开始
..响应正文是一次性值,只能消耗一次
因此,在调试时,检查器会在“幕后”进行调用,并且主体始终为空。请参阅:https://square.github.io/okhttp/2.x/okhttp/com/squareup/okhttp/ResponseBody.html
response.body.string()
只能食用一次。
请按以下方式使用:
String responseBodyString = response.body.string();
根据应用程序中的需要使用responseBodyString。
以下是我修改后的CurlInterceptor。检查拦截函数的末尾,我在消耗旧响应后重新创建响应对象。
var responseBodyString = responseBody?.string()
响应=response.newBuilder() 。身体( ResponseBody.create( .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){}
}
}
鉴于在大文件的情况下响应可能会产生
OutOfMemoryError
,您可以改为“查看”正文的字节数并调用 string()
方法。
注意这会消耗身体。
response.peekBody(500).string());
而不是使用返回对象的 .toString()
String results = response.body().toString();
你可以使用
String results = response.body().string();
Call call = client.newCall(request);
return call.execute().body().string();
我们可以通过这些得到回复作为回报
尝试像这样改变它,例如:
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;
}
消耗字符串后重新创建响应对象
val responseBodyString = response.body()!!.string()
响应=response.newBuilder() .body(ResponseBody.create(responseBody?.contentType(), responseBodyString.toByteArray())) .build()
Kotlin 程序员我在这里等你
response.body?.charStream()?.readText()?.let {
//Where it refers to Response string
callBack.onAPISuccess(it)
}
在这里你不能使用 .toString() 函数,并且 .string() 函数在 Kotlin 中不可用,你可以使用 charStream() 并将该 charStream 转换为 readText() 但你必须在传递之前解开整个值。但这永远不会造成问题。
我还没有在java中探索过这些charStream()和readText()函数,但我认为它应该在那里,如果这些函数可用,你可以在java中使用它,因为我刚刚知道java已经弃用了.string()功能。