本文所要解决的问题是:如何让tomcat将HTTP请求映射到servlet类上让其实现功能。
要搞清楚这个问题,我们首先弄清楚一个正确的对应一个servlet类的HTTP请求是怎样的:
例如,给定一个链接:http://localhost/web/test,其中最关键的部分是/web/test,称为request URL(不包括链接中附带的参数)。在/web/test中,/web称为context path(上下文路径),表示一个context容器(或者说web应用);/test称为servlet path,这是用来找对应servlet的部分。
总的来说,servlet的URL映射问题可以转换为context容器是如何通过request URL找到对应servlet类问题。
答案是映射器,映射器是实现了Mapper接口的类,作用就是根据请求连接(主要是协议和路径)来选择servlet类或其他资源。每一个servlet类都可以绑定一个匹配规则,这样就可以通过映射器映射的方式实现URL与servlet之间的联系。
了解servlet请求的组成之后,我们需要熟悉请求的匹配规则
匹配规则主要有三种:
- Exact Match(完全匹配),也就是精确匹配
- Prefix Match(前缀匹配) ,匹配以 “/ ∗ * ∗” 作为结尾,这是一种最长路径匹配,例如对于URL: http://localhost/web/test 和匹配模式/web/ ∗ * ∗ 、/web/test/ ∗ * ∗,URL会被后者匹配
- Extension Match(扩展匹配),匹配以“ ∗ * ∗ .”作为开头,例如:“ ∗ * ∗ .do”
对于以上三种匹配需要注意的是,当一个url与多个servlet的匹配规则可以匹配时,则按照 “ 完全匹配 > 前缀匹配>扩展匹配> / ”这样的优先级匹配到对应的servlet。当完全匹配、前缀匹配、扩展匹配三者都不能匹配时,最后还会检查 “ / ” 能否被匹配。若都不能匹配,则会交给DefaultServlet来处理。
举例(以下匹配同时存在时):
- 完全匹配:/a
- 前缀匹配:/b/ ∗ * ∗ 、/ ∗ * ∗
- 扩展匹配: ∗ * ∗.do
URL | 被匹配的匹配规则 |
---|---|
/a | /a |
/b/test | /b/ |