【问题标题】:How to represent a form-data request using Akka HTTP?如何使用 Akka HTTP 表示表单数据请求?
【发布时间】:2018-04-26 15:00:19
【问题描述】:

我想使用 Akka HTTP 向Facebook API 创建一个表单数据 http 请求。在 curl 中,请求示例如下所示:

curl \
 -X POST \
 "https://graph-video.facebook.com/v2.3/1533641336884006/videos"  \
 -F "access_token=XXXXXXX" \
 -F "upload_phase=transfer" \
 -F "start_offset=0" \
 -F "upload_session_id=1564747013773438" \
 -F "video_file_chunk=@chunk1.mp4"

所以我为请求有效负载表示创建了以下模型:

case class FBSingleChunkUpload(accessToken: String, 
    sessionId: String,
    from: Long, 
    to: Long, 
    file: File) //file is always ~1Mb

那我就用:

Http().cachedHostConnectionPoolHttps[String]("graph-video.facebook.com")

但我不知道如何将FBSingleChunkUpload 转换为正确的HttpRequest :(

您能否给我一个提示,如何使用 Akka HTTP 表示这种类型的请求?

【问题讨论】:

    标签: scala akka akka-http


    【解决方案1】:

    有一个 FormData Entity 类型

     val fBSingleChunkUpload = ???
     HttpRequest(method = HttpMethods.POST,
                  entity = FormData(("accessToken", fBSingleChunkUpload.accessToken), ...).toEntity)
    

    此外,您可以检查该文件是否适用于Multipart.FormData

     val fileFormPart = Multipart.FormData
        .BodyPart("name", HttpEntity(MediaTypes.`application/octet-stream`, file.length(), FileIO.fromPath(file.toPath)))
    
      val otherPart = Multipart.FormData.BodyPart.Strict("accessToken", "the token")
    
      val entity =
        Multipart.FormData(otherPart, fileFormPart).toEntity
    

    【讨论】:

    • 关于文本字段很清楚。文件字段呢?
    • 我更新了示例,请检查是否可以为您找到解决方案:)
    【解决方案2】:

    在 curl 中,-F 选项规定使用“multipart/form-data”内容类型的 POST。要在 Akka HTTP 中创建这样的请求,请使用 Multipart.FormData(下面的 defaultEntity 是从 Akka HTTP 的 MultipartSpec 借用的):

    val chunkUpload = FBSingleChunkUpload(...)
    
    def defaultEntity(content: String) =
      HttpEntity.Default(ContentTypes.`text/plain(UTF-8)`, content.length, Source(ByteString(content) :: Nil))
    
    val streamed = Multipart.FormData(Source(
      Multipart.FormData.BodyPart("access_token", defaultEntity(chunkUpload.accessToken)) ::
      Multipart.FormData.BodyPart("upload_phase", defaultEntity("transfer")) ::
      Multipart.FormData.BodyPart("start_offset", defaultEntity(chunkUpload.from.toString)) ::
      Multipart.FormData.BodyPart("upload_session_id", defaultEntity(chunkUpload.sessionId)) ::
      Multipart.FormData.BodyPart.fromFile(
        "video_file_chunk", ContentType.Binary(MediaTypes.`video/mp4`), chunkUpload.file
      ) :: Nil))
    
    val request =
      HttpRequest(method = HttpMethods.POST, uri = /** your URI */, entity = streamed.toEntity)
    

    【讨论】:

    • 您是否建议将File 更改为Array[Byte]?在我将请求发送到 Facebook 之前的前一个阶段,我阅读了一个 InputStream 并创建了一个 File。但我很好奇创建相同类型的HttpRequest 但使用Array[Byte] 而不是File 是否更好/更容易?谢谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-29
    相关资源
    最近更新 更多