You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring 3升级至Spring 6后forward跳转路径被篡改引发NoHandlerFoundException问题求助

Spring 3升级至Spring 6后forward跳转路径被篡改引发NoHandlerFoundException问题求助

各位大佬好,我正在把一个基于XML依赖注入的项目从Spring 3升级到Spring 6,碰到了一个诡异的forward跳转问题,折腾好久没解决,来求助大家!

我的项目里有个继承自AbstractCachingViewResolver的TranslatingViewResolver,调试日志显示它正确生成了forward跳转路径:

.TranslatingViewResolver 100159440 | Translating:postpone.noValidDate to forward:/webapp/message?heading=postpone.message.statusError.heading&message=postpone.message.noValidDate (That is an InternalResourceView, btw.)

但紧接着就抛出了找不到映射的异常:

2025-06-16 13:00:34,207 105827 WARN org.springframework.web.servlet.PageNotFound 100159440 | No mapping for GET /fed1/webapp/forward:/webapp/message org.springframework.web.servlet.NoHandlerFoundException: No endpoint GET /fed1/webapp/forward:/webapp/message.

能明显看到原本的forward:/webapp/message被篡改了,前面多了/fed1/webapp/前缀,导致找不到对应的处理器映射,完全搞不懂为啥会这样。

我已经做了这些尝试:

  • 查资料说需要用UrlBasedViewResolver来解析forward跳转,我已经配置了这个解析器,还在log4j2.xml里加了对应的DEBUG日志配置:
<Logger name="org.springframework.web.servlet.view.UrlBasedViewResolver" level="DEBUG">
  <AppenderRef ref="MyFile"/>
  <AppenderRef ref="Console"/>
</Logger>

但日志里完全看不到这个类的输出,根本没法排查它的执行情况。

  • 我翻了好多关于Spring中forward:跳转的文档和帖子,感觉配置都是对的,而且在Spring 3版本下运行得好好的,现在实在没头绪了。

更新1

我看了异常的堆栈跟踪:

at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885) ~[spring-webmvc-6.2.7.jar:6.2.7]
at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:710) ~[servlet-api.jar:6.1]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:130) ~[catalina.jar:11.0.8]
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) ~[tomcat-websocket.jar:11.0.8]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:109) ~[catalina.jar:11.0.8]
at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:514) ~[catalina.jar:11.0.8]
at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:334) ~[catalina.jar:11.0.8]
at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:263) ~[catalina.jar:11.0.8]
at org.springframework.web.servlet.view.InternalResourceView.renderMergedOutputModel(InternalResourceView.java:171) ~[spring-webmvc-6.2.7.jar:6.2.7]

从堆栈里能看到InternalResourceView持有正确的URL,但当请求回到FrameworkServlet时路径就被篡改了。我没办法调试Tomcat内部的代码,这完全说不通,现在开始怀疑是Tomcat或者Spring的bug了。


更新2

现在我发现可能是双重forward导致的问题:我的代码先被转发到PostponeController,这个控制器判断没有处理逻辑,又转发到消息控制器,但还没到消息控制器就触发了错误。查看请求中的转发信息时,发现它带上了Postpone相关的路径前缀,这个问题出在Tomcat 11的ApplicationHttpRequest.getRequestDispatcher()方法里。我不太清楚这应该怎么正常工作,毕竟之前Spring 3下是好的,现在还在深挖细节,欢迎大家提供思路。


更新3

我一直认为forward:是Spring框架的特性,而不是Servlet引擎的(如果这个理解错了请纠正我),所以不应该把带forward:的路径传给Tomcat,但现在实际情况就是这样。在InternalResourceView.renderMergedOutputModel方法里,有一行代码:

RequestDispatcher rd = getRequestDispatcher(request, dispatcherPath);

这里的dispatcherPath就包含了forward:前缀,我感觉这像是Spring Framework的一个bug?

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.08 08:54:36