How to upload a single bitmap image using ktor?

Viewed 987

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

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.

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