服务器接收包含文件和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,如何将其转换为服务器。路由?
答案 0 :(得分:0)
我认为您在那里有两个独立的问题:
例如,如果您的要求是这样的:
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对象。
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