播放WS-从Scala发布multipart / form-data-错误的请求

问题描述

我正在尝试通过multipart / form-data请求将pdf文件发布到外部服务。我已经通过示例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 "[email protected];type=application/pdf"

我是否错过了post(...)中的一些重要参数?与该CURL请求相对应的ScalaWS中适当的发布参数是什么?

解决方法

使用multipart / form-data时,需要边界参数。 Content-Type标头将如下所示:

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

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

,

我遇到了同样的问题,添加了在mycase中解决的Content-Length标头。向WSRequest添加了以下标题,

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

这里的fileToUpload是您要上传的java.io.File对象。