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

问题描述 投票:0回答:1

我们如何在客户端的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特征的自定义实现(重用99%的Multipart),因为Multipart.Formdata使用私有代码。

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

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

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

scala akka content-type akka-http
1个回答
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] )
}
© www.soinside.com 2019 - 2024. All rights reserved.