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

时间:2022-11-10 23:15:23

The example documentation says that you simply need to place your files in war/ (or a subdirectory) and they should be accessible from the host (as long as they aren't JSPs or in WEB-INF). For example, if you place foo.css in war/ then you should be able to access it at http://localhost:8080/foo.css. However, this isn't working for me at all. NONE of my static files are accessible.

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

The docs on appengine-web.xml say that you can also specifically denote certain types as static. I've tried this as well and it makes no difference.

appengine-web.xml上的文档说你也可以特定地将某些类型表示为静态。我也试过这个并没有什么区别。

Am I missing something obvious?

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

UPDATE: Turns out one of the mappings in my web.xml was a little too aggressive. The following was the culprit:

更新:原来我的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>

It seems that it was grabbing everything that wasn't grabbed be one of the other rules, which I don't understand because there was no * on the end of the url-pattern. It also seems to be directly contradictory to the documentation that says:

它似乎抓住了所有未被抓住的其他规则之一,我不明白,因为url-pattern的末尾没有*。它似乎与文档直接相矛盾:

Note: Static files, files that are served verbatim to users such as images, CSS or JavaScript, are handled separately from paths mentioned in the deployment descriptor. A request for a URL path that matches a path to a file in the WAR that's considered a static file will serve the file, regardless of servlet and filter mappings in the deployment descriptor. You can exclude files from those treated as static files using the appengine-web.xml file.

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

So, how can I have a rule that matches the base of my domain (eg. http://www.example.com/) and still allows the static files to filter through?

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

4 个解决方案

#1


Try manually defining the static files in appengine-web.xml like

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

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

This works for me even with servlets like

即使像servlet这样,这对我也有用

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

and

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

See Static Files and Resource Files

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

#2


... It seems that it was grabbing everything that wasn't grabbed be one of the other rules, which I don't understand because there was no * on the end of the url-pattern. ...

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

[[Unfortunately, the term "default servlet" is overloaded to mean differnt things - leading to confusion. I'll try to be clear.]]

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

The url-pattern "/" is special (Rogue Wave calls this the "default mapping"). This defines the application's "default servlet", which is used when the URL request does not match other patterns (SRV.11.2 bullet 3 and SRV 11.1 item #4). Apparently, "/" is handled as if you specified "/*".

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

... It also seems to be directly contradictory to the documentation ...

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

Agreed, I think app engine has a bug so its not following the documentation you cited. Here's my theory of what is going on. Since there is a default servlet for your app (resulting from defining a servlet for url pattern "/"), the app stops using "default" "default servlet" provided by the container for apps that don't define their own "default servlet". The container's "default" "default servlet" is what provides the default behavior for serving up static files. I think this is consistent with how some containers behave.

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

I wonder what would happen if you tried specifying a servlet for a URL pattern that matches a static file. Would it serve the file (as indicated by the docs) or invoke the servlet (as indicated by this theory).

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

... So, how can I have a rule that matches the base of my domain (eg. http://www.example.com/) and still allows the static files to filter through? ...

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

If the theory is right, the solutions provided by jacob (adapted for google app engine) and zockman seem like they'd work - they map the static files to the container's "default" "default servlet".

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

The only other idea I have is to write your app's "default servlet" to examine the request to see if the request is for "/" or not. If so, handle it. If not, then (somehow) invoke the container's "default" "default servlet" to process the request (which will hopefully cache the file). Hopefully, once the static file has been served once, caching will bypass the servlet(s) in the future.

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

Sorry, I can't be more specific or provide code - I haven't work with Google app engine (yet!).

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


Ref:

#3


I realize that this is an really old question but I just ran into the same problem. I had put my css/*.css, js/*.css, and favicon.ico under /war/static/ and used the public_root directive in my appengine-web.xml to point to /static. This worked fine on my local dev server but did not when I uploaded the app. Getting rid of /static and moving everything up a level worked for me.

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

SDK v1.5.2 (Java) on Mac OSX 10.6.8 with Java SE 6 (MacOS X Default)

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

#4


When using e.g tomcat for serving static files one has to specify the patterns like this:

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

Maybe you could try to do the same?

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

#1


Try manually defining the static files in appengine-web.xml like

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

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

This works for me even with servlets like

即使像servlet这样,这对我也有用

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

and

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

See Static Files and Resource Files

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

#2


... It seems that it was grabbing everything that wasn't grabbed be one of the other rules, which I don't understand because there was no * on the end of the url-pattern. ...

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

[[Unfortunately, the term "default servlet" is overloaded to mean differnt things - leading to confusion. I'll try to be clear.]]

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

The url-pattern "/" is special (Rogue Wave calls this the "default mapping"). This defines the application's "default servlet", which is used when the URL request does not match other patterns (SRV.11.2 bullet 3 and SRV 11.1 item #4). Apparently, "/" is handled as if you specified "/*".

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

... It also seems to be directly contradictory to the documentation ...

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

Agreed, I think app engine has a bug so its not following the documentation you cited. Here's my theory of what is going on. Since there is a default servlet for your app (resulting from defining a servlet for url pattern "/"), the app stops using "default" "default servlet" provided by the container for apps that don't define their own "default servlet". The container's "default" "default servlet" is what provides the default behavior for serving up static files. I think this is consistent with how some containers behave.

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

I wonder what would happen if you tried specifying a servlet for a URL pattern that matches a static file. Would it serve the file (as indicated by the docs) or invoke the servlet (as indicated by this theory).

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

... So, how can I have a rule that matches the base of my domain (eg. http://www.example.com/) and still allows the static files to filter through? ...

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

If the theory is right, the solutions provided by jacob (adapted for google app engine) and zockman seem like they'd work - they map the static files to the container's "default" "default servlet".

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

The only other idea I have is to write your app's "default servlet" to examine the request to see if the request is for "/" or not. If so, handle it. If not, then (somehow) invoke the container's "default" "default servlet" to process the request (which will hopefully cache the file). Hopefully, once the static file has been served once, caching will bypass the servlet(s) in the future.

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

Sorry, I can't be more specific or provide code - I haven't work with Google app engine (yet!).

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


Ref:

#3


I realize that this is an really old question but I just ran into the same problem. I had put my css/*.css, js/*.css, and favicon.ico under /war/static/ and used the public_root directive in my appengine-web.xml to point to /static. This worked fine on my local dev server but did not when I uploaded the app. Getting rid of /static and moving everything up a level worked for me.

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

SDK v1.5.2 (Java) on Mac OSX 10.6.8 with Java SE 6 (MacOS X Default)

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

#4


When using e.g tomcat for serving static files one has to specify the patterns like this:

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

Maybe you could try to do the same?

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