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]