Загрузка картинок, используя ktor и kotlin
В двух словах описать не получится. Пожертвую краткостью в пользу подробности. Дано: Сайт, на котором можно создать сущность (пусть будет Профиль). Разумеется, сделать это можно по запросу на определённый эндпоинт сервера. Для создания Профиля в теле POST запроса передаются некоторые данные, в том числе фото. Фото - необязательное поле.
Также есть Прога, которую я потихоньку пишу и с помощью неё тестирую эндпойнты и документацию. Прога написана на Kotlin, а сетевое взаимодействие реализовано через фреймворк Ktor.
Столкнулся с такой сложностью как отправка фото на сервер. Так как фото - необязательное поле, сначала попробовал построить запрос для создания Профиля без фото. Успешно. Но когда пытаюсь прикрепить фото, ничего не выходит, как бы не старался. Такое ощущение что я что-то упустил, но не могу понять что.
Вопрос: Как обработать фото так, чтобы сервер смог его принять?
Вот самый успешный вариант кода:
suspend fun main() {
println(res())
}
val cat = File("resources/Cat.jpg").readBytes()
val client = HttpClient(CIO) {
expectSuccess = false
}
suspend fun res(): String {
val response = client.post<HttpResponse>("http://my_endoint/create_profile/") {
header("Authorization", "$token")
body = MultiPartFormDataContent(formData {
append("some_key_1", "some_value")
append("some_key_2", "some_value")
append("some_key_3", "some_value")
append("photos", cat, Headers.build {
append(HttpHeaders.ContentType, "image/jpg")
})
})
return "${response.status}\n${response.readText()}"
}
Задача - добиться 201 ответа при загрузке фото.
Примечание: Сравнивал трафик, идущий через сайт и через мою Прогу. Почему-то Content-Length фото различается на 101 байт.
Ответы (1 шт):
Нужно было всего лишь добавить хэдер с именем файла. Итого рабочий код будет выглядеть так:
suspend fun main() {
println(res())
}
val cat = File("resources/Cat.jpg").readBytes()
val client = HttpClient(CIO) {
expectSuccess = false
}
suspend fun res(): String {
val response = client.post<HttpResponse>("http://my_endoint/create_profile/") {
header("Authorization", "$token")
body = MultiPartFormDataContent(formData {
append("some_key_1", "some_value")
append("some_key_2", "some_value")
append("some_key_3", "some_value")
append("photos", cat, Headers.build {
append(HttpHeaders.ContentType, "image/jpg")
append(HttpHeaders.ContentDisposition, "filename=\"Cat.jpg\"")
})
})
return "${response.status}\n${response.readText()}"
}
Очень важно учесть кавычки перед именем файла. Без них сервер вернёт ошибку.