Struts 1.2.9迁移至2.5.16时ActionContext.getContext()返回空指针异常
解决Struts2.5 + Sitemesh2.4页面空指针异常(ServletUrlRenderer第132行)
你遇到的这个空指针问题,是Struts2迁移结合Sitemesh装饰器模式时的典型兼容性问题,根源在于Sitemesh渲染页面时,Struts2的ActionContext尚未初始化或无法被正常访问。
问题原因拆解
ServletUrlRenderer第132行调用ActionContext.getContext().getValueStack()时,ActionContext.getContext()返回了null。通常有两种触发场景:
- Sitemesh过滤器的执行顺序在Struts2的DispatcherFilter之前,当Sitemesh通过
RequestDispatcher.include加载被装饰的JSP时,Struts2还没来得及初始化ActionContext。 - 被装饰的JSP页面直接被访问(未经过Struts2的Action处理),此时Struts2的上下文根本没有被创建。
分步解决方案
1. 调整Web.xml过滤器顺序(优先推荐)
确保Struts2的DispatcherFilter在Sitemesh过滤器之前执行,并且让Struts2过滤器处理INCLUDE类型的请求,这样Sitemesh后续的include操作能访问到已初始化的ActionContext:
<!-- 先配置Struts2过滤器 --> <filter> <filter-name>struts2</filter-name> <filter-class>org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter</filter-class> </filter> <filter-mapping> <filter-name>struts2</filter-name> <url-pattern>/*</url-pattern> <dispatcher>REQUEST</dispatcher> <dispatcher>INCLUDE</dispatcher> <!-- 关键:让Struts2处理Sitemesh的include请求 --> <dispatcher>FORWARD</dispatcher> </filter-mapping> <!-- 再配置Sitemesh过滤器 --> <filter> <filter-name>sitemesh</filter-name> <filter-class>com.opensymphony.sitemesh.webapp.SiteMeshFilter</filter-class> </filter> <filter-mapping> <filter-name>sitemesh</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
2. 在装饰器页面手动初始化ActionContext(应急方案)
如果调整过滤器顺序无法解决问题,可以在装饰器JSP的顶部添加代码,手动检查并初始化ActionContext:
<%@ page import="org.apache.struts2.ServletActionContext" %> <%@ page import="com.opensymphony.xwork2.ActionContext" %> <%@ page import="java.util.HashMap" %> <% // 检查ActionContext是否存在,不存在则手动创建上下文 if (ActionContext.getContext() == null) { ActionContext ctx = new ActionContext(new HashMap<>()); ServletActionContext.setContext(ctx); ServletActionContext.setRequest(request); ServletActionContext.setResponse(response); } %>
⚠️ 注意:这种方法是应急手段,手动创建的上下文可能和正常Action处理的上下文不一致,优先用第一种方案。
3. 升级Sitemesh到3.x版本(长期兼容方案)
Sitemesh2.4是比较老旧的版本,和Struts2.5的兼容性有限。Sitemesh3重新设计了集成逻辑,和Struts2的适配性更好,配置也更简洁。你可以考虑:
- 替换Sitemesh2的依赖为Sitemesh3的依赖
- 将web.xml中的Sitemesh过滤器替换为
org.sitemesh.config.ConfigurableSiteMeshFilter - 用sitemesh3.xml替代原有的decorator.xml进行配置
4. 检查Struts2核心配置
确保你的struts.xml配置没有阻断上下文初始化:
- 确认
struts.action.extension配置覆盖了你访问的页面路径 - 排查是否有自定义过滤器拦截请求,导致ActionContext无法正常传递
验证方法
修改过滤器顺序后重启应用,访问出现异常的页面,观察是否仍抛出空指针。如果问题解决,说明是过滤器顺序导致的;若仍存在,可尝试手动初始化上下文或升级Sitemesh。
内容的提问来源于stack exchange,提问作者nitesh basnet
相关产品推荐
相关产品推荐

