On 3/24/06, fea jabi <[EMAIL PROTECTED]> wrote: > BeanUtils.copyProperties(myBusinessBean,form)) is copying DynaValidatorForm > String values to the myBusinessBean which is having the right data types. > > But in validator.xml, I am validating the DynaValidatorForm properties to > check if user is entering the right value i.e Double. which is wrong. > > I think I am missing something here. > > Please, explain. thanks.
Well, cannot tell you much about Validator because I don't use it. Struts has serious issues with input data type conversion, it is probably its weakest point. I prefer things simpler for me, I also do not like to make conversion/validation twice, and I like to have it in a business object in case input comes from somewhere else than browser+Struts. So, here is just a possible way to work with typed properties, that is, non-String properties. I have business, object, say Employee, that I store in an ActionForm as a nested property. Let's say that Employee has Name and Department, and just for the sake of this example Department must be integer. The same Employee object stores error messages, that are generated during type conversion or business-rule validation. When I submit a form, Struts sets nested properties, it passes stringified value, that is converted inside the business object. If conversion was ok, then business rule is checked next. If conversion failed, business rule is not checked. Errors are accumulated in the business object, then my action class reads these errors and takes a decision wheter to save the object or to redisplay the form, using the errors from the object. So, here is how it looks in the code: /* * Department for employee, must be an integer. */ public SmartProperty dept = new SmartProperty() { boolean typeValid; Integer intDept; String strDept; public Object getValue() { if (typeValid) return intDept; else return strDept; } public void setValue(Object value) { typeValid = true; String conversionError = null; // Convert and validate if (value != null) { if (value instanceof Integer) { intDept = (Integer) value; } else if (value instanceof Double) { intDept = new Integer(((Double)value).intValue()); } else { strDept = (String) value; try { intDept = Integer.valueOf( (String) value); } catch (NumberFormatException nfe) { typeValid = false; conversionError = "crudData.deptisnotanumber"; } } } // If conversion failed, use conversion error message if (conversionError != null) { errors.put(conversionError, null); // If conversion was successful, check business rules } else { validate(); } } public void validate() { if (intDept == null || intDept.intValue() < 100) { errors.put("crudData.alldeptsstartfrom100", null); } } }; public Object getDept() {return dept.getValue();} public void setDept(Object value) {this.dept.setValue(value);} /** * Having properties in an array simplifies validation */ SmartProperty[] smartProperties = new SmartProperty[] {name, dept}; /** * Validates business rules (conversion validation is performed * when fields are populated). It is up to the caller to clear * errors before validating business object. * * @return non-empty map containing error objects if some of the business * rules are not met. */ public Map validate() { for (int i = 0; i < smartProperties.length; i++) { smartProperties[i].validate(); } return errors; } I know this is a lot of code for one property, but this way the conversion/validation happens only once, and all rules are in my Model. This way I can switch to a new framework if needed, without caring for ActionForm or for Validator. Michael. --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]