我有一个内容为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>
我尝试过要求
.../path/test/abc
.../path/test
这两个请求都由Servlet2处理。为什么?
更新
谢谢你们的帮助。我意识到行为取决于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>
结果:
.../path/test/abc - servlet2
.../path/test/ - servlet2
.../path/test - servlet2
.../path/abc - servlet3
.../path/ - servlet4
.../path - servlet4
从Servlet 3.0
规范开始,这是Web容器在收到请求后必须定位servlet的方式(重点是我的):
用于映射到servlet的路径是来自请求对象的请求URL减去上下文路径和路径参数。以下URL路径映射规则按顺序使用。
使用第一个成功的匹配,不尝试其他匹配 :
- 容器将尝试查找请求路径与Servlet路径的精确匹配。成功匹配将选择servlet。
- 容器将递归地尝试匹配最长的路径前缀。 这是通过使用“
/”字符作为路径分隔符,一次将路径树下移到一个目录来完成的。最长的匹配确定所选的servlet。
3.
如果URL路径中的最后一个段包含扩展名(例如.jsp),则servlet容器将尝试匹配处理该扩展名请求的servlet。扩展名定义为最后一个段之后的最后一个段的一部分。字符。- 如果前三个规则均未导致servlet匹配,则容器将尝试提供适合于所请求资源的内容。如果为应用程序定义了“默认”
servlet,则将使用它。许多容器提供了一个隐式默认servlet来提供内容。
容器必须使用区分大小写的字符串比较进行匹配。
您还应该查看映射的规范(如下所示):
在Web应用程序部署描述符中,以下语法用于定义映射:
以字符开头
‘/’
并以‘/*’
后缀结尾的字符串用于路径映射。以
‘*.’
前缀开头的字符串用作扩展名映射。空字符串
("")
是一种特殊的URL模式,它精确地映射到应用程序的上下文根,即形式的请求
http://host:port/<contextroot>/
。在这种情况下,路径信息为’/’
,而servlet路径和上下文路径为空字符串(““)
。仅包含
’/’
字符的字符串表示应用程序的“默认”
servlet。在这种情况下,Servlet路径是请求URI减去上下文路径,并且路径信息为null。所有其他字符串仅用于完全匹配
现在让我们来看一些例子。考虑以下一组映射:
路径模式Servlet
/ foo / bar / * servlet1
/ baz / * servlet2
/目录servlet3
* .bop servlet4
将导致以下行为:
传入路径Servlet处理请求
/foo/bar/index.html servlet1
/foo/bar/index.bop servlet1
/ baz servlet2
/baz/index.html servlet2
/目录servlet3
/catalog/index.html“默认” servlet
/catalog/racecar.bop servlet4
/index.bop servlet4
请注意,在的情况下/catalog/index.html
和/catalog/racecar.bop
,该servlet映射到“/catalog”
不使用,因为并不是完全配对。
现在遇到您的问题了:)
/path/test
属于映射规范的第5点。这意味着只有以结尾的路径才是/path/test
target servlet1
。
但是/path/test/*
符合相同规范的第一点。这意味着:
.../path/test
将处理servlet1
和
.../path/test/abc
将由 servlet2
我在测试应用程序中对此进行了验证。
我试过请求 这两个请求都由Servlet2处理。为什么? 更新 结果:
我正在尝试在web.xml中映射多个servlet。在我的index.html中,我有一个操作“desktype.do”的表单,当我运行程序时,它成功了。我是这样开始的: …效果很好。它成功地编译,并且在按下我在index.html中设置的按钮后,它就会按照需要运行。在添加了额外的servlet映射之后: 我收到错误“模块尚未部署。详细信息请参阅服务器日志。构建失败(总时间;0秒)”我不确定该怎么
问题内容: xml文件位于我的项目中。我正在使用Eclipse并运行Tomcat(它不是通过Eclipse安装的。我希望它是单独的安装)。 当表单页面提交到servlet时,它不起作用。我每次都收到404错误。我已经遇到这个问题一段时间了。有人请帮助我。 问题答案: 您缺少标记,这对于映射很重要。因此,使用以下命令: 并且您应该像下面这样在表单上赋予价值: 并记下所有值在以下代码中区分大小写: 您
仅供参考:我已经删除了所有apache默认的webapp文件,并启动了我自己的项目,因此可以使用访问它,这很好。 我在驱动器中的servlet位置: 我在eclipse IDE中的包:eclipse IDE映像中的包 和我的web.xml文件: 我的HTML表单: 感谢所有的回复:)
xml文件位于我的项目的中。我正在使用Eclipse并运行Tomcat(它不是通过Eclipse安装的,我更希望它是一个单独的安装)。 当表单页面提交给servlet时,它就不起作用了。我每次都得到一个404错误。我遇到这个问题有一段时间了。谁来帮帮我。
我有以下代码: 如果我想迭代Map,上面的代码工作得很好。但是现在我有这样的东西。 我想在映射中遍历映射,并获取它的键和值。我想得到key1、value1、key2、value2、key3、value3的值,依此类推。那我该怎么做呢?