wfr*_*wfr 22 java servlets java-ee
我有一个包含内容的web.xml文件:
<servlet>
<servlet-name>servlet1</servlet-name>
<servlet-class>org.mycompany.test1</servlet-class>
</servlet>
<servlet>
<servlet-name>servlet2</servlet-name>
<servlet-class>org.mycompany.test2</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>servlet1</servlet-name>
<url-pattern>/path/test</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>servlet2</servlet-name>
<url-pattern>/path/test/*</url-pattern>
</servlet-mapping>
Run Code Online (Sandbox Code Playgroud)
我试过请求
.../path/test/abc
.../path/test
Run Code Online (Sandbox Code Playgroud)
这两个请求都由Servlet2处理.为什么?
UPDATE
谢谢你们的帮助.我意识到行为取决于servlet映射声明的顺序.我试过这个web.xml
<servlet>
<servlet-name>servlet1</servlet-name>
<servlet-class>org.mycompany.test1</servlet-class>
</servlet>
<servlet>
<servlet-name>servlet2</servlet-name>
<servlet-class>org.mycompany.test2</servlet-class>
</servlet>
<servlet>
<servlet-name>servlet3</servlet-name>
<servlet-class>org.mycompany.test3</servlet-class>
</servlet>
<servlet>
<servlet-name>servlet4</servlet-name>
<servlet-class>org.mycompany.test4</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>servlet1</servlet-name>
<url-pattern>/path/test</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>servlet2</servlet-name>
<url-pattern>/path/test/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>servlet3</servlet-name>
<url-pattern>/path/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>servlet4</servlet-name>
<url-pattern>/path</url-pattern>
</servlet-mapping>
Run Code Online (Sandbox Code Playgroud)
结果:
.../path/test/abc - servlet2
.../path/test/ - servlet2
.../path/test - servlet2
.../path/abc - servlet3
.../path/ - servlet4
.../path - servlet4
Run Code Online (Sandbox Code Playgroud)
Nis*_*hth 49
从Servlet 3.0 规范,这是Web容器在收到请求后必须找到servlet的方式(强调我的):
用于映射到servlet的路径是来自请求对象的请求URL减去上下文路径和路径参数.下面的URL路径映射规则按顺序使用.第一次成功匹配使用,未尝试进一步匹配:
- 容器将尝试查找请求路径与servlet路径的完全匹配.成功匹配选择servlet.
- 容器将递归地尝试匹配最长的路径前缀.这是通过使用'/'字符作为路径分隔符一次单击目录的路径树来完成的.最长匹配确定所选的servlet.
- 如果URL路径中的最后一个段包含扩展名(例如.jsp),则servlet容器将尝试匹配处理扩展请求的servlet.扩展名被定义为最后一个'.'之后的最后一个段的一部分.字符.
- 如果前三个规则都不会导致servlet匹配,则容器将尝试提供适合所请求资源的内容.如果为应用程序定义了"默认"servlet,则将使用它.许多容器提供用于提供内容的隐式默认servlet.
容器必须使用区分大小写的字符串比较进行匹配.
您还应该查看映射的规范(如下所示):
在Web应用程序部署描述符中,以下语法用于定义映射:
以字符开头
‘/’并以‘/*’后缀结尾的字符串用于路径映射.以
‘*.’前缀开头的字符串用作扩展名映射.空字符串
("")是一种特殊的URL模式,它完全映射到应用程序的上下文根,即表单的请求http://host:port/<contextroot>/.在这种情况下,路径信息是’/’,并且servlet路径和上下文路径是空字符串(““).仅包含
’/’字符的字符串表示应用程序的"默认"servlet.在这种情况下,servlet路径是请求URI减去上下文路径,路径信息为null.所有其他字符串仅用于完全匹配
我们现在来看看例子.考虑以下映射集:
Path Pattern Servlet /foo/bar/* servlet1 /baz/* servlet2 /catalog servlet3 *.bop servlet4
将导致以下行为:
Incoming Path Servlet Handling Request /foo/bar/index.html servlet1 /foo/bar/index.bop servlet1 /baz servlet2 /baz/index.html servlet2 /catalog servlet3 /catalog/index.html “default” servlet /catalog/racecar.bop servlet4 /index.bop servlet4
需要注意的是在的情况下/catalog/index.html,并/catalog/racecar.bop映射到这个servlet “/catalog”不使用,因为并不是完全配对.
现在来你的问题:)
/path/test属于映射规范的第5点.这意味着只有结束的路径/path/test才会定位servlet1.
但是/path/test/*有资格获得相同规范的第一点.这意味着:
.../path/test将处理servlet1和
.../path/test/abc 将由.处理 servlet2
我在测试应用程序中验证了这一点.
| 归档时间: |
|
| 查看次数: |
62801 次 |
| 最近记录: |