20

我想知道使用通配符或双通配符来描述 servlet 映射上的 url 模式有什么区别。

例如:下面有什么区别?

1)

<servlet-mapping id="...">
    <servlet-name>BuyServlet</servlet-name>
    <url-pattern>/buy/*</url-pattern>
</servlet-mapping>

2)

<servlet-mapping id="...">
    <servlet-name>ShopServlet</servlet-name>
    <url-pattern>/shop/**</url-pattern>
</servlet-mapping>

编辑:@Andrew 是对的,规范只讨论了一个通配符 (*)。

我仔细检查了我的代码,发现我发现双通配符 (**) 的位置是在 Spring SimpleUrlHandlerMapping bean 中。

在这种情况下,这是有道理的。根据类 doc,它使用AntPathMatcher,其中指出:

映射使用以下规则匹配 URL: ? 匹配一个字符 * 匹配零个或多个字符 ** 匹配路径中的零个或多个“目录”

4

3 回答 3

34

servlet 规范(2.5 版)的第 11.2 节规定如下:

在 Web 应用程序部署描述符中,使用以下语法来定义映射:

  • 以“/”字符开头并以“/*”后缀结尾的字符串用于路径映射。
  • 以“*”开头的字符串。前缀用作扩展映射。
  • 仅包含“/”字符的字符串表示应用程序的“默认”servlet。在这种情况下,servlet 路径是请求 URI 减去上下文路径,并且路径信息为空。
  • 所有其他字符串仅用于完全匹配。

所以我猜第二个变体 ( **) 没有意义。

PS 我刚刚尝试设置这样的映射,似乎只有这个确切的 url/shop/**会被匹配(Tomcat 6.0.32)。

于 2012-12-12T15:50:03.447 回答
8

Servlet 规范本身(3.0 版,第 12.2 章)只定义了两种通配符映射:

  • 如果 URL 模式以“/*”结尾,则它将所有请求匹配到前面的路径。
  • 如果 URL 模式以“*.”开头,它将匹配对任何以以下扩展名结尾的资源的所有请求。

例如,“/foo/*”将匹配所有以“http://server/context/foo/”开头的 URL 请求,而“*.jsp”将匹配所有以“.jsp”结尾的 URL 请求。

按照规范,空字符串(“”)和单斜杠(“/”)具有特定的含义。“所有其他字符串仅用于完全匹配。”

严格遵循规范,您的第二个示例根本不是通配符模式,而应仅与“/shop/**”完全匹配。然而,大多数 Servlet 容器不那么严格,允许在任意位置使用 * 通配符,或者提供更复杂的模式匹配选项。

于 2012-12-12T16:10:12.553 回答
4

没有在规范中谈论第二种情况。

根据servlet 规范 12.2

以“/”字符开头并以“/*”后缀结尾的字符串用于路径映射

All other strings are used for exact matches only.

根据规范,仅考虑精确匹配秒。它可能因服务器提供商而异。

于 2012-12-12T16:04:43.603 回答