正如 Romain Sertelon 建议的那样,您可以编写一个 Writeable 来处理这种情况。这是我写的一个:
package utilities
import java.io.{ByteArrayOutputStream, File}
import com.ning.http.client.FluentCaseInsensitiveStringsMap
import com.ning.http.multipart.{MultipartRequestEntity, FilePart, StringPart}
import play.api.http.HeaderNames._
import play.api.http.{ContentTypeOf, Writeable}
import play.api.mvc.{Codec, MultipartFormData}
object MultipartFormDataWriteable {
implicit def contentTypeOf_MultipartFormData[A](implicit codec: Codec): ContentTypeOf[MultipartFormData[A]] = {
ContentTypeOf[MultipartFormData[A]](Some("multipart/form-data; boundary=__X_PROCESS_STREET_BOUNDARY__"))
}
implicit def writeableOf_MultipartFormData(implicit contentType: ContentTypeOf[MultipartFormData[File]]): Writeable[MultipartFormData[File]] = {
Writeable[MultipartFormData[File]]((formData: MultipartFormData[File]) => {
val stringParts = formData.dataParts flatMap {
case (key, values) => values map (new StringPart(key, _))
}
val fileParts = formData.files map { filePart =>
new FilePart(filePart.key, filePart.ref, filePart.contentType getOrElse "application/octet-stream", null)
}
val parts = stringParts ++ fileParts
val headers = new FluentCaseInsensitiveStringsMap().add(CONTENT_TYPE, contentType.mimeType.get)
val entity = new MultipartRequestEntity(parts.toArray, headers)
val outputStream = new ByteArrayOutputStream
entity.writeRequest(outputStream)
outputStream.toByteArray
})(contentType)
}
}
以下是如何使用它:
import utilities.MultipartFormDataWriteable._
...
val url = "https://example.com"
val dataParts = Map(
"foo" -> Seq("bar"),
"alice" -> Seq("bob")
)
val file = new jave.io.File(... path to a jpg ...)
val fileParts = Seq(new FilePart("attachment", "foo.jpg", Some("image/jpeg"), file)
val multipartFormData = MultipartFormData(dataParts, fileParts, Seq(), Seq())
WS.url(url).post(multipartFormData)