AKKA Http多部分表单提取数据和文件

时间:2018-09-03 21:30:51

标签: scala multipartform-data akka-http

服务器接收包含文件和JSON对象的多部分表单。从请求中提取文件以及元数据和其他JSON对象的最佳方法是谁? 现在我有以下代码:

    pathPrefix(""){
  post {
    extractRequestContext {
      requestCtx => {
        implicit val materializer = requestCtx.materializer
        implicit val executionContext = requestCtx.executionContext
        fileUpload("file") {
          case (metadata, byteSource) => {
                  byteSource.runWith(FileIO.toPath(Paths.get(metadata.fileName))).onComplete {
                    case Success(posts) =>  {
                      formFields('campaign){
                        campaign => {
                          println(campaign)
                          complete(ApiResponse("OK"))
                        }
                    }}}
                      complete(ApiResponse("OK"))
                  }
              }
            }
          }
        }
      }

问题在于AKKA在完全读取请求之前发送了响应。而且我不确定如何从此处完成路线:

byteSource.runWith(FileIO.toPath(Paths.get(metadata.fileName))) ...

此表达式产生IOResult,如何将其转换为服务器。路由?

1 个答案:

答案 0 :(得分:0)

我认为您在那里有两个独立的问题:

如何提取JSON和文件?

例如,如果您的要求是这样的:

curl -X POST "http://localhost/" -H "accept: application/json" -H "Content-Type: multipart/form-data" -F "metadata={ "key": "value" }" -F "attachment=image.png;type=image/png"

您在metadata字段中定义了JSON。这就是你的做法

import akka.http.scaladsl.server.Directives._
path("") {
  post {
    extractRequestContext { ctx =>
      implicit val materializer = ctx.materializer
      formField('metadata) { metadata =>
        fileUpload("attachment") {
          case (fileInfo, byteSource) =>
            ...
        }
      }
    }
  }
}

您的JSON对象被提取为字符串,您可以序列化回JSON对象。

使用IOResult完成路线

Scala的onComplete实际上是问题所在,因为它返回了一个单位。

您可以这样做:

fileUpload("attachment") {
  case (metadata, byteSource) =>
    onComplete(byteSource.runWith(FileIO.toPath(Paths.get(metadata.fileName)))) {
      case Success(value) => complete("OK")
      case Failure(exception) => complete("NOT OK")
    }
}

此onComplete来自软件包akka.http.scaladsl.server.Directives