【问题标题】:Ambiguity in servlet-mappingservlet 映射中的歧义
【发布时间】:2009-10-15 10:50:38
【问题描述】:

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

【问题讨论】:

    标签: java tomcat servlets


    【解决方案1】:

    您的架构是以下内容的缩写吗?

    <?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 遇到与请求匹配的多个定义(如您的情况)时,它会使用第一个。

    【讨论】:

      【解决方案2】:

      当 Tomcat 收到请求时,它会使用配置的 servlet 映射选择一个 servlet 执行。如果请求的 URL 匹配多个映射,则选择最佳匹配,忽略其他匹配。

      根据规范,路径前缀模式映射优于扩展映射。这意味着,在您的示例中,“/servlets/”上的映射应该胜过“.col”上的映射,并且请求应该始终导致模式 servlet 的执行。重新排列声明时出现的意外行为是因为您的描述符不正确,正如其他答案已经指出的那样。尝试使用正确的描述符,就像 David Rabinowitz 建议的那样。

      【讨论】:

      • 谢谢弗利里先生。我也更正了我的描述符。而且,我在哪里可以找到提供有关选择 servlet 映射和此类首选项的信息的规范?
      【解决方案3】:

      在我看来,这不像是合法的部署描述符。架构不需要这样的东西吗:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-01-03
        • 2015-03-01
        • 2011-11-01
        • 1970-01-01
        • 1970-01-01
        • 2015-11-19
        • 2012-04-17
        • 1970-01-01
        相关资源
        最近更新 更多