使用 struts1-plugin 调用操作时出现 InstantiationException

InstantiationException when calling action using struts1-plugin

我们将旧的 Struts 1 应用程序迁移到 Struts 2,使用 struts1-插件来包装我们的操作。
这对某些操作非常有效,但其他操作会抛出如下所示的错误:

java.lang.InstantiationException 
sun.reflect.InstantiationExceptionConstructorAccessorImpl.newInstance(InstantiationExceptionConstructorAccessorImpl.java:48)
java.lang.reflect.Constructor.newInstance(Constructor.java:526)
java.lang.Class.newInstance(Class.java:374)
com.opensymphony.xwork2.ObjectFactory.buildBean(ObjectFactory.java:158)
com.opensymphony.xwork2.ObjectFactory.buildBean(ObjectFactory.java:189)
com.opensymphony.xwork2.ObjectFactory.buildBean(ObjectFactory.java:178)
com.opensymphony.xwork2.interceptor.ScopedModelDrivenInterceptor.resolveModel(ScopedModelDrivenInterceptor.java:106)
com.opensymphony.xwork2.interceptor.ScopedModelDrivenInterceptor.intercept(ScopedModelDrivenInterceptor.java:136)
com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:244)
com.opensymphony.xwork2.interceptor.StaticParametersInterceptor.intercept(StaticParametersInterceptor.java:191)
com.opensymphony.xwork2.DefaultActionInvocation.invoke(DefaultActionInvocation.java:244)
org.apache.struts2.impl.StrutsActionProxy.execute(StrutsActionProxy.java:54)
org.apache.struts2.dispatcher.Dispatcher.serviceAction(Dispatcher.java:564)
org.apache.struts2.dispatcher.ng.ExecuteOperations.executeAction(ExecuteOperations.java:81)
org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter.doFilter(StrutsPrepareAndExecuteFilter.java:99)
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
de.dak.intranet.webtier.extranet.StartPageFilter.doFilter(StartPageFilter.java:74)
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
de.dak.intranet.webtier.auth.LoginFilter.doFilter(LoginFilter.java:288)
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:504)
org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:170)
org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:950)
org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:421)
org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1074)
org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:611)
org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:314)
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
java.lang.Thread.run(Thread.java:745)

此操作的配置非常简单:

<package name="extranet" extends="struts1-default" namespace="/extranet">
  <action name="acceptConditions" class="org.apache.struts2.s1.Struts1Action>
    <param name="className">de.intranet.webtier.extranet.AcceptConditionsAction</param>
    <interceptor-ref name="struts1Stack"/>
    <result name="success">/servlet/index.jsp</result>
  </action>
</package>

我尝试删除操作中的拦截器,但这并没有改变任何东西。 操作 class 看起来像这样(省略了实际逻辑):

public class AcceptConditionsAction extends Action {
  public ActionForward execute(ActionMapping mapping, 
                               ActionForm form, 
                               HttpServletRequest request, 
                               HttpServletResponse response) 
        throws Exception {
    return mapping.findForward("success");
  }
}

我们的 jsp 模板中的 link 是使用 s:action 标签正确构建的,当单击 link 时,同一站点上的另一个操作完美运行。然而,此操作会生成上面显示的堆栈跟踪,我无法弄清楚它来自哪里或如何修复它。永远不会到达操作内的断点,因此必须在实例化操作本身时发生错误。

我希望有人能帮我弄清楚发生了什么。

编辑: 澄清工作行动:

<package name="extranet" extends="struts1-default" namespace="/extranet">
  <interceptors>
    <interceptor name="pwdForm" class="com.opensymphony.xwork2.interceptor.ScopedModelDrivenInterceptor>
      <param name="className">de.intranet.webtier.extranet.PasswordForm</param>
      <param name="name">pwdForm</param>
    </interceptor>
  </interceptors>
  <action name="editPassword" class="org.apache.struts2.s1.Struts1Action">
    <param name="className">de.intranet.webtier.extranet.EditPasswordAction</param>
    <interceptor-ref name="pwdForm"/>
    <interceptor-ref name="struts1Stack"/>
    <result name="changePassword">/extranet/changePassword.jsp</result>
  </action>
</package>

Java 实现看起来像 AcceptConditionsAction。只有执行方法被覆盖,没有定义构造函数。

Aleksandr 向我指出了答案: struts1-插件(称为 struts1Stack)提供的拦截器堆栈创建了几个需要表单的拦截器(即 scopedModelDrivenmodelDriven 和其他一些)。如果您不使用整个堆栈而只添加操作所需的拦截器,则不再需要定义 FormBean.

删除 interceptor-ref "strutsStack",添加 "staticParams" 即可。 如下图

<package name="extranet" extends="struts1-default" namespace="/extranet">
  <action name="acceptConditions" class="org.apache.struts2.s1.Struts1Action>
    <param name="className">de.intranet.webtier.extranet.AcceptConditionsAction</param>
    <!--interceptor-ref name="struts1Stack"/-->
    <interceptor-ref name="staticParams"/>
    <result name="success">/servlet/index.jsp</result>
  </action>
</package>