scala - Akka-HTTP : File Upload

标签 scala upload akka akka-stream

我正在尝试使用akka http实现简单的文件上传。
我的尝试如下所示:

    import akka.actor.ActorSystem
    import akka.event.{LoggingAdapter, Logging}
    import akka.http.scaladsl.Http
    import akka.http.scaladsl.model.{HttpResponse, HttpRequest}
    import akka.http.scaladsl.model.StatusCodes._
    import akka.http.scaladsl.server.Directives._
    import akka.stream.{ActorMaterializer, Materializer}
    import com.typesafe.config.Config
    import com.typesafe.config.ConfigFactory
    import scala.concurrent.{ExecutionContextExecutor, Future}
    import akka.http.scaladsl.model.StatusCodes
    import akka.http.scaladsl.model.HttpEntity
    import java.io._
    import akka.stream.io._

    object UploadTest extends App {
      implicit val system = ActorSystem()
      implicit val executor = system.dispatcher
      implicit val materializer = ActorMaterializer()

      val config = ConfigFactory.load()
      val logger = Logging(system, getClass)

      val routes = {
        pathSingleSlash {
          (post & extractRequest) { 
            request => {
              val source = request.entity.dataBytes
              val outFile = new File("/tmp/outfile.dat")
              val sink = SynchronousFileSink.create(outFile)
              source.to(sink).run()
              complete(HttpResponse(status = StatusCodes.OK))
            }
          }
        }
      }

      Http().bindAndHandle(routes, config.getString("http.interface"), config.getInt("http.port"))

    }

此代码存在多个问题:
  • 无法上传大于配置的实体大小的文件:Request Content-Length 24090745 exceeds the configured limit of 8388608
  • 连续执行两次上传会导致dead letters encountered.异常。

  • 克服大小限制的最佳方法是什么?如何正确关闭文件,以便后续的上载会覆盖现有文件(暂时忽略并发上载)?

    最佳答案

    对于第2点,我认为source.to(sink).run()可异步执行该操作。它实现了Future。因此,您的HTTP请求可能会在文件写入完成之前返回,因此,如果在第一个请求返回后立即在客户端开始第二次上载,则第一个请求可能尚未完成对文件的写入。

    您可以使用onCompleteonSuccess指令仅在将来完成时完成http请求:

    http://doc.akka.io/docs/akka-stream-and-http-experimental/1.0-M2/scala/http/directives/alphabetically.html

    http://doc.akka.io/docs/akka-stream-and-http-experimental/1.0/scala/http/routing-dsl/directives/future-directives/onSuccess.html

    编辑:

    对于内容长度问题,您可以做的一件事就是增加application.conf中该属性的大小。默认值为:

    akka.server.parsing.max-content-length = 8m
    

    参见http://doc.akka.io/docs/akka-stream-and-http-experimental/1.0/java/http/configuration.html

    关于scala - Akka-HTTP : File Upload,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32924813/

    相关文章:

    php - Dreamhost 上的 uploadify/php 导致大型 http 上传失败

    java - Akka Actors unstashAll() 与 Java 中的谓词

    java - 在类型安全配置中访问完全解析的配置

    javascript - jQuery AJAX 文件上传 PHP

    scala - 在 Slick 3.0 中,有一种方法可以在不使用特定 JDBC 驱动程序的情况下声明表

    jquery - HTML5 拖放文件上传,页面上有多个目标放置区域

    scala - 如何在play框架中使用akka、scala、websockets实现 'Private Chat'模块?

    scala - 检查Scala/Akka Actor 是否已终止

    scala - SBT 使用哪个版本的 Java?

    scala - #::方法是什么