You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@struts.apache.org by "Hohlen, John" <JH...@erac.com> on 2002/10/01 17:44:34 UTC

QUESTION: Automatic Data Transfer To/From DynaActionForms

Here's a question regarding the transfer of data from a DynaActionForm to a
Value Object using the copyProperties() method in the
org.apache.commons.beanutils.PropertyUtils class:

My team just started experimenting with DynaActionForms.  Until now, we've
been using standard action forms (i.e. manually coded).  Wherever possible,
we're using Value Objects with matching property names.  This allows us to
use the "copyProperties" method to transfer user input data between the two
objects without writing special adapter code.  

Our basic approach was that all property fields in an ActionForm class would
be declared as strings -- as recommended with DynaForms.  Therefore, a
property always has a SETTER method that takes a string input.  However, a
property name in an ActionForm class would always end with the suffix
"String" (or "StringList" for an array list) if the string type is not its
real-world data type (e.g. a property representing a salary amount where
double would be the real-world type).  Otherwise, the property would not
have the "String" suffix in it's name (e.g. a property representing a last
name where String would be the real-world type).

However, if the property name does end with "String (again, indicating
String is not its real-world type), then there are two getters and two
setters.  More specifically, there is a string pair, and a real-world data
type pair.  As expected, the string pair deals exclusively with String data
types.  These methods are used by Struts and the JSPs.  Conversely, the
real-world data type pair deals exclusively with the real-world data types.
The getter method throws some type of StringFormatException since it tries
to convert a value from String to its real-world data type.  The real-world
data type methods are used to automatically copy data to/from value objects
via the "copyProperties" method.  Our Value Object always refer to the data
as their real-world type and not Strings (unless String is the real-world
type).

The code example below should make what I tried to say about our ActionForm
naming conventions, in the words above, easier to understand:
 
public class employeeForm extends ActionForm {
  private String lastName = null;
  private String salaryString = null;
 
  // Last name getter / setter
  public String setLastName(String lastName) {
    this.lastName = lastName;
  }
  public Sting getLastName() {
    return lastName;
  }
  
  // Salary getters / setters 
  public void setSalaryString(String salaryString) {
    this.salaryString = salaryString;
  }
  public String getSalaryString() {
    return salaryString;
  }
  public void setSalary(double salary) { // does not throw exception
    salaryString = StringFormat.numberToString(salary, 2); // two decimal
places
  }  
  public double getSalary() throws StringFormatException {
    return StringFormat.stringToFloat(salaryString);
  }

}

Here's the benefit.  This approach allows us to copy all the values to/from
the form bean to a corresponding value object in one line of code.  For
example,

PropertyUtils.copyProperties(employeeValueObject, employeeForm);

FYI, the EmployeeValueObject is declared as:
 
public class EmployeeValueObject {
  private String lastName = null;
  private double salary = 0.0;
 
  // Last name getter / setters
  public String setLastName(String lastName) {
    this.lastName = lastName;
  }
  public Sting getLastName() {
    return lastName;
  }
  
  public void setSalary(double salary) {
    this.salary = salary
  }  
  public double getSalary() {
    return salary;
  }

}

Now, if you've hung here for this long, I appreciate it.  We're getting to
the heart of my question.  If I use DynaActionForms, I lose the ability to
use the copyProperties method in this situation because there is no getter
method in the Employee "Dyna" Form which returns a double primitive.
Hence, I have to write additional adapter code to stuff the value into my
Value Object.  Therefore, by using DynaActionForms, I reduce the ActionForm
code that I have to write, but increase the adapter code that I have to
write.  Right?

What are others doing here?  Would it make sense to enhance the
DynaActionForm class to generate getter/setter methods for real-world  types
if there real-world data type is not String.  More specifically, there would
always be String methods for each property, but if the "form-property" is
not specified as String the struts-config.xml file, an additional setter and
getter method for the real-world data type would also generated.

By the way, the reason for using the "String" suffix in the String methods
corrresponding to non-string properties (i.e. real-world) is that you cannot
overload methods differing only by return type. 

Thanks for reading this.  Please let me know if there is a better way to do
this.  Obviously, I'm trying to keep the amount of code we have to write to
minimum and take advantage of the Struts framework will automatically do for
us.

JOHN





 

--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: QUESTION: Automatic Data Transfer To/From DynaActionForms

Posted by "Craig R. McClanahan" <cr...@apache.org>.

On Tue, 1 Oct 2002, Hohlen, John wrote:

>
> Now, if you've hung here for this long, I appreciate it.  We're getting to
> the heart of my question.  If I use DynaActionForms, I lose the ability to
> use the copyProperties method in this situation because there is no getter
> method in the Employee "Dyna" Form which returns a double primitive.
> Hence, I have to write additional adapter code to stuff the value into my
> Value Object.  Therefore, by using DynaActionForms, I reduce the ActionForm
> code that I have to write, but increase the adapter code that I have to
> write.  Right?

The logic in PropertyUtils and BeanUtils has special functionality that
treats DynaBeans (and therefore DynaActionForms) like regular JavaBeans.
For copyProperties(), a DynaBean can be the source, the destination, or
both, or neither.

You should also check out BeanUtils.copyProperties() that does conversions
as part of its processing.  Of course, this is only helpful when you use
the same property names in the form bean and in the value object -- for
example:


    public class CustomerFormBean extends ActionForm {
        ...
        public String getStartDate();
        public void setStartDate(String startDate);
        ...
    }


    public class CustomerValueObject {
        ...
        public Date getStartDate();
        public void setStartDate(Date startDate);
        ...
    }

Then, you can copy the properties (including the automatic date
conversion of the "startDate" property) like this:


    CustomerFormBean cfb = ...;
    CustomerValueObject cvo = ...;
    BeanUtils.copyProperties(cvo, cfb);


Craig


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>