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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 06:57:13