【问题标题】:Reading a file from within App Engine module从 App Engine 模块中读取文件
【发布时间】:2014-04-04 21:45:00
【问题描述】:

我正在尝试从位于 WEB-INF 目录中的 App Engine 模块中读取静态文件。

...
File file = new File("WEB-INF/somestaticfile.ext);
...

它在云环境中完美运行,但是在开发服务器中它以FileNotFoundException 结束。

我在 maven 的帮助下构建和运行应用程序,似乎还需要在项目的 EAR 层次结构中添加一个表示模块的目录,以便找到该文件。

...
File file = new File("modulename.war/WEB-INF/somestaticfile.ext);
...

这适用于本地开发服务器,但不适用于云环境。

我相信有一种方法可以在云和本地环境中读取文件。任何意见,将不胜感激。

【问题讨论】:

    标签: java google-app-engine maven


    【解决方案1】:

    我花了一些时间来解决这个问题,这里是我找到的解决方案。如果您将资源放在类路径中,则可以从云和本地开发服务器访问它们,如下所示。

    getClass().getClassLoader().getResource("resourceName");
    

    getClass().getClassLoader().getResourceAsStream("resourceName");
    

    但是,如果您的资源位于其他地方(例如 WEB-INF),我发现的唯一方法是通过 javax.servlet.ServletContext#getResource(String)javax.servlet.ServletContext#getResourceAsStream(String) 在这两种环境中都可以使用。如果您从应用程序的 Web 层访问资源,则此解决方案完全可以,但如果您需要从其他层(例如服务层)访问它们,则向该层引入对 Java Servlet API 的依赖关系可能不是一个好主意。

    由于我使用的是 Spring,我决定通过 org.springframework.core.io.ResourceLoader#getResource(String) 加载资源,它返回一个资源抽象,其具体实现取决于应用程序上下文类型和资源路径前缀。对于在 Web 容器中运行的应用程序,实际实现在后台使用 ServletContext 方法,但您不会受到它的影响。

    如果你不使用Spring,基于ServletContext实现自己的资源抽象应该没什么大不了的。

    如果有人可以提供其他解决方案,请随时提供。

    【讨论】:

      【解决方案2】:

      Google 开发者文档一如既往地是一个极好的资源:

      也就是说,为了将来帮助其他人,我将总结一些我认为通常与问题相关的相关点(因为我看不到您的特定环境正在发生什么)。

      App Engine 从独立于应用服务器的专用服务器和缓存中提供静态文件。应用程序代码可以使用文件系统访问的文件称为资源文件。这些文件与应用程序一起存储在应用程序服务器上。

      默认情况下,WAR中的所有文件都被视为静态文件和资源文件,除了JSP文件编译成servlet类并映射到URL路径,WEB-INF/目录下的文件从未用作静态文件,并且始终可用作应用程序的资源文件。您可以使用 appengine-web.xml 文件中的元素调整哪些文件被视为静态文件以及哪些文件被视为资源文件。该元素指定匹配文件路径的模式,以从静态文件列表中包含和排除,覆盖或修改默认行为。同样,该元素指定哪些文件被视为资源文件。

      您提到开发服务器和部署之间似乎存在脱节。在没有深入研究 Maven 的情况下,我的第一个想法是查看路径模式。正如他们在 Google Developers 文档中指出的那样,路径模式是使用零个或多个元素来指定的。在一个模式中,* 表示文件或目录名称中的零个或多个任意字符,** 表示路径中的零个或多个目录。将应用部署到 App Engine 时,不会上传匹配模式的文件和目录。但是,在本地开发服务器上运行时,您的应用程序仍然可以访问这些文件和目录。元素会覆盖包含所有文件的默认行为。一个元素在所有模式之后应用(如果没有提供显式,则应用默认值)。

      希望这有助于提供一个总体观点。如果您找到该问题的具体解决方案并可以在此处分享,请执行!

      【讨论】:

      • 我知道 App Engine 处理静态和资源文件的方式,正如您引用的文档,WEB-INF 目录中的文件始终可作为资源文件供应用使用。我需要的是一种在云和本地开发环境中访问此类文件的统一方式。您提到的路径模式仅适用于资源文件配置元素,而不是作为如何通过 Java API 指定文件路径的一种方式。
      • 完全有道理。将内容放在那里,以防其他人想要在开发人员页面之外快速找到它。也就是说,如果您确实找到了具体的解决方案,请分享,因为我很感兴趣!我正在努力构建一个 AppEngine 应用程序,并在本周末使用与你的特性相似的 Maven!
      猜你喜欢
      • 1970-01-01
      • 2013-01-26
      • 1970-01-01
      • 1970-01-01
      • 2018-07-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-02-07
      相关资源
      最近更新 更多