skip to Main Content

I’m trying to upload an image to an http server that supposedly accepts files in "the standard way", whatever that means. I’ve combined a bunch of examples from the Internet, each of which does a tiny part of what I want, into this solution.

'srcBitmap' is a byteArray containing the JPG data.

val response: HttpResponse = httpClient.submitFormWithBinaryData(
    url = URLUploadFile,
    formData = formData {
        append("bitmapName", "image.jpg")
        append("image", srcBitmap, Headers.build {
            append(HttpHeaders.ContentType, "image/jpg")
            append(HttpHeaders.ContentDisposition, "filename=image.jpg")
        })
    },
    block = {
        headers {
            append(HttpHeaders.ContentType, contentTypeString)
            append(HttpHeaders.CacheControl, "no-cache")
            append("my-app-authtoken", PREFKEY_AUTHTOKEN)
            append("my-app-id", PREFKEY_USERID)
        }
        contentType(ContentType.Application.Json)
        body = jsonBody.toString()
    })

The main "body" part is some json that gets passed in the ‘block’ parameter. This data is arriving safely as intended.

But the binary data of the image itself is either not showing up on the server side, or is being ignored by the server because I don’t have some "key" value set appropriately.

Is this the correct way to upload a file using Ktor? And if not, what am I doing wrong?

2

Answers


  1. The second append call is a correct way of sending a part with the name image and the filename image.jpg. The problem is that you can’t send both application/json and multipart/form-data content in one request.

    Login or Signup to reply.
  2. Actually yours is a correct way, I was facing the same problem with my back-end guy that he receives my request as a byteArray file and couldn’t recognized. So what I did was specify the files directly to the body instead of using submitFormWithBinaryData, as below..

    ‘srcBitmap’ is a byteArray containing the JPG data.

     httpClient.post<RESPONSE>(URL) {
                headers {
                    append(HttpHeaders.Accept, ContentType.Application.Json)
                }
                body = MultiPartFormDataContent(
                    formData {
                        this.append(FormPart("bitmapName", "image.jpg"))
                        this.appendInput(
                            key = "image",
                            headers = Headers.build {
                                append(
                                    HttpHeaders.ContentDisposition,
                                    "filename=image.jpg"
                                )
                            },
                        ) { buildPacket { writeFully(srcBitmap) } }
                    }
                        )
                    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search