servlet映射中的歧义

时间:2009-10-15 10:50:38

标签: java tomcat servlets

我有两个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

3 个答案:

答案 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>