OkHttp 以 JSON 形式发布正文
Posted
技术标签:
【中文标题】OkHttp 以 JSON 形式发布正文【英文标题】:OkHttp Post Body as JSON 【发布时间】:2016-03-14 19:00:10 【问题描述】:所以,当我使用 Koush 的 Ion 时,我可以通过简单的 .setJsonObjectBody(json).asJsonObject()
将 json 正文添加到我的帖子中
我正在迁移到 OkHttp,但我真的看不出有什么好方法。我到处都是错误 400。
有人有什么想法吗?
我什至尝试过手动将其格式化为 json 字符串。
String reason = menuItem.getTitle().toString();
JsonObject json = new JsonObject();
json.addProperty("Reason", reason);
String url = mBaseUrl + "/" + id + "/report";
Request request = new Request.Builder()
.header("X-Client-Type", "android")
.url(url)
.post(RequestBody
.create(MediaType
.parse("application/json"),
"\"Reason\": \"" + reason + "\""
))
.build();
client.newCall(request).enqueue(new com.squareup.okhttp.Callback()
@Override
public void onFailure(Request request, IOException throwable)
throwable.printStackTrace();
@Override
public void onResponse(Response response) throws IOException
if (!response.isSuccessful()) throw new IOException(
"Unexpected code " + response);
runOnUiThread(new Runnable()
@Override
public void run()
Toast.makeText(context, "Report Received", Toast.LENGTH_SHORT).show();
);
);
/*Ion.with(getContext(), url)
.setHeader("X-Client-Type", "Android")
.setJsonObjectBody(json)
.asJsonObject()
.setCallback(new FutureCallback<JsonObject>()
@Override
public void onCompleted(Exception e, JsonObject result)
Toast.makeText(context, "Report Received", Toast.LENGTH_SHORT).show();
);*/
【问题讨论】:
您的网址是否在开始时包含“http://”? https://,实际上,但是是的 您是否信任过您应用的证书? 好吧,看到我得到 "Reason":"Inappropriate" Responseprotocol=http/1.1, code=200, message=OK, url=api/id/report "Reason": “版权” 响应protocol=http/1.1, code=400, message=Bad Request, url=api/id/report 23 分钟 它取出了我的 https:// 作为 url= 【参考方案1】:只需使用JSONObject.toString();
method。
并看看 OkHttp 的教程:
public static final MediaType JSON
= MediaType.parse("application/json; charset=utf-8");
OkHttpClient client = new OkHttpClient();
String post(String url, String json) throws IOException
RequestBody body = RequestBody.create(json, JSON); // new
// RequestBody body = RequestBody.create(JSON, json); // old
Request request = new Request.Builder()
.url(url)
.post(body)
.build();
Response response = client.newCall(request).execute();
return response.body().string();
【讨论】:
好吧,我需要看看后端是否正常工作。您的代码与我的代码行为相同 - 当我为 JSON 中的字符串提供一个东西时崩溃,但当我提供不同的东西时工作。 RequestBody.create() 已弃用 @Iman Marashi 不推荐使用的不是方法名称。不推荐使用的是方法参数。实际上,最新版本仅将 MediaType 替换为第二个参数。没有更多的改变。所以,应该是RequestBody body = RequestBody.create(json, JSON);
并且.....问题解决了
@HardikParmar,不推荐使用的不是方法名称,而是一个参数。只需替换第一个和第二个参数,正如 poring91 提到的那样
这是一个过时的解决方案。请参阅@Allen 的回答。【参考方案2】:
您可以创建自己的JSONObject
然后toString()
。
记得在后台线程中运行它,例如doInBackground
in AsyncTask
。
OkHttp 版本 > 4:
import okhttp3.MediaType.Companion.toMediaType
// create your json here
JSONObject jsonObject = new JSONObject();
try
jsonObject.put("KEY1", "VALUE1");
jsonObject.put("KEY2", "VALUE2");
catch (JSONException e)
e.printStackTrace();
val client = OkHttpClient()
val mediaType = "application/json; charset=utf-8".toMediaType()
val body = jsonObject.toString().toRequestBody(mediaType)
val request: Request = Request.Builder()
.url("https://YOUR_URL/")
.post(body)
.build()
var response: Response? = null
try
response = client.newCall(request).execute()
val resStr = response.body!!.string()
catch (e: IOException)
e.printStackTrace()
OkHttp 版本 3:
// create your json here
JSONObject jsonObject = new JSONObject();
try
jsonObject.put("KEY1", "VALUE1");
jsonObject.put("KEY2", "VALUE2");
catch (JSONException e)
e.printStackTrace();
OkHttpClient client = new OkHttpClient();
MediaType JSON = MediaType.parse("application/json; charset=utf-8");
// put your json here
RequestBody body = RequestBody.create(JSON, jsonObject.toString());
Request request = new Request.Builder()
.url("https://YOUR_URL/")
.post(body)
.build();
Response response = null;
try
response = client.newCall(request).execute();
String resStr = response.body().string();
catch (IOException e)
e.printStackTrace();
【讨论】:
这不起作用:val mediaType = "application/json; charset=utf-8".toMediaType();
.
如果我试试这个---> RequestBody body = RequestBody.create(JSON, jsonObject.toString());在 JSON 对象中添加 JSON 数组,数组值变为字符串,只想传递 JSON 数组数据而不是字符串,任何人都帮我解决这个问题【参考方案3】:
另一种方法是使用FormBody.Builder()
。
下面是一个回调的例子:
Callback loginCallback = new Callback()
@Override
public void onFailure(Call call, IOException e)
try
Log.i(TAG, "login failed: " + call.execute().code());
catch (IOException e1)
e1.printStackTrace();
@Override
public void onResponse(Call call, Response response) throws IOException
// String loginResponseString = response.body().string();
try
JSONObject responseObj = new JSONObject(response.body().string());
Log.i(TAG, "responseObj: " + responseObj);
catch (JSONException e)
e.printStackTrace();
// Log.i(TAG, "loginResponseString: " + loginResponseString);
;
然后,我们创建自己的身体:
RequestBody formBody = new FormBody.Builder()
.add("username", userName)
.add("password", password)
.add("customCredential", "")
.add("isPersistent", "true")
.add("setCookie", "true")
.build();
OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(this)
.build();
Request request = new Request.Builder()
.url(loginUrl)
.post(formBody)
.build();
最后,我们调用服务器:
client.newCall(request).enqueue(loginCallback);
【讨论】:
谢谢,这个答案非常适合我。但我有一个问题,发送 JSON 类型的额外参数的最佳方法是什么。这就是请求的工作方式image,这就是我发送RequestBody
信息image 的方式。该代码运行良好,但我从响应中收到一条错误消息,告诉我 Image 参数不正确。也许我需要变成一个对象并解析为String
?。提前致谢
如何将 JSON 作为块添加到 FormBody 中,而无需手动添加每个键值对。【参考方案4】:
在 kotlin 中,在 okhttp v4 中。* 我是这样工作的
// import the extensions!
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.RequestBody.Companion.toRequestBody
// ...
json : String = "..."
val JSON : MediaType = "application/json; charset=utf-8".toMediaType()
val jsonBody: RequestBody = json.toRequestBody(JSON)
// go on with Request.Builder() etc
【讨论】:
不工作。这没有道理。json
是 String
。 String
没有 toRequestBody()
方法
基于@parsecer 的评论,重要的是要注意上面不是Java - 它是Kotlin。以上是关于OkHttp 以 JSON 形式发布正文的主要内容,如果未能解决你的问题,请参考以下文章
OkHttp 2.0 响应(POST 请求)正文字符串为空字符串