如何在Scala中创建多部分/混合HTTPRequest(JSON +文件)

时间:2017-09-06 14:45:09

标签: scala akka content-type akka-http

我们如何在客户端的akka​​中创建multipart/mixed个请求?

multipart/form-datamultipart/mixed有99%的相似之处,但是akka-http只为前者提供了方便的方法而不是后者,尽管它们有相似之处。

val jsonPayload = DataSourceSingleUploadRequest(
  "datasource-name",
  "datasource-username",
  "datasource-password",
)

import io.circe.generic.auto._, io.circe.syntax._

def createEntity: RequestEntity = {
  val fileFormPart = Multipart.FormData.BodyPart.fromPath("datasource", ContentTypes.`application/octet-stream`, Paths.get(extractFilePath))
  val jsonRequestFormPart = Multipart.FormData.BodyPart("request_payload", HttpEntity(ContentTypes.`application/json`, jsonPayload.asJson.noSpaces))

  Multipart.FormData(
    fileFormPart,
    jsonRequestFormPart
  ).toEntity()
}

理想的方法是拥有Multipart.MixedData。我已经尝试了几种解决方案来替换mediaType,但没有一种成功:

  • 类和特征是密封的,因此我无法覆盖
  • 无法创建Multipart-Formdata特征的自定义实施(重用Multipart的99%),因为Multipart.Formdata使用私有代码。

我很简单,我想帮助创建与multipart/mixed 99%相似的multipart/form-data次请求。

PS:服务器并不真正接受multipart/form-data:/

编辑:为了完整性,DataSourceSingleUploadRequest是一个案例类,我正在使用circe

1 个答案:

答案 0 :(得分:0)

您使用的是哪个版本的akka​​-http?

10.1.0-RC1上,我可以看到Multipart.General.Strict(它也可能出现在早期版本中)。

免责声明:以下代码编译,但我尚未对其进行测试。

/*
* Create a Multipart/mixed message body
*/
private
def genMultipart( set: Set[MyEntry] ): Multipart.General.Strict = {
  import scala.collection.immutable.{Seq => ImmutableSeq}

  val parts: Set[Multipart.General.BodyPart.Strict] = set.map {
    case MyEntry(keys, ct, value) =>

      val headers: ImmutableSeq[HttpHeader] = ImmutableSeq(
        RawHeader("X-AC-key1", keys._1),
        RawHeader("X-AC-key2", keys._2)
      )
      Multipart.General.BodyPart.Strict(
        HttpEntity.Strict(ContentTypes.`text/plain(UTF-8)`, ByteString("1,2,3")),   // some random values
        headers
      )
  }

  Multipart.General.Strict( MediaTypes.`multipart/mixed`, parts.to[ImmutableSeq] )
}