Am 17.12.2001, 18:09:29, schrieb "Craig R. McClanahan"
<[EMAIL PROTECTED]> zum Thema Re: ActionServlet behavior:

> On Mon, 17 Dec 2001, Johann Herunter wrote:

> > When having more FormBeans on the same jsp-page and you change the
> > value of one form bean, the values of the other change too or will be
> > reset. I need the behavior that when the value of one form bean is
> > changed, the other must remain unchanged. For this purpose i changed
> > the source-code of the ActionServlet so that it is now able
> >

> If you use session-scoped beans, the state of the forms you didn't submit
> is maintained -- but only as of the last time that form *was* submitted.
> Any changes you make on the client in one form are still not sent when
you
> update another -- thanks to the way HTML forms work.

> I would be interested in seeing exactly what changes you made to deal
with
> this -- if the changes are consistent with the Struts design philosophy
> for web apps, I'd be interested in including this in the standard packge.

This is exactly the behaviour we intended to change. Our idea was that
there
might be several different FormBeans being displayed into one component
on a
single page (eg. AddressBookEntryFB and MailFB) and that a user might
change
entries within fields belonging to either FormBean at once, before
submitting one or the other.

To maintain those changes we thought about a new Tag, which might go
together with the html:form tag, and which would span a single html form
around the entire page, and have the html:form bean leave out the form
tags.

We developed a multiform tag, that stores a Constants variable in the
pageContext, which is called in the FormTag and causes it not to print 
out the form tags if it is set.

The rest of the work is done by the FormTag class.

We changed the ActionServlet in the following ways:

After the „ActionForm formInstance = „ line, we inserted the following
lines of code:

This works fine with a get request,

java.util.Vector formBeans = this.getBeansForRequest(request);
// if there were any form beans request via special formtag-names,
// they are processed at this place
if(formBeans.size() > 0) {
    this.processMultiformPageRequest(request, mapping, formBeans,
          formInstance.toString());
}

Then we inserted the following three Methods after the „process(...“
Method, which
are responsible for our tasks:

/**
* Processes the request in a matter that if the values of
* form bean change, the values of the other ones being still
* the same.
*
* @param request - The Servlet request
* @param mapping - The mapping
*
*/
private void processMultiformPageRequest(HttpServletRequest request,
    ActionMapping mapping, java.util.Vector formBeans,
        String formBeanInstance) {

    for(int j = 0; j < formBeans.size(); j++) {
        String formBean = (String) formBeans.get(j);
                        
          //gets the actual form bean
          ActionForm actionForm = getActionForm(request,formBean);
                        
          if(!(formBeanInstance.equals(actionForm.toString()))) {
              try {
                  //sets the values of this form, also, while the loop
                    //is running, the values of all form beans in the
                    //page
                    processPopulate(actionForm, mapping, request);
              } catch (javax.servlet.ServletException exc) {
                  log("populateException:"+exc, 1);
              }
        }
    }
}

/**
* Returns the class for the given formBean without needing a mapping
*
* @param request - The servlet request
* @param actualFormBean - The name of the form bean,
*                         not the class name!
*
* @return - return the right ActionForm for the request
*/
private ActionForm getActionForm(HttpServletRequest request,
    String actualFormBean) {

    // gets the session for the actual request
    HttpSession session = request.getSession();

    // gets the form instance based on the method parameter
    ActionForm instance = (ActionForm)
    session.getAttribute(actualFormBean);

    String className = null;
    //The bean, that is responsible for this form
    ActionFormBean formBean = findFormBean(actualFormBean);
    if (formBean != null) {
        className = formBean.getType();

          // if the form instance exists return it
          if ((instance != null) &&
              className.equals(instance.getClass().getName())) {
                return instance;
          }
          //else instantiate a new one
          try {
              instance = null;
                Class clazz = Class.forName(className);
                instance = (ActionForm) clazz.newInstance();
          } catch (ClassNotFoundException cnfe) {
              log("failure in Class.forName():"+cnfe, 1);
          } catch (InstantiationException ie) {
              log("cannot instantiate Exc.:"+ie, 1);
          } catch (IllegalAccessException iae) {
                log("access denied:"+iae, 1);   
          }
    }
    return instance;
}

/**
* Finds out the form beans, based on the given Request, and returns
* it in a Vector
*
*
* @param request - The servlet request with all parameters
*
* @return - The Vector with only the form bean names for the given
Request,
*           not the class names !
*/
private java.util.Vector getBeansForRequest(HttpServletRequest request) {
    // stores all form bean names based on the request
    java.util.Vector tmp = new java.util.Vector();
    // get all parameter names in the request
    java.util.Enumeration enum = request.getParameterNames();
    // contains all names unparsed
    java.util.Vector paramNames = new java.util.Vector();
    while(enum.hasMoreElements()) {
        paramNames.add(enum.nextElement());
    }

    //For now, we defined an own Syntax: property=“fb_myFormName_name“.

    for(int j = 0; j < paramNames.size(); j++) {
        String parameters = (String) paramNames.get(j);
        // if this name contains an underscore, it is a value that
        // contains a form bean
        if(parameters.indexOf("_") > 0) {
              String identification = parameters.substring(0,
                    parameters.indexOf("_"));
              // a form bean is actually identified by "fb",
              // may be changed in a future version
              if(identification.equals("fb")) {
                  String formBeanName = parameters.substring(
                        identification.length() +1, 
parameters.lastIndexOf("_")) ;
                  // if the form bean name is not existent in the
                  // vector, set it
                  if(!(tmp.contains(formBeanName))) {
                      tmp.add(formBeanName);
                  }
            }    
        }
    }
    // has all true needed request paramnames to give back
    return tmp;
}

------------------------------------------------------------------------
--------
Because the Actions of the different Buttons wouldn't work either, the
„processPath(...“ Method has been extended
so that it is now able to obtain the right action. This does NOT work 
with a post 
request.

The changes:

„return path(...“ has been changed by calling a new Method

// tm1 : change rherzig - for multiple buttons within one form to
//       match several action mappings method addSecondaryAction is
//       called
return (addSecondaryAction(request, path));

/**
* Add the value off the submit button that may have been pressed to the
* path, so that two buttons may be dispatched to two different actions
*
* Thus if the submit button name is submit (requirement for the secondary
* action to work, and the value is action1 then the action mapping
* that is used is normalActionNameOfForm.action1
*
* @param request The servlet request we are processing
* @param path the action path that has been extracted so far
*/
protected String addSecondaryAction(HttpServletRequest request,
    String path) {
    if (request.getParameter("submit") != null) {
        path = path + "." + request.getParameter("submit");
    }

    return path;
}

Sincerly

Johann Herunter - tm1


--
To unsubscribe, e-mail:   <mailto:[EMAIL PROTECTED]>
For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>

Reply via email to