I am revisiting the internals of Struts after quite a while of not working 
with it. I'm working on a webapp that is currently still using Struts1.1, 
but it may be upgraded. My questions revolve around best practices and 
patterns for using the ActionForm to do what I really want. If any of this 
is solved in >1.1 versions of Struts, please let me know and I will check 
them out before digging too deep!

GOAL:
====
The webapp has many Javabeans representing the domain data structure. These 
beans are passed between layers. I would like my ActionForms to simply 
contain these beans for painting and populating forms, so there is no messy 
transformation stage to convert from ActionForm<-->Beans.
What is the best way to reuse an application's existing data bean structure 
for forms?

Consider an ActionForm/bean structure like this:
------------------------------------------------
ActionForm
 - ArrayList employees // holds Employee beans

Employee.java
 - Integer employeeId
 - String employeeName
 - ArrayList assignments // holding Assignment beans

Assignment.java
 - Integer assignmentId
 - String assignmentName
------------------------------------------------
(in reality, imagine a nested structure 5-10 levels deep and very complex)

Now imagine a web form which is adding, changing, and deleting details for a 
list of employees.
Having a structure like this would allow me to just grab the bean structure 
from my business layer, which was passed the bean structure from the model 
layer. My Action could just put the ArrayList of employees into the 
ActionForm and go!

This approach leads to a few problems:

1. Using nested properties, I can have form inputs named 
"employees[0].assignments[2].assignmentName" and the ActionForm will be 
correctly set the inner bean values - as long as the structure exists. I've 
seen the LazyBean solution - but is there anything wrong with just making 
getters() for the ArrayLists which create the objects as necessary? For 
example, in the ActionForm:
    public Employee getEmployees(int i) {
      if(employees == null) { employees = new ArrayList(); }
      while (i>=employees.size()) { employees.add(new Employee()); }
      return (Employee)employees.get(i);
    }

2. Fields such as Integer, which are objects rather than int specifically so 
they can be null, get set to a default value (example: 0) when the form 
field is empty. If I understand correctly, I need to register a Converter 
with BeanUtils so it behaves more rationally with this?

3. Invalid data trying to be set to an Integer field, for example, cannot be 
presented back to the user. It either needs to be a valid number or null. In 
my specific case, though, this is fine. If the user enters an invalid value, 
they can just see the empty field when the screen re-paints.

4. Conversion errors throw exceptions that I can't catch in my Action, since 
population happens before I have control. I can't keep a list of all fields 
with conversion problems, for example, in order to flag them on the screen.


One solution I imgagined to address these annoyances is to create a FormBean 
for every Bean in the application. The FormBeans would be identical in 
structure to the data beans, but contain only String fields. But this would 
lead to duplication of the entire domain data structure in two sets of 
beans - one for real data, and one for form data. And then after ActionForm 
population, the entire nested structure would need to convert itself to the 
real bean structure in order for the business layer to process it. And the 
real bean structure would need to be converted to the Form Bean structure to 
be populated into the ActionForm. Seems like a lot of extra work, especially 
considering a very complex and deep data structure in a big application.


What are the recommendations for dealing with ActionForms that contain or 
represent complex nested data structures, preferrably using JavaBeans that 
already exist within the application?

Thanks!

-- 
Matt Kruse
http://www.JavascriptToolbox.com
http://www.AjaxToolbox.com




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

Reply via email to