【问题标题】:Struts2 global result throwing StackOverflowError on result type chain/tilesStruts2 全局结果在结果类型链/图块上抛出 StackOverflowError
【发布时间】:2013-01-01 12:38:54
【问题描述】:

下面是我在 struts.xml 中定义的拦截器和全局结果

 <package name="auth_basic" extends="struts-default,tiles-default">
<interceptors>
        <interceptor name="nlogin" class="interceptors.LoginInterceptor"/>
        <interceptor-stack name="loginStack">
            <interceptor-ref name="nlogin"/>
            <interceptor-ref name="defaultStack"/>
        </interceptor-stack>
    </interceptors>
    <default-interceptor-ref name="loginStack"/>
    <global-results>
        <result name="login" type="redirectAction">gotostart</result>
        <result name="input" type="redirectAction">gotostart</result>
    </global-results>
.
.
.
</package>

上述配置工作正常,但是当我使用结果 chain 而不是 redirectAction 时,它会给出 java.lang.StackOverflowError

当我使用tiles 代替链时,它也会抛出 java.lang.StackOverflowError

我不能在全局结果中使用动作链吗?

下面是我的拦截器代码。另外,我想强调结果类型 redirectAction 工作正常,只有瓷砖和链会产生问题。

public String intercept(ActionInvocation ai) throws Exception {
    try {
        if (ai.getInvocationContext().getSession().get("user") == null) {
            System.out.println("Session Expired/Invalid");
            Object action = ai.getAction();
            if (action instanceof ValidationAware) {
                ((ValidationAware) action).addActionError("Unauthorized access. Please Login first");
            }
            return "login";
        }
        return ai.invoke();
    } catch (Exception e) {
        e.printStackTrace();
    }
    return ai.invoke();
}

edited to include more code from struts.xml

 <package name="default" extends="struts-default,tiles-default,json-default">
    <default-action-ref name="gotostart"/>
    <global-results>
        <result name="input" type="tiles">tiles-home</result>
    </global-results>
<action name="gotostart" class="actions.IndexAction" method="start">
        <result name="success" type="tiles">tiles-home</result>
        <result name="input" type="tiles">tiles-home</result>
    </action>
</package>

【问题讨论】:

  • 你可能在nLogin 拦截器中做错了什么。 stackOverflowError 意味着您有 99% 的时间处于无限循环中;尝试调试它,你会看到...
  • @AndreaLigios 我已经编辑了问题以包含我的拦截器代码。请注意,redirectAction 结果类型不会只给出链和平铺结果类型的错误。

标签: java jakarta-ee struts2 java-ee-6 java-ee-5


【解决方案1】:

好的,知道了。

如果未登录,您将返回一个全局结果 login,这是一个 chain 结果类型,然后是对另一个操作的调用。

login 结果类型位于包含nLogin Interceptor 的同一拦截器堆栈下。

这意味着,当您尝试链接您的 login 结果时,您会在您的 nLogin Interceptor 中再次传递,再次检查 user 是否为空,并返回 login 结果,在无限循环中。

你可以:

返回一个 JSP 而不是链接到另一个 Action,像这样:

<result name="login">myLogin.jsp</result>

或将您的全局结果 login 移到您的自定义拦截器堆栈范围之外(例如,将其放在父包中的默认堆栈下),如下所示:

<struts>
   <package name="defaultPackage" extends="struts-default" >

      <default-interceptor-ref name="defaultStack"/>

      <global-results>
         <result name="login" type="chain">
            <param name="actionName">myLoginAction</param>
         </result>
      </global-results>

   </package>

   <package name="myLoginProtectedPackage" extends="defaultPackage">

      <interceptors>
         <interceptor name="nlogin" class="interceptors.LoginInterceptor"/>
         <interceptor-stack name="loginStack">
            <interceptor-ref name="nlogin"/>
            <interceptor-ref name="defaultStack"/>
         </interceptor-stack>
      </interceptors>

      <default-interceptor-ref name="loginStack"/>

      <global-results>
        <result name="input" type="chain">
            <param name="actionName">myLoginAction</param>
        </result>
      </global-results>    

      <action name="myLoginAction" class="...">
         <result>myLogin.jsp</result>             
      </action>

   </package>
</struts>

不要问我为什么使用redirectAction 有效......它应该是相同的,但可能是由于它们的不同行为。

请注意,according to the guide

一般来说,不推荐使用动作链。首先探索其他选项,例如 Redirect After Post 技术。

【讨论】:

  • 感谢您的解释。但是链式操作 (gotostart) 具有 defaultInterceptorStack,因此它不会再次返回“登录”结果。
  • 那么,这不是您发布的内容。在您发布的内容中,全局结果位于“loginStack”下。你确定吗 ?您可以发布完整的 struts.xml(带有链,如果问题出在链中,而不是重定向操作)?
  • 正确的全局结果在 LoginStack 下,但链式操作具有不同的拦截器堆栈。我已编辑问题以获取更多详细信息。请看。
  • 这意味着当您尝试从登录结果链接到 GotoStart Action 时,它将通过 loginStack,正如我所说:|在到达 Action 之前遍历堆栈,而不是之后...尝试将登录结果从 auth-package 的全局移动到 default-package 的全局,并观察结果...
  • 好的,我好像明白了。拦截器也将在结果之后被调用。对 ?尽管将登录结果移出 auth 包没有任何意义,因为该包中的操作需要进行身份验证,所以我不能让其他包的操作返回来自其他包的结果。尽管我似乎明白了全部要点,但为什么链接不起作用。如果你写了一个答案来解释我的错,我很乐意接受。
猜你喜欢
  • 2011-04-14
  • 1970-01-01
  • 1970-01-01
  • 2011-09-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-11
相关资源
最近更新 更多