Post 通过 ktor-client 多部分
Post multipart via ktor-client
我必须通过 ktor-client 发出多部分请求。请求方式:
suspend fun uploadPhoto(userId: String, bitmapPhoto: BitmapPhoto) {
kotlin.runCatching {
val response: HttpResponse = httpClient.submitFormWithBinaryData(
url = BASE_URL.plus("$userId/${bitmapPhoto.name}"),
formData = formData {
append("file", bitmapPhoto.bitmap.toByteArray(),
Headers.build {
append(HttpHeaders.ContentType, "multipart/form-data; boundary=boundary")
append(HttpHeaders.ContentDisposition, "form-data; name=file; filename=${bitmapPhoto.name}")
}
)
}
)
}
执行请求时服务器returns出错。
有正确请求的例子
POST https://host-name.com
Content-Type: multipart/form-data; boundary=boundary;
--boundary
Content-Disposition: form-data; name="file"; filename="image.png"
< C:/path/image.png
--boundary
所以我不明白我的 kotlin 方法哪里不正确
更新
方法的第一个变体是
suspend fun uploadPhoto(userId: String, bitmapPhoto: BitmapPhoto) {
kotlin.runCatching {
val response: HttpResponse = httpClient.submitFormWithBinaryData(
url = BASE_URL.plus("$userId/${bitmapPhoto.name}"),
formData = formData {
append("file", bitmapPhoto.bitmap.toByteArray(),
Headers.build {
append(HttpHeaders.ContentType, "image/png")
append(HttpHeaders.ContentDisposition, "filename=${bitmapPhoto.name}")
}
)
}
)
}
但是没用所以
问题在以下headers:
append(HttpHeaders.ContentType, "multipart/form-data; boundary=boundary")
append(HttpHeaders.ContentDisposition, "form-data; name=file; filename=${bitmapPhoto.name}")
Content-Type
header 应该有你的文件内容的 MIME 类型 (bitmapPhoto
),而不是请求的类型 body (Ktor 添加它自动),例如image/png
。 Content-Disposition
header 对于你的情况应该只有 filename=${bitmapPhoto.name}
值,因为 Ktor 会自动添加 form-data; name=file;
。所以你的代码应该是这样的:
append(HttpHeaders.ContentType, "image/png")
append(HttpHeaders.ContentDisposition, "filename=${bitmapPhoto.name}")
更多信息,请参考Ktor documentation。
我必须通过 ktor-client 发出多部分请求。请求方式:
suspend fun uploadPhoto(userId: String, bitmapPhoto: BitmapPhoto) {
kotlin.runCatching {
val response: HttpResponse = httpClient.submitFormWithBinaryData(
url = BASE_URL.plus("$userId/${bitmapPhoto.name}"),
formData = formData {
append("file", bitmapPhoto.bitmap.toByteArray(),
Headers.build {
append(HttpHeaders.ContentType, "multipart/form-data; boundary=boundary")
append(HttpHeaders.ContentDisposition, "form-data; name=file; filename=${bitmapPhoto.name}")
}
)
}
)
}
执行请求时服务器returns出错。 有正确请求的例子
POST https://host-name.com
Content-Type: multipart/form-data; boundary=boundary;
--boundary
Content-Disposition: form-data; name="file"; filename="image.png"
< C:/path/image.png
--boundary
所以我不明白我的 kotlin 方法哪里不正确
更新 方法的第一个变体是
suspend fun uploadPhoto(userId: String, bitmapPhoto: BitmapPhoto) {
kotlin.runCatching {
val response: HttpResponse = httpClient.submitFormWithBinaryData(
url = BASE_URL.plus("$userId/${bitmapPhoto.name}"),
formData = formData {
append("file", bitmapPhoto.bitmap.toByteArray(),
Headers.build {
append(HttpHeaders.ContentType, "image/png")
append(HttpHeaders.ContentDisposition, "filename=${bitmapPhoto.name}")
}
)
}
)
}
但是没用所以
问题在以下headers:
append(HttpHeaders.ContentType, "multipart/form-data; boundary=boundary")
append(HttpHeaders.ContentDisposition, "form-data; name=file; filename=${bitmapPhoto.name}")
Content-Type
header 应该有你的文件内容的 MIME 类型 (bitmapPhoto
),而不是请求的类型 body (Ktor 添加它自动),例如image/png
。 Content-Disposition
header 对于你的情况应该只有 filename=${bitmapPhoto.name}
值,因为 Ktor 会自动添加 form-data; name=file;
。所以你的代码应该是这样的:
append(HttpHeaders.ContentType, "image/png")
append(HttpHeaders.ContentDisposition, "filename=${bitmapPhoto.name}")
更多信息,请参考Ktor documentation。