Spring MVC从5.3升级到6.1.13出现NoHandlerFoundException求助
问题原因
Spring MVC 6.x 默认启用 PathPatternParser 作为路径匹配器,替代了旧版本的 AntPathMatcher。两者在处理Servlet映射前缀时逻辑不同:当DispatcherServlet映射为 /start/* 时,PathPatternParser 会自动剥离请求路径中的 /start 前缀,再与控制器的映射路径匹配。而你的控制器映射路径包含重复的 /start,导致实际匹配路径变成 /landing/{pageId},与控制器的 /start/landing/{pageId} 不匹配,最终抛出 NoHandlerFoundException。
解决方法
方法一:调整控制器映射路径(推荐)
去掉控制器映射中重复的 /start 前缀,适配 PathPatternParser 的前缀剥离逻辑:
@RequestMapping(value="/landing/{pageId}", method=RequestMethod.GET)
这样当请求 /myapp/start/landing/home 到达时,DispatcherServlet 剥离 /start 后,剩余路径 /landing/home 就能和控制器的映射规则匹配。
方法二:强制切换回 AntPathMatcher
若不想修改控制器代码,可配置使用旧的 AntPathMatcher,保持和 Spring 5.3 一致的匹配逻辑:
Java 配置方式
在自定义的 WebMvcConfigurer 实现类中重写方法:
@Override public void configurePathMatch(PathMatchConfigurer configurer) { configurer.setPathMatcher(new AntPathMatcher()); }
注意不要用 setPathPatternParser(null),直接设置 PathMatcher 才能生效。
XML 配置方式
添加如下配置:
<mvc:annotation-driven path-matcher="antPathMatcher"/> <bean id="antPathMatcher" class="org.springframework.util.AntPathMatcher"/>
方法三:配置 PathPatternParser 保留前缀(不推荐)
若坚持使用 PathPatternParser,可通过配置让其不自动剥离前缀,但这种方式不符合 Spring MVC 6.x 的设计意图,仅作为临时兼容方案:
@Override public void configurePathMatch(PathMatchConfigurer configurer) { configurer.setPathPatternParser(new PathPatternParser()); configurer.setUseSuffixPatternMatch(true); configurer.addPathPrefix("/start", c -> true); }
内容的提问来源于stack exchange,提问作者Sumanth

