【问题标题】:OkHttp Post Body as JSONOkHttp 以 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"} Response{protocol=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=

标签: android json http-post okhttp android-ion


【解决方案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

【讨论】:

  • 不工作。这没有道理。 jsonStringString 没有 toRequestBody() 方法
  • 基于@parsecer 的评论,重要的是要注意上面不是Java - 它是Kotlin。
猜你喜欢
  • 2015-05-11
  • 2021-10-16
  • 2018-09-16
  • 2021-03-17
  • 1970-01-01
  • 1970-01-01
  • 2017-09-07
  • 2016-01-31
相关资源
最近更新 更多