Announcement Announcement Module
No announcement yet.
Struts forms and validation with webflow Page Title Module
Move Remove Collapse
Conversation Detail Module
  • Filter
  • Time
  • Show
Clear All
new posts

  • Struts forms and validation with webflow

    I have numerous Struts forms with validation rules in both validation.xml and in in the validate method of the forms. I would like to reuse these forms and their validation with Web Flow. Is this possible? or do you need to use the binding of objects like in in the birthdate sample? If it is possible please can someone point me in the direction of documentation for configuring it or an example.


  • #2
    Hmmmm... I guess I see two options:

    - Use a generic BindingActionForm adapter, like BirthDate does, but have your existing ActionForms be managed by the Spring Web Flow FormAction as a POJO.

    So in that case I could see the "FormAction" being responsible for creating instances of your existing ActionForms you want to use in Spring Web Flows. Binding should work with no change, but you'll likely need to tweak the validate hooks in FormAction to invoke the proper validate method on your Struts action form classes, as by default it'll use a Spring validator if one is configured.

    - Keep your existing ActionForm definition as is, and reference it from your FlowAction definition in struts-config.xml, instead of using the generic "bindingActionForm".

    In that case your action code will need to pull your ActionForm form out of the request. Also, the RequestProcessor will do binding/validation instead of deferring that to the Web Flow system.

    The limitation with this approach is you'll need to define a single FlowAction def per flow (limited to a single form object per flow), where with the first approach you could still have a single FlowAction for the whole app (with perhaps multiple form objects in play over the life of the flow).

    Overall, I'd say currently web flow's Struts integration is most appropriate with Spring-powered data binding and validation, as Spring's solution is just more feature rich, so it's best for use in completely new code you want to write as flows. But I see no reason why we can't make it easier to adapt existing Struts code to the web flow system, particularly if there is a lot of demand for it.


    • #3
      In this case, I think the second option would be most suitable since I am trying to make use of Web Flow with minimum impact. There will be 2 workflows, both of which will be using the same form throughout, and in many states using the same JSPs (which I also hope will be largely unchanged apart from state tracking fields).

      I am however a little unsure on how to configure this. If I have a form, myForm which extends the Struts ValidatorForm, and an action defined as:
      <action path="/MyWorkflow"
              name="myForm" scope="request" 
              <set-property property="flowId" value="workflow" />
      Do I still need to define the following?
      <controller processorClass="org.springframework.web.struts.BindingRequestProcessor"/> 
      <plug-in className="org.springframework.web.struts.BindingPlugin"/>


      • #4
        No, you don't need it -- if you don't use a BindingActionForm, the BindingRequestProcessor will act just like the standard RequestProcessor. It only acts differently for BindingActionForm, defining form binding and validation. It shouldn't hurt to leave it in though.

        I'm considering adding a StrutsEvent subclass of HttpServletRequestEvent that makes it easier to get the ActionForm for the current request. In that case, to get it in your actions, you can just do this:


        • #5
          Would anything need to be added to the JSPs if I was to follow this approach? or would the be left intact? (Asking because the struts sample uses the spring:bind tag). The JSPs and validation (using struts forms) are my biggest concern since I use a custom library to generate the forms, validation rules and JSPs from a single xml file, and changing the library is unfortunately not an option.

          The addition of a StrutsEvent would certainly simplify things.


          • #6
            No, you should be able to work with your custom tag lib or struts tags with no problems. Birthdate really shouldn't be using spring:bind--I'll change it to be a full struts solution in the JSPs.

            I just committed a StrutsEvent, providing access to the ActionForm and ActionMapping (in addition to all the HttpServletRequestEvent stuff.)


            • #7
              I've just updated BirthDate to be a complete struts solution from the JSP point of view, using the standard struts html tags. It still uses Spring's data binding and validation infrastructure with a BindingActionForm adapter, but it should be easily possibly now to obtain handles to your own ActionForm instances using the StrutsEvent class like:

              RequestContext context = ...
              ActionForm myActionForm = &#40;&#40;StrutsEvent&#41;context.getOriginatingEvent&#40;&#41;&#41;.getActionForm&#40;&#41;;
              We'll release PR3 next week to officialy include these fixes and enhancements, but feel free to try in CVS now. In fact, I'd encourage that--we could use the feedback before PR3.




              • #8
                Thanks for the help.

                I will hopefully get some time this afternoon to try out the code from CVS.



                • #9
                  I could well have missed something, but is the following really required in my code? Is there a way to get the normal struts validation to work for action states?
                   StrutsEvent strutsEvent = &#40;StrutsEvent&#41;context.getOriginatingEvent&#40;&#41;;
                          MyForm form = &#40;MyForm&#41;strutsEvent.getActionForm&#40;&#41;;
                          ActionMessages errors = form.validate&#40;strutsEvent.getActionMapping&#40;&#41;,strutsEvent.getRequest&#40;&#41;&#41;;
                              return error&#40;&#41;;
                          return success&#40;&#41;;
                  The action mapping which is a flow action has the validate attribute set to false, since having it true requires an input attribute to be specified. This would be fine if it was at the start of the flow, but the validation is required half way through, so the input is no longer correct.


                  • #10
                    Well, not sure what to say, I guess that's just problamatic with Struts -- as there is one ActionMapping per Action, and only one FlowAction per flow (where a flow has multiple states, any of which might trigger validation.) I don't think you can rely on a flag in the ActionMapping to detrmine whether validation should be performed...


                    • #11
                      I agree that the validate flag cannot be relied upon while using web flow. What I was trying to ask is whether or not the struts style validation could be performed automatically for a state in the flow? As in, specified in the flow definition.

                      What I have just now works, it is only required for a single state, but it would be nice if it the validation could be performed automatically.


                      • #12
                        What do you mean automatically? You could encapsulate the validate logic in a StrutsFormAction or something, and reuse that in whatever states you like.


                        • #13
                          Thanks for all your help

                          I've gone for the option of creating encapsulating the code I posted previously into a method which any of the other states can use.


                          • #14


                            I have a form bean in a JSP which uses the html:select tag. i need to use this form bean in a table such that i can display the data in the form bean row by row wise. Actually i am having an array list in the form bean, i need to use that arraylist in the table. Kindly help me in solving this issue.

                            I am unable to get the form instance for this. Pls send me the relevant code for this.

                            Thanx in advance.

                            Phani Kumar