我正在尝试从位于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);
...
这适用于本地开发服务器,但不适用于云环境。
我相信如何读取可在云和本地环境中工作的文件。任何意见,将不胜感激。
答案 0 :(得分:2)
我花了一些时间来弄明白,这里是我找到的解决方案。如果您将资源放在类路径上,那么您可以从云和本地开发服务器中按如下方式访问它们。
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
实现你自己的资源抽象应该不是什么大事。
如果有人可以提供其他解决方案,请随时这样做。
答案 1 :(得分:1)
一如既往,优秀的资源是Google开发人员文档:
那就是说,为了将来帮助别人,我将总结一些我认为通常与问题相关的相关观点(因为我看不到你的具体环境发生了什么)。
App Engine提供来自与应用程序服务器分开的专用服务器和缓存的静态文件。应用程序代码使用文件系统可访问的文件称为资源文件。这些文件与应用程序一起存储在应用程序服务器上。
默认情况下,WAR中的所有文件都被视为静态文件和资源文件,JSP文件(编译为servlet类并映射到URL路径)和WEB-INF /目录中的文件除外,它们是从未作为静态文件提供,并始终作为资源文件提供给应用程序。您可以使用appengine-web.xml文件中的元素调整哪些文件被视为静态文件以及哪些文件被视为资源文件。该元素指定匹配文件路径的模式,以包含和排除静态文件列表,覆盖或修改默认行为。同样,该元素指定哪些文件被视为资源文件。
您提到开发服务器和部署之间似乎存在脱节。没有潜入Maven,我的第一个想法是看路径模式。正如他们在Google Developers文档中所述,使用零个或多个元素指定路径模式。在模式中,*表示文件或目录名中任何字符的零个或多个,**表示路径中的零个或多个目录。将应用程序部署到App Engine时,将不会上载与模式匹配的文件和目录。但是,在本地Development Server上运行时,应用程序仍可访问这些文件和目录。元素将覆盖包含所有文件的默认行为。在所有模式之后应用元素(如果未提供显式,则应用默认值)。
希望有助于提供一般观点。如果您找到问题的具体解决方案并可以在此处分享,请执行!