java.lang.ClassCastException 在动作链接期间 - 从 Struts 1 到 Struts 2

java.lang.ClassCastException during action chaining - from Struts 1 to Struts 2

我们有 Struts 1 application.We 需要迁移到 Struts 2。 次要 change.We 不会改变 Action class 中的任何内容。 我们正在使用现有的操作 class 和操作表单。 动作正在被触发,没有任何问题。 但是动作链没有按预期工作。 我们使用了从 LoginAction 到 FetchInboxAction 的许多值。两者都使用两种不同的形式。 请找到示例 struts.xml 和错误堆栈。 连锁行动对我们不起作用。

目前我们遇到以下错误:

225760 [http-nio-8080-exec-8] ERROR org.apache.struts2.dispatcher.DefaultDispatcherErrorHandler  - Exception occurred during processing request: com.InboxForm cannot be cast to com.LoginForm
java.lang.ClassCastException: com.InboxForm cannot be cast to com.LoginForm
at com.LoginAction.execute(LoginAction.java:104)
at org.apache.struts2.s1.Struts1Action.execute(Struts1Action.java:99)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at ognl.OgnlRuntime.invokeMethod(OgnlRuntime.java:891)
at ognl.OgnlRuntime.callAppropriateMethod(OgnlRuntime.java:1293)
at ognl.ObjectMethodAccessor.callMethod(ObjectMethodAccessor.java:68)
at com.opensymphony.xwork2.ognl.accessor.XWorkMethodAccessor.callMethodWithDebugInfo(XWorkMethodAccessor.java:117)
at com.opensymphony.xwork2.ognl.accessor.XWorkMethodAccessor.callMethod(XWorkMethodAccessor.java:108)
at ognl.OgnlRuntime.callMethod(OgnlRuntime.java:1369)
at ognl.ASTMethod.getValueBody(ASTMethod.java:90)
at ognl.SimpleNode.evaluateGetValueBody(SimpleNode.java:212)
at ognl.SimpleNode.getValue(SimpleNode.java:258)
at ognl.Ognl.getValue(Ognl.java:494)
at ognl.Ognl.getValue(Ognl.java:458)
at com.opensymphony.xwork2.ognl.OgnlUtil.execute(OgnlUtil.java:309)
at com.opensymphony.xwork2.ognl.OgnlUtil.compileAndExecute(OgnlUtil.java:340)
at com.opensymphony.xwork2.ognl.OgnlUtil.getValue(OgnlUtil.java:307)
at com.opensymphony.xwork2.DefaultActionInvocation.invokeAction(DefaultActionInvocation.java:423)
at com.opensymphony.xwork2.DefaultActionInvocation.invokeActionOnly(DefaultActionInvocation.java:287)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:250)
at org.apache.struts2.interceptor.DeprecationInterceptor.intercept(DeprecationInterceptor.java:41)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:244)
at com.opensymphony.xwork2.interceptor.ConversionErrorInterceptor.intercept(ConversionErrorInterceptor.java:138)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:244)
at com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:229)
at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:244)
at com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:229)
at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:244)
at org.apache.struts2.interceptor.MultiselectInterceptor.intercept(MultiselectInterceptor.java:73)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:244)
at org.apache.struts2.interceptor.DateTextFieldInterceptor.intercept(DateTextFieldInterceptor.java:125)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:244)
at org.apache.struts2.interceptor.CheckboxInterceptor.intercept(CheckboxInterceptor.java:91)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:244)
at com.opensymphony.xwork2.interceptor.PrepareInterceptor.doIntercept(PrepareInterceptor.java:171)
at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:244)
at org.apache.struts2.interceptor.ServletConfigInterceptor.intercept(ServletConfigInterceptor.java:164)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:244)
at com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor.intercept(ExceptionMappingInterceptor.java:189)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:244)
at com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor.intercept(ModelDrivenInterceptor.java:100)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:244)
at com.opensymphony.xwork2.interceptor.ScopedModelDrivenInterceptor.intercept(ScopedModelDrivenInterceptor.java:141)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:244)
at com.opensymphony.xwork2.interceptor.StaticParametersInterceptor.intercept(StaticParametersInterceptor.java:191)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:244)
at org.apache.struts2.impl.StrutsActionProxy.execute(StrutsActionProxy.java:54)
at com.opensymphony.xwork2.ActionChainResult.execute(ActionChainResult.java:233)
at com.opensymphony.xwork2.DefaultActionInvocation.executeResult(DefaultActionInvocation.java:369)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:273)
at org.apache.struts2.interceptor.DeprecationInterceptor.intercept(DeprecationInterceptor.java:41)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:244)
at com.opensymphony.xwork2.interceptor.ConversionErrorInterceptor.intercept(ConversionErrorInterceptor.java:138)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:244)
at com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:229)
at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:244)
at com.opensymphony.xwork2.interceptor.ParametersInterceptor.doIntercept(ParametersInterceptor.java:229)
at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:244)
at org.apache.struts2.interceptor.MultiselectInterceptor.intercept(MultiselectInterceptor.java:73)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:244)
at org.apache.struts2.interceptor.DateTextFieldInterceptor.intercept(DateTextFieldInterceptor.java:125)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:244)
at org.apache.struts2.interceptor.CheckboxInterceptor.intercept(CheckboxInterceptor.java:91)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:244)
at com.opensymphony.xwork2.interceptor.PrepareInterceptor.doIntercept(PrepareInterceptor.java:171)
at com.opensymphony.xwork2.interceptor.MethodFilterInterceptor.intercept(MethodFilterInterceptor.java:98)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:244)
at org.apache.struts2.interceptor.ServletConfigInterceptor.intercept(ServletConfigInterceptor.java:164)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:244)
at com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor.intercept(ExceptionMappingInterceptor.java:189)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:244)
at com.opensymphony.xwork2.interceptor.ModelDrivenInterceptor.intercept(ModelDrivenInterceptor.java:100)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:244)
at com.opensymphony.xwork2.interceptor.ScopedModelDrivenInterceptor.intercept(ScopedModelDrivenInterceptor.java:141)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:244)
at com.opensymphony.xwork2.interceptor.StaticParametersInterceptor.intercept(StaticParametersInterceptor.java:191)
at com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:244)
at org.apache.struts2.impl.StrutsActionProxy.execute(StrutsActionProxy.java:54)
at org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:564)
at org.apache.struts2.dispatcher.ng.ExecuteOperations.executeAction(ExecuteOperations.java:81)
at org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.doFilter(StrutsPrepareAndExecuteFilter.java:99)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at com.SecurityAccessFilter.doFilter(SecurityAccessFilter.java:105)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:142)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:610)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:537)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1085)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:658)
at org.apache.coyote.http11.Http11NioProtocol$Http11ConnectionHandler.process(Http11NioProtocol.java:222)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1556)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1513)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:745)

struts.xml:

<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>


<package name="PackageName" namespace="/"
                               extends="struts1-default">
<interceptors>
  <interceptor name="LoginForm" 
   class="com.opensymphony.xwork2.interceptor.ScopedModelDrivenInterceptor">
    <param name="className">com.LoginForm</param>
    <param name="name">LoginForm</param>
    <param name="scope">request</param>
  </interceptor>


  <interceptor name="InboxForm" 
   class="com.opensymphony.xwork2.interceptor.ScopedModelDrivenInterceptor">
    <param name="className">com.InboxForm</param>
    <param name="name">InboxForm</param>
    <param name="scope">request</param>
  </interceptor>


  <interceptor-stack name="web">
    <interceptor-ref name="staticParams"/> 
    <interceptor-ref name="LoginForm"/>
    <interceptor-ref name="modelDriven"/>
    <interceptor-ref name="basicStack"/>
  </interceptor-stack>    


  <interceptor-stack name="web2">
    <interceptor-ref name="staticParams"/> 
    <interceptor-ref name="InboxForm"/>
    <interceptor-ref name="modelDriven"/>
    <interceptor-ref name="basicStack"/>
  </interceptor-stack>

</interceptors>


<action name="LoginAction" class="org.apache.struts2.s1.Struts1Action" method="execute" >
 <param name="className">com.LoginAction</param>
    <interceptor-ref name="web"/>       
    <result name="success" type="chain">FetchInboxAction</result>
    <result name="failure">/error.jsp</result>
 </action>

    <action name="FetchInboxAction" class="org.apache.struts2.s1.Struts1Action" method="execute">
 <param name="className">com.FetchInboxAction</param>
    <interceptor-ref name="web2"/>
    <result name="success">/sucess.jsp</result>
    <result name="failure">/error.jsp</result>
    </action>


    </package>
</struts>

在 struts.xml 中,对于 fetchInboxAction 所有拦截器在执行 LoginAction 之后再次被调用,而不是调用 FetchInboxAction 它调用 LoginActionInboxForm.In Action class Action 表单被类型转换为 LoginForm 但在 运行 时间我们得到 FetchInboxForm。这是由于错误的配置。

经过以下更改后,Action chin 正常工作。

已修改 Struts.xml

<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>


<package name="PackageName" namespace="/"
                               extends="struts1-default">
<interceptors>
  <interceptor name="LoginForm" 
   class="com.opensymphony.xwork2.interceptor.ScopedModelDrivenInterceptor">
    <param name="className">com.LoginForm</param>
    <param name="name">LoginForm</param>
    <param name="scope">request</param>
  </interceptor>


  <interceptor name="InboxForm" 
   class="com.opensymphony.xwork2.interceptor.ScopedModelDrivenInterceptor">
    <param name="className">com.InboxForm</param>
    <param name="name">InboxForm</param>
    <param name="scope">request</param>
  </interceptor>


  <interceptor-stack name="web">
    <interceptor-ref name="staticParams"/> 
    <interceptor-ref name="LoginForm"/>
    <interceptor-ref name="modelDriven"/>
    <interceptor-ref name="basicStack"/>
  </interceptor-stack>    


  <interceptor-stack name="web2">
    <interceptor-ref name="staticParams"/> 
    <interceptor-ref name="InboxForm"/>
    <interceptor-ref name="modelDriven"/>
    <interceptor-ref name="basicStack"/>
  </interceptor-stack>

</interceptors>


<action name="LoginAction" class="org.apache.struts2.s1.Struts1Action" method="execute" >
 <param name="className">com.LoginAction</param>
    <interceptor-ref name="web"/>       
    <result name="success" type="chain">FetchInboxAction</result>
    <result name="failure">/error.jsp</result>
 </action>

    <action name="FetchInboxAction" class="org.apache.struts2.s1.Struts1Action" method="execute">
 <param name="className">com.FetchInboxAction</param>
    <interceptor-ref name="InboxForm"/>
    <result name="success">/sucess.jsp</result>
    <result name="failure">/error.jsp</result>
    </action>


    </package>
</struts>