我正在编写一个应用程序,通过我使用Akka HTTP的RESTful服务向客户端提供文件。
来自客户端的请求可能是一个POST请求,正文包含我需要提供的文件的名称。
{filename: abc.zip}
我的文件存储在我的服务器上。我如何提供文件以及适当的响应类型?该文件可以是任何格式。在java中,我们将其指定为MediaType.APPLICATION_OCTET_STREAM。
答案 0 :(得分:1)
用于二进制文件下载的裸机HTTP服务器(目标文件位于src/main/resources/
)可能如下所示:
import akka.actor.ActorSystem
import akka.stream.ActorMaterializer
import akka.stream.scaladsl._
import akka.http.scaladsl.Http
import akka.http.scaladsl.model.{HttpEntity, ContentTypes}
import akka.http.scaladsl.server.Directives._
import java.nio.file.Paths
import scala.io.StdIn
object DownloadServer {
def main(args: Array[String]) {
implicit val system = ActorSystem("my-system")
implicit val materializer = ActorMaterializer()
implicit val ec = system.dispatcher
val route =
path("hello") {
get {
complete( HttpEntity( ContentTypes.`text/html(UTF-8)`,
"Hello from Akka-HTTP!"
) )
}
} ~
path("download") {
post {
formField('filename) { filename: String =>
complete( HttpEntity( ContentTypes.`application/octet-stream`,
FileIO.fromPath(Paths.get(s"src/main/resources/$filename"), 100000)
) )
}
}
}
val bindingFuture = Http().bindAndHandle(route, "localhost", 8080)
println(s"Server online at http://localhost:8080/\nPress RETURN to stop...")
StdIn.readLine()
bindingFuture
.flatMap(_.unbind())
.onComplete(_ => system.terminate())
}
}
要测试它,只需运行服务器并在命令提示符下使用cURL
,如下所示:
curl -X GET http://localhost:8080/hello
// Hello from Akka-HTTP!
curl -d "filename=abc.zip" -X POST http://localhost:8080/download > abc1.zip
// % Total % Received % Xferd Average Speed Time Time Time Current
// Dload Upload Total Spent Left Speed
// 100 131k 0 131k 100 16 6914k 839 --:--:-- --:--:-- --:--:-- 6937k
[UPDATE]
评论部分中的每个问题,formField()用于提取请求中的单个表单字段。您也可以使用entity(as[someType])
替换行formField('filename) ... =>
替换为以下内容:
entity(as[String]) { entity =>
val filename = entity.split("=").last
FileIO.fromPath(nioFilePath, chunkSize)允许您提供缓冲区大小,示例代码中为100,000。您还可以使用Framing.delimiter()
创建自定义Akka Flow以满足更复杂的要求。有关详情,请参阅相关的Akka doc。