(Java)App Engine中的静态文件无法访问

时间:2009-06-22 11:06:53

标签: java google-app-engine web.xml

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

appengine-web.xml上的文档说明您也可以将某些类型明确表示为静态类型。我也试过这个,但没有区别。

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

更新 原来我的web.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-pattern的末尾没有*。它似乎与the documentation直接相矛盾:

  

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

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

4 个答案:

答案 0 :(得分:11)

尝试在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>

请参阅Static Files and Resource Files

答案 1 :(得分:2)

  

......似乎它抓住了所有未被抓住的其他规则之一,我不理解,因为url-pattern的末尾没有*。 ...

[[不幸的是,术语“默认servlet”被重载意味着不同的东西 - 导致混淆。我会尽力说清楚。]]

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

  

......它似乎与文件直接相矛盾......

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

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

  

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

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

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

抱歉,我无法更具体或提供代码 - 我还没有使用Google应用引擎(还有!)。


价:

答案 2 :(得分:1)

我意识到这是一个非常古老的问题,但我遇到了同样的问题。我已将css/*.cssjs/*.cssfavicon.ico放在/war/static/下,并使用public_root中的appengine-web.xml指令指向{{1} }}。这在我的本地开发服务器上运行良好,但在我上传应用程序时没有。摆脱/static并将一切都提升到一个水平对我有用。

使用Java SE 6的Mac OSX 10.6.8上的SDK v1.5.2(Java)(MacOS X默认)

答案 3 :(得分:-2)

当使用例如tomcat来提供静态文件时,必须指定如下模式:

<servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>*.css</url-pattern>
</servlet-mapping>
<servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>*.js</url-pattern>
</servlet-mapping>

也许你可以尝试做同样的事情?