Play 2.0 How to Post MultipartFormData using WS.url or WS.WSRequest

后端 未结 6 1314
小蘑菇
小蘑菇 2021-02-08 22:42

In Java Http request, we can do this to make multipart HTTP POST.

HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost(url);

FileBo         


        
6条回答
  •  星月不相逢
    2021-02-08 23:28

    As Romain Sertelon suggested, you can write a Writeable to handle this case. Here's one I wrote:

    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)
        }
    
    }
    

    Here's how to use it:

    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)
    

提交回复
热议问题