How to suppress Charset being automatically added to Content-Type in okhttp

前端 未结 2 948
爱一瞬间的悲伤
爱一瞬间的悲伤 2021-01-04 01:05

Consider the following code:

    OkHttpClient client = new OkHttpClient();

    MediaType mediaType = MediaType.parse(\"text/plain; charset=utf-8\"); // [A]
         


        
相关标签:
2条回答
  • 2021-01-04 01:39

    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)
        }
    
    0 讨论(0)
  • 2021-01-04 01:58

    I found the solution:

    The following line is the culprit:

    RequestBody body = RequestBody.create(mediaType, media);
    

    create has 3 signatures for media:

    • String
    • byte[]
    • File

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

    0 讨论(0)
提交回复
热议问题