web.xml中servlet-mapping的url-pattern支持多路径组件吗?Spring MVC请求映射异常
问题解答
1. web.xml中servlet-mapping的url-pattern是否支持多路径组件?
可以,Servlet 2.3规范明确允许/path/to/*这类包含多路径组件的前缀匹配模式,属于合法的url-pattern定义。只要请求路径以该前缀(包含后续的/及子路径)开头,就会被匹配到对应的Servlet。
2. 请求映射异常的原因分析
核心问题是Spring Controller的@RequestMapping路径与DispatcherServlet的url-pattern重复了前缀,导致Spring无法正确解析请求路径:
请求
http://myserver/myapp/functionality/2.0正常:
该请求路径无结尾/,Tomcat不会匹配/functionality/2.0/*的前缀映射(前缀要求路径以/functionality/2.0/开头),而是匹配了/functionality/2.0的精确映射(大概率你在web.xml中为NEWAPI DispatcherServlet配置了该精确匹配规则)。此时Spring处理的路径是空字符串"",刚好匹配你Controller中/functionality/2.0的映射组合(类上@RequestMapping+方法上空映射),因此能正常调用方法。请求
http://myserver/myapp/functionality/2.0/失败:
该路径以/functionality/2.0/开头,被Tomcat匹配到NEWAPI DispatcherServlet。Spring会自动去掉/functionality/2.0前缀,提取剩余路径为/,但你的Controller映射是/functionality/2.0/,Spring在当前DispatcherServlet上下文里找不到/对应的处理方法,因此抛出No mapping警告。请求
http://myserver/myapp/functionality/2.0/pathvalue失败:
逻辑同上,Spring提取后的路径是/pathvalue,但你的Controller映射是/functionality/2.0/pathvalue,两者不匹配导致无法找到处理方法。
解决方案
修改Controller的@RequestMapping路径,去掉与DispatcherServlet url-pattern重复的/functionality/2.0前缀,使用相对路径定义:
@RequestMapping("") @RestController public class MyControllerV2 { // 匹配 /myapp/functionality/2.0 @GetMapping public String getSomething4() { // 原有业务逻辑 } // 同时匹配 /myapp/functionality/2.0/ @GetMapping("/") public String getRoot() { return getSomething4(); // 复用原有逻辑或单独处理 } // 匹配 /myapp/functionality/2.0/pathvalue @GetMapping("/pathvalue") public String getPathValue() { // 原有业务逻辑 } // 匹配 /myapp/functionality/2.0/{entity} @GetMapping("/{entity}") public String getEntity(@PathVariable String entity) { // 原有业务逻辑 } }
如果希望/functionality/2.0和/functionality/2.0/共用同一个处理方法,可简化映射:
@GetMapping({"", "/"}) public String getSomething4() { ... }
同时检查web.xml,确保NEWAPI DispatcherServlet包含精确匹配规则,覆盖无结尾/的请求:
<servlet-mapping> <servlet-name>NEWAPI</servlet-name> <url-pattern>/functionality/2.0/*</url-pattern> <url-pattern>/functionality/2.0</url-pattern> </servlet-mapping>
内容的提问来源于stack exchange,提问作者Sridhar Sarnobat

