Announcement Announcement Module
Collapse
No announcement yet.
Getting the ApplicationContext in the Struts Form Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Getting the ApplicationContext in the Struts Form

    I've got an application context created by using the contextConfigLocation servlet of spring and I can get to the context in an action.

    However, I want to use a bean that is create via the constructor of an ActionForm. What is the best practice for getting an applicationContext in a Struts form. I can use ClasspathXmlAppContect or XmlBeanFactory, but is there a way to get the context similarly to the setServlet of the Struts Action?

    Thanks!

  • #2
    AFAIK, Struts ActionForms should be /must be exclusively/ used to gather user input. No particular processing should go inside ActionForms.

    IMHO, your Action should get the bean from the Context then inject the indeed data into your ActionForm.

    Comment


    • #3
      Code:
      void setServlet(ActionServlet actionServlet)
      is called on ActionForms. You should be able to retrive the application context out of that in an identical way you do in the Action class.

      Mike

      Comment


      • #4
        Mike,

        Do you think it is a good design to bind ActionForms to Spring Framewok?

        Comment


        • #5
          Originally posted by irbouho
          AFAIK, Struts ActionForms should be /must be exclusively/ used to gather user input. No particular processing should go inside ActionForms.

          IMHO, your Action should get the bean from the Context then inject the indeed data into your ActionForm.
          I'm not processing. What does occur is that I use a form as a wrapper to a bean that does hold the data collected by the form. In addition, this bean has a DataValidator interface which in turn has a BaseErrors generic error object similar to a Struts ActionErrors. I use Spring to create this bean which gets inject by the DataValidator which gets injected by the BaseErrors.

          My form's validate method delegates validation to this valueObject(in essence) which delegates to this DataValidator.

          Now, my validation is decouple completely from Struts. Later, in my Action, I pull this bean out of the form and pass it to my middle tier where it becomes the data in a businessobject(also created by Spring).

          Currently, in the form constructor, I call the XmlBeanFactory to create this object, but I was wondering if there was a better way.

          Comment


          • #6
            Originally posted by futang
            Code:
            void setServlet(ActionServlet actionServlet)
            is called on ActionForms. You should be able to retrive the application context out of that in an identical way you do in the Action class.

            Mike
            I actually tried that, but unfortunately, this method wasn't called by the Struts framework the way the Action's setServlet is.

            Comment


            • #7
              irbouho,

              No I wouldn't suggest it, but the feature is there and it's certainly possible there is some benefit (i.e. this isn't life or death, giving people enough rope to hang themselves is ok with me). On the other hand now that I've used SpringMVC and Webwork2, Struts ActionForms make me cry.

              Mike

              Comment


              • #8
                jominor,

                could you expand on what's happening? I haven't used this feature and was operating based on the javadoc. After reading your last post I checked the source (CVS HEAD) and it looks like the ActionServlet should be set before processing occurs. The following is from FormBeanConfig and is called to create the ActionForm instance.

                Code:
                public ActionForm createActionForm(ActionServlet servlet)
                        throws IllegalAccessException, InstantiationException {
                
                        Object obj = null;
                
                        // Create a new form bean instance
                        if (getDynamic()) {
                            obj = getDynaActionFormClass().newInstance();
                        } else {
                            obj = formBeanClass().newInstance();
                        }
                
                        ActionForm form = null;
                        if (obj instanceof ActionForm) {
                            form = (ActionForm)obj;
                        } else  {
                            form = new BeanValidatorForm(obj);
                        }
                
                        form.setServlet(servlet);
                
                        if (form instanceof DynaBean && 
                            ((DynaBean)form).getDynaClass() instanceof MutableDynaClass) {
                            DynaBean         dynaBean  = (DynaBean)form;
                            MutableDynaClass dynaClass = (MutableDynaClass)dynaBean.getDynaClass();
                
                            // Add properties
                            dynaClass.setRestricted(false);
                            FormPropertyConfig props[] = findFormPropertyConfigs();
                            for &#40;int i = 0; i < props.length; i++&#41; &#123;
                                dynaClass.add&#40;props&#91;i&#93;.getName&#40;&#41;, props&#91;i&#93;.getTypeClass&#40;&#41;&#41;;
                                dynaBean.set&#40;props&#91;i&#93;.getName&#40;&#41;, props&#91;i&#93;.initial&#40;&#41;&#41;;
                            &#125;
                            dynaClass.setRestricted&#40;isRestricted&#40;&#41;&#41;;
                
                        &#125;
                
                        return form;
                
                    &#125;

                Comment


                • #9
                  Originally posted by futang
                  jominor,

                  could you expand on what's happening? I haven't used this feature and was operating based on the javadoc. After reading your last post I checked the source (CVS HEAD) and it looks like the ActionServlet should be set before processing occurs. The following is from FormBeanConfig and is called to create the ActionForm instance.
                  I'm afraid I misspoke. It wasn't that setServlet wasn't called, I just need(or at least want) the context at form creation time. Ultimately, I want my bean created after the form is created, but before someone would do something with the form.

                  The XmlBeanFactory does work in the constructor, but I want to make sure that I wasn't overlooking anything. Ultimately, what I'm doing is the results of taking advantage of Spring. Pre-Spring, I still had data objects that were used to hold data with form getter/setters passing data directly into this object. I also had the DataValidator and other stuff I mentioned in a previous post. My goal is Struts decoupling and reuse of both valueobject and validation in presentation and middle-tiers. This is a goal I've pretty much realized, but Spring influences have made me realized that with some small refactoring, I can take advantage of Spring to handle creating some of the things, I was doing by hand.


                  I'm pleased with the results, but it seems that the beanfactory will give me the results I desire.

                  Comment


                  • #10
                    jominor,

                    1. If you want to access Spring Context from within your Struts Actions please, take a look at org.springframework.web.struts.ActionSupport and org.springframework.web.struts.DispatchActionSuppo rt.
                    All you need to do, is make your Struts Action/DispatchAction extend Spring classes respectively instead of Struts' one. To extract beans form your Context, you can use:
                    Code:
                      getWebApplicationContext&#40;&#41;.getBean&#40;"beanName"&#41;;
                    2. As for accessing Spring Context from within your Struts ActionForms, Spring provides no support for that, but you can implement it yourself (some copy/past from Spring ActionSupport.java). Spring Implementation for Struts Actions Support is (as usually) very clean. Just stick to it, and it will reponses 100% to the needs you expressed in this thread.

                    3. Using ActionSupport, DispatchActionSupport (and perhaps ActionFormSupport / ValidatorFormSupport :wink to access the ApplicationConext is far more cleaner and performant than going the hard way with XMLBeanFactory.

                    Please let me know if you need more help to create ActionFormSupport / ValidatorFormSupport.

                    Comment


                    • #11
                      irbouho,

                      Now I'm on the same page with you. Just defer you initilization from the constructor of your action form to the setServlet method. As you can see from the code I previously posted, no interaction occurs with the action form between instantiation and the call to setServlet.

                      Mike

                      Comment


                      • #12
                        Originally posted by futang
                        irbouho,

                        Now I'm on the same page with you. Just defer you initilization from the constructor of your action form to the setServlet method. As you can see from the code I previously posted, no interaction occurs with the action form between instantiation and the call to setServlet.

                        Mike
                        I actually tried that after seeing the code and it actually work for the reason you mentioned. My only issue probably may just be one of semantics. With the Action, setting the webAppContext seems(IMO anyway) natural and intuitive. But for the form doing this AND initializing that data object seems...weird. Plus, I've got a minor concern about that particular assumption changing.

                        Other than my particular usage, the setServlet does work as adverstised for anyone else who is wondering. Thanks for the post.

                        Comment

                        Working...
                        X