使用 akka-http 重新加载静态资源

Static resource reload with akka-http

简而言之:是否可以使用 akka-http 重新加载静态资源?

再多一点:

我想要的是在开发过程中热交换我的静态资源。 例如,我有 index.htmlapplication.js,我对其进行了更改,我想在刷新浏览器后查看更改,而无需重新启动服务器。做这样的事情的最佳做法是什么?

我知道 Play! 允许这样做,但不想仅仅因为这个原因就将我的项目基于 Play!

两个选项:

  1. 最简单:在本地 运行 时使用 getFromDirectory 指令,并将其指向您想要 'hotload' 的文件所在的路径,它直接从文件系统为它们提供服务, 所以每次更改文件并通过 Akka HTTP 加载它都会是最新版本。
  2. getFromResourceDirectory从class路径加载文件,资源是可用的,因为每次构建时SBT都会将它们复制到target下的class目录中(copyResources).您可以使用 unmanagedClasspath 配置 sbt,使其在 class 路径中包含静态资源目录。如果你想在 运行 package 时将资源打包到工件中,但是这将需要更多的 sbt-trixery(如果你只是将 src/resources 放在 unmanagedClasspath 中,它将取决于class如果使用复制的或修改的路径排序。

下面的代码尝试在目录“staticContentDir”中找到文件。如果找到该文件,则将其发送回客户端。如果未找到,它会尝试从类路径中的目录“site”中获取文件。 用户 url 是:http://server:port/site/path/to/file.ext

/site/ 来自 "staticPath"

  val staticContentDir = calculateStaticPath()
  val staticPath = "site"
  val routes = pathPrefix(staticPath) {
    entity(as[HttpRequest]) { requestData =>
      val fullPath = requestData.uri.path
      encodeResponse {
        if (Files.exists(staticContentDir.resolve(fullPath.toString().replaceFirst(s"/$staticPath/", "")))) {
          getFromBrowseableDirectory(staticContentDir.toString)
        } else {
          getFromResourceDirectory("site")
        }
      }
    }
  }

希望清楚。

我无法通过添加到 unmanagedClasspath 来让它工作,所以我改为使用 getFromDirectory。如果 getFromResourceDirectory 像这样失败,您可以使用 getFromDirectory 作为备用。

val route =
  pathSingleSlash {
    getFromResource("static/index.html") ~
    getFromFile("../website/static/index.html")
  } ~
  getFromResourceDirectory("static") ~
  getFromDirectory("../website/static")

首先它尝试在静态资源目录中查找文件,如果失败,则检查 ../website/static 是否有该文件。