Отправить часть json в составном запросе play-ws

#scala #playframework #play-ws

#scala #playframework #воспроизведение-ws

Вопрос:

Я реализую внешний API, в котором мне нужно отправить вложение файла в комплекте с мета-частью JSON.

Следующий код не принимается сервером, поскольку Play жестко кодирует тип содержимого DataPart to text/plain , и сервер ожидает application/json

 val meta = Json.obj(
  "name" -> s"Invoice ${invoiceNumber}.pdf",
  "referenceType" -> "INVOICE",
  "referenceId" -> 42
)

ws.url("{API-URL}")
  .addHttpHeaders("Authorization" -> s"Bearer ${accessToken}")
  .post(Source(DataPart("meta", meta.toString) :: FilePart("file", s"Invoice ${invoiceNumber}.pdf", Option("application/pdf"), FileIO.fromPath(file.toPath)) :: List()))
  .map(res => {
    logger.debug("Status: "   res.status)
    logger.debug("JSON: "   res.json)

    Right(invoiceNumber)
  })
  

Примером команды curl (которую я протестировал и проверил) для конечной точки API является:

 curl -H "Authorization: Bearer {accessToken}" 
  -F 'meta={"name": "Invoive 4.pdf", "referenceType": "INVOICE", "referenceId": 42 } 
  ;type=application/json' 
  -F "file=@Invoice.pdf" 
  '{API-URL}'
  

Есть ли простой способ либо заставить DataPart использовать другой тип содержимого, либо использовать другую часть, чтобы получить больше контроля над тем, что я отправляю?

Ответ №1:

Я нашел решение проблемы:

Сначала я создаю временный файл для хранения метаданных

 val meta = new File(s"/tmp/${UUID.randomUUID()}")
Files.write(meta.toPath, Json.obj(
  "name" -> s"Invoice ${invoiceNumber}.pdf",
  "referenceType" -> "INVOICE",
  "referenceId" -> 42
).toString.getBytes)
  

Затем я использую два FilePart в своем запросе:

 ws.url("{API-URL}")
  .addHttpHeaders("Authorization" -> s"Bearer ${accessToken}")
  .post(Source(FilePart("meta", "", Option("application/json"), FileIO.fromPath(meta.toPath)) :: FilePart("file", s"Invoice ${invoiceNumber}.pdf", Option("application/pdf"), FileIO.fromPath(file.toPath)) :: List()))
  .map(res => {
    logger.debug("Status: "   res.status)
    logger.debug("JSON: "   res.json)

    Right(invoiceNumber)
  })