【问题标题】:Static files in (Java) App Engine not accessible(Java) App Engine 中的静态文件无法访问
【发布时间】:2010-11-04 19:45:56
【问题描述】:

example documentation 表示您只需将文件放在 war/(或子目录)中,它们应该可以从主机访问(只要它们不是 JSP 或 WEB-INF)。例如,如果您将 foo.css 放在 war/ 中,那么您应该能够通过 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 模式的末尾没有 *。它似乎也与the documentation 直接矛盾,它说:

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

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

【问题讨论】:

  • SDK 附带的示例是否有效?如何启动应用程序。我猜你已经检查过文件真的在战争中/
  • 是的,留言簿应用程序让我可以很好地访问它的 CSS 文件。

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


【解决方案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>

Static Files and Resource Files

【讨论】:

    【解决方案2】:

    ... 似乎它正在抓取所有未抓取的内容,这是其他规则之一,我不明白,因为 url 模式的末尾没有 *。 ...

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

    url 模式“/”是特殊的(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(适用于谷歌应用引擎)和 zockman 提供的解决方案似乎可以工作 - 他们将静态文件映射到容器的“默认”“默认 servlet”。

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

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


    参考:

    【讨论】:

    • This Q&A 似乎已经为这个疯狂的问题找到了一个疯狂的答案。
    【解决方案3】:

    我意识到这是一个非常古老的问题,但我遇到了同样的问题。我将css/*.cssjs/*.cssfavicon.ico 放在/war/static/ 下,并在appengine-web.xml 中使用public_root 指令指向/static。这在我的本地开发服务器上运行良好,但在我上传应用程序时却没有。摆脱 /static 并将所有内容提升一个级别对我来说很有效。

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

    【讨论】:

      【解决方案4】:

      当使用例如 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>
      

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-03-02
        • 2013-10-01
        • 2021-05-14
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多