任何人都可以解释servlet映射?

我正在尝试使用SpringMVC编写一个Web应用程序。 通常情况下,我只是将一些制作好的文件扩展名映射到Spring的前端控制器,并且乐于生活,但是这一次我要使用类似REST的URL,而且没有文件扩展名。

将我的上下文path下的所有内容映射到前端控制器(我们称之为“ app ”)意味着我也应该处理静态文件,我宁愿不要这么做(为什么要重新创build另一个文件?),所以与tomcat默认servlet(我们称之为“ tomcat ”)似乎是要走的路。

我得到了这样的事情来做类似的事情

<servlet-mapping> <servlet-name>app</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>tomcat</servlet-name> <url-pattern>*.ext</url-pattern> </servlet-mapping> 

并为我的静态内容的每个文件扩展名重复后者。 我只是想知道为什么下面的设置,这对我来说是相当于上面的,不起作用。

 <!-- failed attempt #1 --> <servlet-mapping> <servlet-name>app</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>tomcat</servlet-name> <url-pattern>*.ext</url-pattern> </servlet-mapping> <!-- failed attempt #2 --> <servlet-mapping> <servlet-name>app</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>tomcat</servlet-name> <url-pattern>/some-static-content-folder/*</url-pattern> </servlet-mapping> 

任何人都可以点亮一下吗?

我想我可能知道发生了什么事情。

在你正在工作的web.xml中,你已经将你的servlet设置为默认的servlet(如果没有其他匹配,它本身就是被调用的默认servlet),它将回答任何不匹配另一个映射的请求。

在失败1您的/ *映射似乎是一个有效的path映射。 通过web.xml中的/ *映射,它会回答除了其他path映射以外的所有请求。 根据规范,扩展映射是由显式映射覆盖的隐式映射。 这就是为什么扩展映射失败。 一切都明确映射到应用程序。

在失败2中,除了与静态内容映射匹配的内容之外,应用程序负责所有内容。 显示我设置的快速testing中发生了什么。 这是一个例子。 /some-static-content-folder/包含test.png

试图访问test.png我试过:

 /some-static-content-folder/test.png 

并找不到该文件。 然而尝试

 /some-static-content-folder/some-static-content-folder/test.png 

它出现了。 所以看起来,Tomcat的默认servlet(至less6.0.16)将删除servlet映射,并尝试使用剩余的path来查找文件。 根据这个postServlet提供静态内容 Jetty给你的行为,我期待。

是否有一些原因,你不能做你的rest电话的地图根目录。 像应用程序映射到/ rest_root / *比你负责rest_root文件夹中的任何事情,但任何其他地方应该由Tomcat处理,除非你做另一个明确的映射。 我build议把你的rest servlet设置成一个path映射,因为它更好的声明了这个意图。 使用/或/ *似乎不太合适,因为您必须绘制例外。 使用SO作为例子,我的rest映射将是类似的

/ users / *为用户servlet

/ posts / *为postservlet

映射顺序

  1. 显式(path映射)
  2. 隐式(扩展映射)
  3. 默认(/)

请纠正任何我错了。

作为参考,在Tomcat> = 6.0.29版本中,“失败的尝试#2”是完全正确的。

这是Tomcat bug在6.0.29版本中得到修复的结果:

https://issues.apache.org/bugzilla/show_bug.cgi?id=50026

 <!-- Correct for Tomcat >= 6.0.29 or other Servlet containers --> <servlet-mapping> <servlet-name>app</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>default</servlet-name> <url-pattern>/some-static-content-folder/*</url-pattern> </servlet-mapping> 

我从来没有尝试过像这样映射一个servlet,但是我认为/ *在技术上都是以/开头的,而以/ *结尾,即使两个匹配使用相同的字符。