我有两个servlet'ExtensionServlet'和'PatternServlet'以及一个静态html页面。 HTML代码如下所示。
<html>
<head>
<title>
Resolve servlet ambiguity
</title>
</head>
<body>
<form action="servlets/form.col" method="POST">
<input type="submit" value="Goto Servlet">
</form>
</body>
</html>
部署描述符如下。
<?xml version="1.0" encoding="ISO-8859-1" ?>
<web-app version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" >
<servlet>
<servlet-name>Extension Servlet</servlet-name>
<servlet-class>ExtensionServlet</servlet-class>
<servlet-name>Pattern Servlet</servlet-name>
<servlet-class>PatternServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Extension Servlet</servlet-name>
<url-pattern>*.col</url-pattern>
<servlet-name>Pattern Servlet</servlet-name>
<url-pattern>/servlets/*</url-pattern>
</servlet-mapping>
</web-app>
当我点击HTML页面中的按钮时,它会指向“PatternServlet”。如果我在部署描述符中重新排列servlet顺序,如下所示,它将转到“ExtensionServlet”
<?xml version="1.0" encoding="ISO-8859-1" ?>
<web-app version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" >
<servlet>
<servlet-name>Pattern Servlet</servlet-name>
<servlet-class>PatternServlet</servlet-class>
<servlet-name>Extension Servlet</servlet-name>
<servlet-class>ExtensionServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Pattern Servlet</servlet-name>
<url-pattern>/servlets/*</url-pattern>
<servlet-name>Extension Servlet</servlet-name>
<url-pattern>*.col</url-pattern>
</servlet-mapping>
</web-app>
有人可以解释一下这种行为吗?
Tomcat 6.0.20 JVM 1.6.0_15-b03
答案 0 :(得分:4)
您的架构是否缩短了以下内容?
<?xml version="1.0" encoding="ISO-8859-1" ?>
<web-app version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" >
<servlet>
<servlet-name>Pattern Servlet</servlet-name>
<servlet-class>PatternServlet</servlet-class>
</servlet>
<servlet>
<servlet-name>Extension Servlet</servlet-name>
<servlet-class>ExtensionServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Pattern Servlet</servlet-name>
<url-pattern>/servlets/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>Extension Servlet</servlet-name>
<url-pattern>*.col</url-pattern>
</servlet-mapping>
</web-app>
在您的版本中,我认为您只定义了一个servlet。
当tomcat遇到与请求匹配的多个定义时(如您的情况),它使用第一个定义。
答案 1 :(得分:2)
当Tomcat收到请求时,它会使用配置的servlet映射选择一个servlet来执行。如果请求的URL匹配多个映射,则选择最佳匹配,忽略其他匹配。
根据规范,路径前缀模式映射优于扩展映射。这意味着,在您的示例中,“/ servlets / ”上的映射应该胜过“ .col”上的映射,并且请求应始终导致Pattern servlet的执行。重新排列声明时出现的意外行为是因为您的描述符不正确,正如其他答案已经指出的那样。尝试使用正确的描述符,如David Rabinowitz建议的描述符。
答案 2 :(得分:1)
对我来说,这看起来不像是合法的部署描述符。架构不需要这样的东西:
<servlet>
<servlet-name>Extension Servlet</servlet-name>
<servlet-class>ExtensionServlet</servlet-class>
</servlet>
<servlet>
<servlet-name>Pattern Servlet</servlet-name>
<servlet-class>PatternServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Extension Servlet</servlet-name>
<url-pattern>*.col</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>Pattern Servlet</servlet-name>
<url-pattern>/servlets/*</url-pattern>
</servlet-mapping>