代码之家  ›  专栏  ›  技术社区  ›  Alex Fruzenshtein

Akka-HTTP:ByteString作为表单数据请求中的文件负载

  •  1
  • Alex Fruzenshtein  · 技术社区  · 6 年前

    在我的 previous questions ,我问如何使用Akka HTTP表示表单数据请求?根据答案,我创建了一个工作示例,但面临一个“可伸缩性”问题——当表单数据请求的数量很高时,我需要处理文件系统中的大量文件。

    我很好奇,能不能 ByteString 作为表单数据请求中的文件负载?

    case class FBSingleChunkUpload(accessToken: String, 
            sessionId: String,
            from: Long, 
            to: Long, 
            file: ByteString) //this property is received from S3 as array of bytes
    

    我创建了以下示例:

    def defaultEntity(content: String) =
      HttpEntity.Default(
        ContentTypes.`text/plain(UTF-8)`,
        content.length, Source(ByteString(content) :: Nil)
      )
    
    def chunkEntity(chunk: ByteString) =
      HttpEntity.Strict(
        ContentType(MediaTypes.`application/octet-stream`),
        chunk
      )
    
    val formData = Multipart.FormData(
      Source(
        Multipart.FormData.BodyPart("access_token", defaultEntity(upload.fbUploadSession.fbId.accessToken)) ::
        Multipart.FormData.BodyPart("upload_phase", defaultEntity("transfer")) ::
        Multipart.FormData.BodyPart("start_offset", defaultEntity(upload.fbUploadSession.from.toString)) ::
        Multipart.FormData.BodyPart("upload_session_id", defaultEntity(upload.fbUploadSession.uploadSessionId)) ::
        Multipart.FormData.BodyPart("video_file_chunk", chunkEntity(upload.chunk)) :: Nil
      )
    )
    val req = HttpRequest(
      HttpMethods.POST,
      s"/v2.3/${upload.fbUploadSession.fbId.pageId}/videos",
      Nil,
      formData.toEntity()
    )
    

    在这种情况下,Facebook会向我发回一条消息:

    您的视频上载在完成之前超时。这是 可能是因为网络连接速度慢或视频 您尝试上载的内容太大

    但如果我发同样的 ByteString公司 作为 File 它工作得很好。

    这可能是什么原因?我已经试过使用 MediaTypes.multipart/form-data 在里面 chunkEntity 但它的行为方式是一样的。

    1 回复  |  直到 6 年前
        1
  •  2
  •   Alex Fruzenshtein    6 年前

    为了发送 ByteString 作为表单数据文件,您需要使用以下 BodyPart :

    def fileEntity(chunk: ByteString) = Multipart.FormData.BodyPart.Strict("video_file_chunk",
        HttpEntity(ContentType(MediaTypes.`application/octet-stream`), chunk), Map("fileName" -> "video_chunk"))
    

    特别注意 Map("fileName" -> "video_chunk") 为了正确构造表单数据HTTP请求,此参数是必需的。

    因此 chunkEntity 根据问题,使用 fileEntity 从这个答案:)