参考资源
详情可以参考:https://jakarta.ee/specifications/servlet/6.0/jakarta-servlet-spec-6.0.html#mapping-requests-to-servlets
URL路径的使用
web容器接收到客户端的请求,决定转发给哪个web应用。被选中的web 应用必须具有最长的上下文(context path)路径(从请求URL开始匹配)。URL中匹配的部分就是映射到servlet的上下文路径。
请求URL中用于映射到servlet的部分是去掉上下文路径、去掉路径参数的部分。按照如下的URL映射规则进行,顺序从上到下。如果发现了一条匹配的规则,就不再往后查找:
- 容器尽量发现请求路径和servlet路径的精确匹配。成功匹配后,也就选定了处理该请求的servlet。
- 容器递归尽力查找最长匹配的路径前缀(path-prefix)。成功匹配后,也就选定了处理该请求的servlet。
- 如果路径的最后一段包含一个扩展名(例如.jsp),容器尽量匹配一个处理该扩展名的servlet。扩展名定义为最后一个"."字符后面的部分。
- 如果上面的三个规则都没有匹配上,容器试图根据请求提供适合的内容。如果配置了默认(“default”)servlet,那么会使用该默认的servlet。
映射规范
在web应用描述符(web.xml),用如下语法定义映射:
- 以"/“字符开头、以”/*"结尾的字符串用于路径匹配。
例如:
<servlet-mapping><servlet-name>restful-addnumbers</servlet-name><url-pattern>/addnumbers/*</url-pattern>
</servlet-mapping>
- 以"*."前缀开头的字符串作为一个扩展名匹配。
例如:*.bop
- 空字符串(“”)是一个特殊的URL模式。它精确映射到应用的上下文的根,即请求的形式是
http://host:port/<context-root>/
。在这种情况下,路径信息(path info)是"/“,servlet path和context path是空字符串(”")。 - 字符串串只包含"/"这样一个字符,表示应用的默认servlet(“default” servlet)。在这种情况下,servlet path 等于 请求URI 减去上下文路径(context path),路径信息(path info)是null。
- 所有其它的字符串只用于精确匹配。
隐含匹配
如果容器包含一个JSP容器,那么*.jsp扩展名映射到该JSP容器,这个称为隐含映射。但如果应用明确定义了*.jsp映射,那么应用定义的映射优先级高于隐含映射。
举例
采用servlet规范中的例子:https://jakarta.ee/specifications/servlet/6.0/jakarta-servlet-spec-6.0.html#example-mapping-set
当一个应用进来的时候,上面配置的映射规则产生下面的实际匹配结果:
注意:/catalog/index.html
和/catalog/racecar.bop
没有使用servlet映射中配置的/catalog
这条规则,因为/catalog
代表的是精确匹配。