0

我正在实现一个外部 API,我需要发送一个与 JSON 元部件捆绑在一起的文件附件。

服务器不接受以下代码,因为 Play 硬编码DataPartto的内容类型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)
  })

API 端点的示例 curl(我已经测试和验证)命令是:

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使用不同的内容类型或使用不同的部分来更好地控制我发送的内容?

4

1 回答 1

0

我找到了解决问题的方法:

首先我创建一个临时文件来保存元数据

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)
  })
于 2019-03-28T12:41:45.823 回答