(Java) App Engine 中的静态文件不可访问

2022-09-04 21:49:40

示例文档说,您只需要将文件放在war/(或子目录)中,并且它们应该可以从主机访问(只要它们不是JSP或WEB-INF)。例如,如果您将foo.css置于战争/中,那么您应该能够在 http://localhost:8080/foo.css 访问它。但是,这对我根本不起作用。我的静态文件都不可访问。

appengine-web上的文档.xml说你也可以专门将某些类型表示为静态。我也尝试过这个,它没有区别。

我是否错过了一些明显的东西?

更新:事实证明,我网络上的一个映射.xml有点太激进了。罪魁祸首如下:

<servlet>
    <servlet-name>Main</servlet-name>
    <servlet-class>MainServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>Main</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

它似乎抓住了所有没有被抓住的东西,这是其他规则之一,我不明白,因为在url模式的末尾没有*。它似乎也与文档直接矛盾,该文档说:

注意:静态文件(逐字提供给用户的文件,如图像、CSS 或 JavaScript)与部署描述符中提到的路径分开处理。对 URL 路径的请求与 WAR 中被视为静态文件的文件的路径匹配,则无论部署描述符中的 servlet 和筛选器映射如何,都将为该文件提供服务。您可以使用 appengine-web.xml文件从被视为静态文件的文件中排除文件。

那么,我怎么能有一个与我的域的基础相匹配的规则(例如。http://www.example.com/)并且仍然允许静态文件过滤?


答案 1

尝试在 appengine-web 中手动定义静态文件.xml例如

<static-files>
  <include path="/favicon.ico" expiration="1d" />
  <include path="/static/**" />
  <include path="/**.css" />      
</static-files>

即使使用像这样的servlet,这也适用于我

<servlet-mapping>
 <servlet-name>testServlet</servlet-name>
 <url-pattern>/</url-pattern>
</servlet-mapping>

<servlet-mapping>
 <servlet-name>testServlet</servlet-name>
 <url-pattern>/*</url-pattern>
</servlet-mapping>

请参阅静态文件和资源文件


答案 2

...它似乎抓住了所有没有被抓住的东西,这是其他规则之一,我不明白,因为在url模式的末尾没有*。...

[[不幸的是,术语“默认 servlet”被重载为表示不同的东西 - 导致混淆。我会尽量说清楚。

url-pattern “/” 是特殊的(Rogue Wave 称之为“默认映射”)。这定义了应用程序的“默认 servlet”,当 URL 请求与其他模式(SRV.11.2 项目符号 3 和 SRV 11.1 项 #4)不匹配时,将使用该服务。显然,“/”的处理方式就像您指定了“/*”一样。

...它似乎也与文档直接矛盾...

同意,我认为应用程序引擎有一个错误,所以它没有遵循你引用的文档。这是我关于正在发生的事情的理论。由于您的应用程序有一个默认的 servlet(由为 url 模式“/”定义 servlet 而产生),因此应用程序停止使用容器为未定义自己的“默认 servlet”的应用程序提供的“默认”“默认 servlet”。容器的“默认”“默认 servlet”是为提供静态文件提供的默认行为。我认为这与某些容器的行为方式一致。

我想知道如果您尝试为与静态文件匹配的URL模式指定servlet会发生什么。它是为文件提供服务(如文档所示)还是调用 servlet(如本理论所示)。

...那么,我怎么能有一个与我的域的基础相匹配的规则(例如。http://www.example.com/)并且仍然允许静态文件过滤?...

如果理论是正确的,jacob(适用于google应用程序引擎)和zockman提供的解决方案似乎可以工作 - 他们将静态文件映射到容器的“默认”“默认servlet”。

我唯一的另一个想法是编写应用程序的“默认servlet”来检查请求,以查看请求是否为“/”。如果是这样,请处理它。如果没有,那么(以某种方式)调用容器的“默认”“默认servlet”来处理请求(希望这将缓存文件)。希望一旦静态文件被提供一次,缓存将来会绕过 servlet。

抱歉,我不能更具体或提供代码 - 我还没有使用Google应用程序引擎(尚未!


裁判:


推荐