一尘不染

谁能解释servlet映射?

spring-mvc

我正在尝试使用SpringMVC编写Web应用程序。通常,我只是将一些虚构的文件扩展名映射到Spring的前端控制器并愉快地运行,但是这次我要使用类似REST的URL,没有文件扩展名。

将上下文路径下的所有内容映射到前端控制器(我们称其为“ app
”)意味着我也应该处理静态文件,这是我不希望做的事情(为什么要重塑另一种方式呢?),因此与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>

谁能阐明一些想法?


阅读 398

收藏
2020-06-01

共1个答案

一尘不染

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

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

在“失败1”中,您的/ 映射确实是有效的路径映射。通过web.xml中的/
映射,它可以回答除其他路径映射以外的所有请求。根据规范,扩展映射是由显式映射覆盖的隐式映射。这就是扩展映射失败的原因。一切都明确地映射到应用程序。

在失败2中,除了与静态内容映射匹配的内容外,App负责其他所有事情。为了显示快速测试中发生的情况,我进行了设置。这是一个例子。 /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(至少为6.0.16)会删除servlet映射,并会尝试使用剩余路径查找文件。
Jetty给出了您和我所期望的行为。

是否有某些原因导致您无法执行某些操作,例如为其余调用映射根目录。诸如app映射到/ rest_root /
之类的事情要由您负责rest_root文件夹中发生的任何事情,但是Tomcat应该处理其他任何地方,除非您进行其他显式映射。我建议将您的其余servlet设置为路径映射,因为它可以更好地声明意图。使用/或/
似乎不合适,因为您必须映射例外。以SO为例,我的其余映射将类似于

/ users / *用于用户servlet

/ posts / *用于posts servlet

映射顺序

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

请纠正我弄错的任何事情。

2020-06-01