Spring 5升级后Spring MVC映射正常却报404:找不到修改密码JSP
问题概述
将遗留Spring应用升级到Spring 5后,未修改控制器映射,登录时用户被引导至修改密码页面,触发404错误,提示「JSP文件[/WEB-INF/jsp/public/change-password.jsp]未找到」。
根源分析
1. 视图路径解析不匹配
公共Servlet配置的视图解析器规则:
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/jsp/public/"/> <property name="suffix" value=".jsp"/> </bean>
修改密码控制器返回的视图名为change-password/change-password,按规则拼接后路径为:/WEB-INF/jsp/public/change-password/change-password.jsp
但实际change-password.jsp直接位于/WEB-INF/jsp/public/目录下,路径不匹配导致找不到文件。
2. 请求映射冲突
登录失败处理器配置的跳转地址为/public/change-password,而修改密码控制器的@RequestMapping为/change-password。结合默认公共控制器@RequestMapping("/*")的通配规则,/public/change-password请求可能被默认控制器优先拦截,无法匹配到PublicChangePasswordController。
解决方案
方案1:修正控制器视图名
将PublicChangePasswordController中返回的视图名从change-password/change-password改为change-password,让视图解析器匹配正确的文件路径:
// 显示页面方法修改 ModelAndView modelAndView = new ModelAndView("change-password"); // 错误处理分支同步修改 if (bindingResult.hasErrors()) { return "change-password"; }
方案2:统一请求跳转地址
修改登录失败处理器的changePasswordUrl为/change-password,避免默认控制器拦截:
<property name="changePasswordUrl" value="/change-password" />
确保该请求能直接匹配到PublicChangePasswordController的映射规则。
方案3:调整JSP目录结构
若不想修改代码,可将change-password.jsp移动到/WEB-INF/jsp/public/change-password/目录下,保持与控制器返回视图名的路径一致。
补充说明
Spring 5对@RequestMapping的匹配规则做了严格优化,通配符/*的优先级和匹配逻辑相比旧版本更严谨,这是默认控制器可能拦截特定请求的原因之一。优先推荐前两种方案,避免依赖目录结构调整带来的维护成本。
内容的提问来源于stack exchange,提问作者dynamo

