【问题标题】:Reading Files from public folder in play framework in production从生产中播放框架中的公共文件夹中读取文件
【发布时间】:2016-08-22 17:05:48
【问题描述】:

我的 Play 应用程序是 2.4.2。 在开发人员模式下,我曾经使用 Source.fromFile("./public/files/abc.json") 从后端控制器的公共文件夹中读取文件

当我将应用程序转换为生产模式时,我收到了 File Not Found Exceptions。我发现公用文件夹在生产模式下打包在资产 jar 中。我该怎么做才能使其在开发和生产模式下都工作??

【问题讨论】:

  • 您可以尝试从类路径中读取它:stackoverflow.com/a/1464366/1080523
  • @user1869107 " 在生产模式下,Play 的类加载器只能从 conf 文件夹中读取文件" -> 这是不正确的。实际上,您可以在分发时将其他资源目录添加到 Play 框架中。我将编辑我的答案并添加方法。

标签: playframework playframework-2.4


【解决方案1】:

如果您使用的是 scala 2.12,请使用 Source.fromResource 而不是 Source.fromFile。

例子:

如果您将文件放在公用文件夹中,请不要使用前导斜杠。

Source.fromResource(“public/files/abc.txt”)

如果将文件放在 conf 文件夹中,请不要在路径中包含 conf。

Source.fromResource(“files/abc.txt”)  // conf/files/abc.txt

如果您使用的是

相对路径(没有前导斜杠)

scala.io.Source.fromInputStream(getClass.getClassLoader.getResourceAsStream(“public/test.txt”))

绝对路径(需要前导斜杠)

scala.io.Source.fromInputStream(getClass.getResourceAsStream(“/public/test.txt”))

如果您将文件放在 conf 文件夹中,我猜您还必须在路径中排除“conf”。

最后,您可以在blog 中了解 Java 的资源加载是如何工作的。

【讨论】:

    【解决方案2】:

    你试过这个播放文档https://www.playframework.com/documentation/2.5.x/AssetsOverview 吗? Play 2.4 没问题,即使是 2.3,我也试过了。

    在那里你可以找到这个,你可以在你的 conf/routes 文件中简单地做到这一点。

    GET  /assets/*file        controllers.Assets.at(path="/public", file)
    

    file -> 指的是文件名。 例如:myFile.json

    要使这项工作在生产模式下工作,您还需要做一些额外的工作。如this 回答中所述,将这些行添加到您的 /build.sbt 文件中。

    import com.typesafe.sbt.packager.MappingsHelper._
        mappings in Universal ++= directory(baseDirectory.value / "public")
    

    这将在 dist 文件中包含您的“公共”目录(您可以像这样包含任何目录)。然后您的应用程序将在生产环境中运行。

    【讨论】:

    • 这里给出的 sbt 指令也适用于 Play 2.3!
    【解决方案3】:

    有两种方法可以解决这个问题:- 1)直接使用Supun Wijerathne在上面的评论中建议的内容。 2)第二种是使用以下方法,如果不想在应用程序的分发版本中添加额外的公用文件夹:- a) 从 conf 文件夹中的 public 文件夹中复制所有文件。 b) 使用 Play 的类加载器将资源作为流获取。 c) 使用 Source.fromInputStream 方法将此输入流转换为缓冲源。现在,这个文件可以被控制器用来处理了。

    【讨论】:

      【解决方案4】:

      Play 带有一个内置控制器来服务公共资产。

      控制器在默认的 Play JAR 中作为 controllers.Assets 可用,并定义了一个带有两个参数的 at 动作:

      Assets.at(路径:字符串,文件:字符串) path 参数必须是固定的,并且定义了操作管理的目录。文件参数通常是从请求路径中动态提取出来的。

      下面是 conf/routes 文件中 Assets 控制器的典型映射:

      GET  /assets/*file        controllers.Assets.at(path="/public", file)
      

      Refer here for more.

      【讨论】:

        【解决方案5】:

        你可以使用这个方法:

        Play.application().getFile("/public/foobar.baz");
        

        Method Doc

        获取相对于应用程序根路径的文件。

        【讨论】:

        • 这很有帮助,因为它为我指出了 resourceAsStream 方法
        猜你喜欢
        • 2021-07-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多