从 scala 播放 WS - post multipart/form-data - 错误请求

Play WS - post multipart/form-data from scala - Bad Request

我正尝试通过 multipart/form-data 请求将 pdf 文件 post 发送到外部服务。我已经使用示例 Java 脚本客户端完成了此操作,因此外部服务可以正常工作。 Hovewer 在 Scala 中我得到了以下代码: Bad request:

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(...) 中的一些重要参数? ScalaWS 中对应于此 CURL 请求的适当 post 参数是什么?

当使用multipart/form-data时,需要一个边界参数。 Content-Type header 看起来像这样:

Content-Type: multipart/form-data; boundary=nZaYg9TFHoDaLWhs8w

您使用 addHttpHeaders 设置了 Content-Type header,但是由于它缺少边界参数,所以它不起作用。 解决方案是不要手动设置 header,实际上您永远不需要设置 header。 Play-WS 将根据您传递给 post 方法的 object 类型添加适当的 Content-Type header。当您传递 Source[Part[Source[ByteString, Any]]] 时,它将设置 multipart/form-data Content-Type 并添加适当的边界参数。

我遇到了同样的问题,添加 Content-Length header 在我的案例中解决了。向 WSRequest 添加了如下 header,

wsRequest.setHeader("Content-Length", String.valueOf(fileToUpload.length()));

此处 fileToUpload 是您尝试上传的 java.io.File object。