Announcement Announcement Module
Collapse
No announcement yet.
Howto use Groovy bean as Struts action Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Howto use Groovy bean as Struts action

    Hello,

    I'm using Struts and DelegatingTilesRequestProcessor to get my Actions created by Spring. I'd like to use a groovy to script them for quick prototyping.
    First, I cannot set the name attribute to a bean (using spring 2.0-rc2 : only id can be set, and "/foo/bar" is not allowed as an ID). I've used an alias to solve this.

    Now, I get an exception
    Code:
    BeanNotOfRequiredTypeException: Bean named '/intranet/validationCde/recapCde' must be of type [org.apache.struts.action.Action], but was actually of type [$Proxy0]
    Sounds like the groovy-scripting support has created a Proxy that doesn't expose the target bean as type. I may need to use a cglib proxy, but have no idea how to do this.

    Does anyone have a solution for this ?

  • #2
    Just for info, here is my current context file :

    Code:
      
      <!-- lang:groovy doesn't allow name attribute -->
      <alias name="recapCde" alias="/intranet/validationCde/recapCde"/>
      <lang:groovy id="recapCde"
       script-source="file:D:/hamlet/hamlet-webapp/src/java/sfr/hamlet/webapp/action/validationCde/RecapCdeAction.java"
        refresh-check-delay="1">
        <lang:property name="radius" ref="radius"/>
      </lang:groovy>

    Comment


    • #3
      Allow ScriptFactoryPostProcessor to create CGlib proxies ?

      I've searched in spring sources why using a groovy bean as Action doesn't work.
      From What I've found, the ScriptFactoryPostProcessor creates a proxy for refreshable scripted-beans (createRefreshableProxy).
      The ProxyFactory used cannot be configured to use a CGlib proxy or anything else that allows to make the Proxy extend struts Action class.

      Is there any technical limitation for this ?

      Comment


      • #4
        I've found a (not so bad) solution !

        I've found a "quick & dirty" solution to use groovy beans as Struts action :

        I've created a "StrutsAction" interface with the Struts execute Method. My action must implement it (developper just have to add " implements StrutsAction")
        Code:
        public interface StrutsAction
        {
            public abstract ActionForward execute(ActionMapping mapping,
                    ActionForm form, HttpServletRequest request,
                    HttpServletResponse response) throws Exception;
        
        }
        I've created a SciptedBeanActionAdapter that extends Action and delegates to a StrutsAction.
        Code:
        public class SciptedBeanActionAdapter extends Action {
            private StrutsAction delegate;
            
            public SciptedBeanActionAdapter(StrutsAction delegate) {
                this.delegate = delegate;
            }
        
            public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
                return delegate.execute(mapping, form, request, response);
            }
        }
        I've extended AutowiringTilesRequestProcessor and override processActionCreate to first look for the action in context, like DeletatingRequestProcessor does, but expecting a StrutsAction. It then creates a SciptedBeanActionAdapter and return it as action.

        Code:
        protected Action processActionCreate(HttpServletRequest request,
                    HttpServletResponse response, ActionMapping mapping)
                throws IOException  {
                WebApplicationContext wac = getWebApplicationContext();
                String beanName = DelegatingActionUtils.determineActionBeanName(mapping);
                if (wac.containsBean(beanName)) {
                    StrutsAction bean = (StrutsAction) wac.getBean(beanName, StrutsAction.class);
                    return new SciptedBeanActionAdapter(bean);
                }
                return super.processActionCreate(request, response, mapping);
            }
        I've added a "classpath*:localContext.xml" to my webApplicationContext definition. This file is in $TOMCAT/shared/classes and defines my struts action as a grrovy bean :

        Code:
          <alias name="groovyAction" alias="/intranet/logonvalidate"/>
          <lang:groovy id="groovyAction"
            script-source="file:D:/../src/java/.../LogonValidateAction.java"
            refresh-check-delay="1">
            <lang:property name="contexte" ref="contexte" />
            <lang:property name="configuration" ref="configuration" />
          </lang:groovy>
        That beeing done , I can change the action code and hit refresh in my browser to see changes. On the production server, no localContext is defined and application uses statically compiled Actions.
        Last edited by ndeloof; Aug 3rd, 2006, 05:56 AM.

        Comment


        • #5
          This solution is now also explained on Struts wiki
          http://wiki.apache.org/struts/StrutsAndSpring

          Any suggestion is welcome.

          Comment

          Working...
          X