This is a basic 1,2,3 guide that anyone can expand upon when they have something useful to add:\

        <!-- sets up Validator -->
        <plug-in className="org.apache.struts.validator.ValidatorPlugIn">
          <set-property 
            property="pathnames" 
            value="/WEB-INF/validator-rules.xml,/WEB-INF/validation.xml"/>
        </plug-in>
        <form-bean name="surveyForm"
          type="com.mystuff.myapp.myForm">
        </form-bean>
        <form-bean name="surveyForm"
          type="org.apache.struts.validator.DynaValidatorForm">
          <form-property name="surveyForm"
            type="java.lang.String"/>
          <form-property name="title"
            type="java.lang.String"/>
        </form-bean>
        <action path="/private/esurvey/survey/update"
          type="org.gargantus.esurvey.SurveyAction"
          name="surveyForm"
          scope="request"
          validate="true"
          parameter="save"
          input="/private/esurvey/survey/validate/failed.do"
          roles="user">
          <set-property property="secure" value="true"/>
          <forward name="failed" path=".survey"/>
          <forward name="display" path=".survey"/>
          <forward name="finished"   
            path="/private/esurvey/survey/list.do" 
            redirect="true"/>
        </action>
    <form-validation>
      <formset>        
        <form name="surveyForm">
          <field property="surveyId"
            depends="required,integer">
            <arg0 key="esurvey.survey.validate.id"/>
          </field>
          <field property="dateLive"
            depends="date">
            <arg0 key="esurvey.survey.validate.dateLive"/>
            <var>
              <var-name>datePattern</var-name>
              <var-value>yyyy-MM-dd</var-value>
            </var>
          </field>
        </form>
      </formset>
    </form-validation>
      <%@ taglib prefix="html" uri="http://jakarta.apache.org/struts/tags-html" %>
      <html:form action="/private/esurvey/survey/update"
        focus="optionText">
          <html:form action="/private/esurvey/survey/update" >
            focus="optionText"
            onsubmit="return validateForm(this);">
          <html:javascript formName="surveyForm" 
            method="validateForm"
            dynamicJavascript="true"
            staticJavascript="false" 
            cdata="false" />
      <script src="<html:rewrite page="/staticjavascript.do"/>" 
        type="text/javascript"></script>
      <html:messages id="validatorMsgs" 
                message="false" 
                 header="errors.header"
                 footer="errors.footer">
        <p>
          <c:out default="default text for &lt;c:out&gt; error in validatorMsgs" 
                 value="${validatorMsgs}" 
             escapeXml="false"/>
        </p>
      </html:messages>

And finally, this is how struts actually deals with it all on submission of a form:

  1. It goes and checks for any instances of the form-bean in the scope (the name of the class, type, and scope is specified by the action mapping in struts-config.xml).
  2. If found then call the form's reset method is called.
  3. If not found than a new instance is created and stored in the proper scope.
  4. Then the formBean is populated with request parameters by struts
  5. If the validate is true than the form's validate() method is called. There's no need to call it explicitly and because of ValidatorForm doing all the validation automatically, all that is required for code is a call in your form's submit() method to super.validate(). If you are using DynaValidatorForm, then you will not have program any form beans at all.
    1. if validate() returns any errors, then struts forwards the request to the URL specified in the input attribute of the action mapping.
    2. otherwise it checks for the action which the action mapping is based on.

Then after that you have a populated form. Normally you would then transfer the data into a value or data-transfer object to pass to your business layer (see BeanUtils.copyProperties).