Consider the following code:
OkHttpClient client = new OkHttpClient();
MediaType mediaType = MediaType.parse(\"text/plain; charset=utf-8\"); // [A]
When you create requestbody, just set the content typy as "null", and add header manual, like this:
OkHttpClient client = new OkHttpClient();
RequestBody body = RequestBody.create('your media string', null);
String[] aclHeader = "x-goog-acl:public-read".split(":");
Request request = new Request.Builder()
.addHeader("Content-Type", "text/plain") // [B]
.addHeader(aclHeader[0], aclHeader[1])
.url(url)
.put(body)
.build();
Response response = client.newCall(request).execute();
Beacuse when I read okhttp source code, in RequestBody.kt, I find following code:
/**
* Returns a new request body that transmits this string. If [contentType] is non-null and lacks
* a charset, this will use UTF-8.
*/
@JvmStatic
@JvmName("create")
fun String.toRequestBody(contentType: MediaType? = null): RequestBody {
var charset: Charset = UTF_8
var finalContentType: MediaType? = contentType
if (contentType != null) {
val resolvedCharset = contentType.charset()
if (resolvedCharset == null) {
charset = UTF_8
finalContentType = "$contentType; charset=utf-8".toMediaTypeOrNull()
} else {
charset = resolvedCharset
}
}
val bytes = toByteArray(charset)
return bytes.toRequestBody(finalContentType, 0, bytes.size)
}
I found the solution:
The following line is the culprit:
RequestBody body = RequestBody.create(mediaType, media);
create has 3 signatures for media:
When I pass a String, it disregards the supplied mediaType and adds the charset to it. Even for image/jpeg it would send
image/jpeg; charset=utf-8
to the server.
Using byte[] or File suppresses that behavior.
I hope this helps you!
[Stupid me - for simplicity I gave it a String during testing, as I didn't care about the body ;-( ]