Java 如何使用web.xml中的Servlet url映射?

Java 如何使用web.xml中的Servlet url映射?,java,jakarta-ee,servlets,Java,Jakarta Ee,Servlets,我有一个包含以下内容的web.xml文件: servlet1 org.mycompany.test1 servlet2 org.mycompany.test2 servlet1 /路径/测试 servlet2 /路径/测试/* 我试过请求 .../path/test/abc .../path/test 这两个请求都由Servlet2处理。为什么? 更新 谢谢你们的帮助。 我意识到行为取决于servlet映射声明的顺序。 我尝试了这个web.xml servlet1 org.mycomp

我有一个包含以下内容的web.xml文件:


servlet1
org.mycompany.test1
servlet2
org.mycompany.test2
servlet1
/路径/测试
servlet2
/路径/测试/*
我试过请求

.../path/test/abc 
.../path/test
这两个请求都由Servlet2处理。为什么?

更新

谢谢你们的帮助。 我意识到行为取决于servlet映射声明的顺序。 我尝试了这个web.xml


servlet1
org.mycompany.test1
servlet2
org.mycompany.test2
servlet3
org.mycompany.test3
servlet4
org.mycompany.test4
servlet1
/路径/测试
servlet2
/路径/测试/*
servlet3
/路径/*
servlet4
/路径
结果:

.../path/test/abc - servlet2
.../path/test/ - servlet2
.../path/test - servlet2

.../path/abc - servlet3
.../path/ - servlet4
.../path - servlet4
在Servlet 3.0中,这是web容器在收到请求后必须定位Servlet的方式(我的重点):

用于映射到servlet的路径是来自 请求对象减去上下文路径和路径参数。这个 下面的URL路径映射规则按顺序使用第一个成功的 使用match时不再尝试进一步匹配

  • 容器将尝试找到请求路径与servlet路径的精确匹配。成功匹配将选择 servlet
  • 容器将递归地尝试匹配最长路径前缀。这是通过在一个目录中的路径树上走下来完成的 每次使用“/”字符作为路径分隔符。最长的 匹配决定所选的servlet。
  • 如果URL路径中的最后一段包含扩展名(例如.jsp),servlet容器将尝试匹配处理 请求延期。扩展被定义为的一部分 最后一个“.”字符后的最后一段
  • 如果前三个规则都没有导致servlet匹配,那么容器将尝试提供适合该servlet的内容 请求的资源。如果为 应用程序,它将被使用。许多容器提供隐式 为内容提供服务的默认servlet
  • 容器必须使用区分大小写的字符串比较进行匹配

    您还应该查看映射规范(如下所示):

    在Web应用程序部署描述符中,使用以下语法 用于定义映射:

    Path Pattern Servlet /foo/bar/* servlet1 /baz/* servlet2 /catalog servlet3 *.bop servlet4
    • '/'
      字符开头,以
      '/*'
      后缀结尾的字符串 用于路径映射

    • '*.
      前缀开头的字符串用作扩展映射

    • 空字符串
      (“”)
      是一种特殊的URL模式,它精确地映射到 应用程序的上下文根,即表单的请求
      http://host:port//
      。在这种情况下,路径信息是
      “/”
      ,并且 servlet路径和上下文路径是空字符串
      (“”)

    • 仅包含
      '/'
      字符的字符串表示“默认值” 应用程序的servlet。在本例中,servlet路径是 请求URI减去上下文路径,路径信息为空

    • 所有其他字符串仅用于精确匹配

    现在让我们看看例子。考虑下面的映射集合:

    Path Pattern Servlet /foo/bar/* servlet1 /baz/* servlet2 /catalog servlet3 *.bop servlet4 路径模式Servlet /foo/bar/*servlet1 /baz/*servlet2 /目录服务3 *.bop服务4 将导致以下行为:

    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 传入路径Servlet处理请求 /foo/bar/index.html servlet1 /foo/bar/index.bop servlet1 /baz servlet2 /baz/index.html servlet2 /目录服务3 /catalog/index.html“默认”servlet /目录/赛车.bop服务4 /index.bop servlet4 注意,在
    /catalog/index.html
    /catalog/racecar.bop
    的情况下 未使用映射到
    “/catalog”
    的servlet,因为匹配不精确

    现在来谈谈你的问题:)

    /path/test
    属于映射规范的第五点。这意味着只有以
    /path/test
    结尾的路径将以
    servlet1
    为目标

    但是
    /path/test/*
    符合相同规范的第一点。这意味着:

    ../path/test
    将由
    servlet1

    ../path/test/abc
    将由
    servlet2

    我在测试应用程序中对此进行了验证。

    您的路径冲突

    两条路径的含义相同,“/*”没有任何区别。 显然,当您尝试您的路径时,将执行最后一个匹配(servlet2)

    您通常将Servlet名称放入路径中,例如:

    /path/test/servlet1
    /path/test/servlet2
    

    可能您没有运行当前版本的web应用程序。是否使用IDE?如何部署?/path/test符合/path/test/*规则,它们存在冲突。@AurA如果是XML,则注释肯定不会与
    /*
    @MagnusTengdahl一起出现。我已修复语法突出显示-作为参考,您可以强制使用代码块通过在其前面加上
    (或
    lang java
    或任何东西)将其视为特定语言@wfr-您能否编辑您的问题以删除/澄清更新部分。您所说的不正确。映射的顺序无关紧要。假设您的更新是问题的解决方案,我浪费了好几个小时。可能是这样,但只是出于偶然。谢谢。@wfr,您为什么接受这个答案?似乎不是o不同意您关于servlet2处理/path/test的观察。谢谢。您在这里解决了我的问题: