#scala #playframework #multipartform-data
#scala #playframework #составная часть-данные
Вопрос:
Я пытаюсь отправить PDF-файл во внешнюю службу с помощью запроса multipart / form-data. Я сделал это с образцом клиента Java Script, чтобы внешняя служба работала должным образом. Я перешел в scala со следующим кодом, который я получил: Неверный запрос:
import akka.stream.scaladsl.FileIO
import akka.stream.scaladsl.Source
import play.api.libs.ws.WSClient
import play.api.mvc.MultipartFormData._
val pathToFile = "./sampleCV.pdf"
val fileName = "sampleCV.pdf"
val futureResponse = ws.url(url).withRequestTimeout(Duration.create(55, TimeUnit.SECONDS))
.addHttpHeaders("authorization" -> s"bearer $access_token")
.addHttpHeaders("accept" -> "*/*")
.addHttpHeaders("content-type" -> "multipart/form-data")
.post(Source(
FilePart("File", fileName, Option("application/pdf"), FileIO.fromPath(Paths.get(pathToFile))) :: List()
))
Версия воспроизведения: 2.6.19
Следуя команде curl, загрузите файл правильно:
curl -X POST "https://rest_url" -H "accept: */*" -H "Authorization: bearer <TOKEN>" -H "Content-Type: multipart/form-data" -F "File=@sampleCV.pdf;type=application/pdf"
Я пропустил какой-то важный параметр в post(...)
? Каковы соответствующие параметры post в ScalaWS, которые соответствуют этому запросу CURL?
Комментарии:
1. Сначала проверьте свой запрос, например, с помощью cURL
2. Я отредактировал вопрос и добавил пример curl POST, который работает с этим сервисом. Спасибо!
3. Заголовок
accept
отличается, также поле файлаFile
!=cv
и проверьте токен (который в качестве значения Scala должен быть скорее названaccessToken
)4. Выполнено — результат тот же — Неверный запрос
Ответ №1:
При использовании составных / данных формы требуется параметр границы. Заголовок типа содержимого будет выглядеть примерно так:
Content-Type: multipart/form-data; boundary=nZaYg9TFHoDaLWhs8w
Вы задаете заголовок типа содержимого с помощью addHttpHeaders
, но поскольку в нем отсутствует параметр boundary, он не работает.
Решение состоит в том, чтобы не устанавливать этот заголовок вручную, фактически вам никогда не понадобится устанавливать этот заголовок. Play-WS добавит соответствующий заголовок типа содержимого на основе типа объекта, который вы передаете post
методу. Когда вы передаете Source[Part[Source[ByteString, Any]]]
, он установит тип содержимого составных / данных формы, а также добавит соответствующий граничный параметр.
Ответ №2:
Я столкнулся с той же проблемой, добавив заголовок Content-Length, решаемый в mycase. Добавлен заголовок, как показано ниже, в WSRequest,
wsRequest.setHeader("Content-Length", String.valueOf(fileToUpload.length()));
Здесь fileToUpload является java.io .Файловый объект, который вы пытаетесь загрузить.