OkHttp Post Body as JSON

AndroidJsonHttp PostOkhttpAndroid Ion

Android Problem Overview


So, back when I was using Koush's Ion, I was able to add a json body to my posts with a simple .setJsonObjectBody(json).asJsonObject()

I'm moving over to OkHttp, and I really don't see a good way to do that. I'm getting error 400's all over the place.

Anyone have any ideas?

I've even tried manually formatting it as a json string.

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();
            }
        });*/

Android Solutions


Solution 1 - Android

Just use JSONObject.toString(); method. And have a look at OkHttp's tutorial:

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

Solution 2 - Android

You can create your own JSONObject then toString().

Remember run it in the background thread like doInBackground in AsyncTask.

OkHttp version > 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 version 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();
  }

Solution 3 - Android

Another approach is by using FormBody.Builder().
Here's an example of callback:

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

Then, we create our own body:

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();

Finally, we call the server:

client.newCall(request).enqueue(loginCallback);

Solution 4 - Android

In kotlin, in okhttp v4.* I got it working that way


// 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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionPixel PerfectView Question on Stackoverflow
Solution 1 - AndroidOstap AndrusivView Answer on Stackoverflow
Solution 2 - AndroidAllenView Answer on Stackoverflow
Solution 3 - AndroidAbdulMomen عبدالمؤمنView Answer on Stackoverflow
Solution 4 - AndroidlcapraView Answer on Stackoverflow