5

我正在使用 Struts 2(版本 2.3.14.3)和 Sitemesh 3(版本 3.0-alpha-2),并且在某些情况下我得到了 NullPointerException。

首先,这是我在 web.xml 中的 struts2 / sitemesh 配置:

<filter-mapping>
    <filter-name>struts-prepare</filter-name>
    <url-pattern>*.do</url-pattern>
    <dispatcher>REQUEST</dispatcher>
    <dispatcher>FORWARD</dispatcher>
</filter-mapping>

<filter-mapping>
    <filter-name>sitemesh</filter-name>
    <url-pattern>*.do</url-pattern>
    <dispatcher>REQUEST</dispatcher>
    <dispatcher>FORWARD</dispatcher>
    <dispatcher>INCLUDE</dispatcher>
</filter-mapping>

<filter-mapping>
    <filter-name>struts-execute</filter-name>
    <url-pattern>*.do</url-pattern>
    <dispatcher>REQUEST</dispatcher>
    <dispatcher>FORWARD</dispatcher>
</filter-mapping>

<servlet>
    <servlet-name>sitemesh-freemarker</servlet-name>
    <servlet-class>org.apache.struts2.sitemesh.FreemarkerDecoratorServlet</servlet-class>
    <init-param>
        <param-name>default_encoding</param-name>
        <param-value>UTF-8</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

现在,这是问题描述:

如果启用了 struts dev.mode 并且我尝试访问不存在的操作,则会引发 struts ConfigurationException。

Struts 调度程序尝试通过调用 org.apache.struts2.dispatcher.Dispatcher.sendError() 来处理异常,这会将标准 Struts 错误模板 (/org/apache/struts2/dispatcher/error.ftl) 写入响应。

现在这是事情开始出错的时候。

因为原始请求是用sitemesh过滤器装饰的,即使在发生配置错误之后,sitemesh也会尝试应用装饰器,这会导致异常,因为由于配置异常,Struts action context没有正确设置,我得到以下:

java.lang.NullPointerException
org.apache.struts2.sitemesh.FreemarkerDecoratorServlet.process(FreemarkerDecoratorServlet.java:176)

这是来自 FreemarkerDecoratorServlet.java 的相应代码 - ctx 变量为空:

ActionContext ctx = ServletActionContext.getActionContext(request);
model = freemarkerManager.buildTemplateModel(ctx.getValueStack(), ctx.getActionInvocation().getAction(), servletContext, request, response, wrapper);

我认为如果调用动作时出现错误,sitemesh 不应该尝试装饰响应,但我不知道如何在不修改 Struts2/Sitemesh 集成的情况下做到这一点。

任何想法如何避免NPE?

谢谢,马雷克

4

1 回答 1

1

解决方法可能是将此代码段放在文件末尾Struts.xml

<action name="pageNotFound">
    <result>404.jsp</result>
</action>

<action name="*">
    <result type="redirectAction">
        <param name="actionName">pageNotFound</param>
    </result>
</action>

它应该拦截每个未声明的、请求的动作,并将它们重定向到带有其 JSP 的现有动作。

试一试... ;)

于 2013-07-01T13:04:59.343 回答