struts-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Michael Jouravlev" <jmi...@gmail.com>
Subject Re: formbean of double type value chages when submitting the form
Date Fri, 24 Mar 2006 17:32:39 GMT
On 3/24/06, fea jabi <zyxrm@hotmail.com> 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: user-unsubscribe@struts.apache.org
For additional commands, e-mail: user-help@struts.apache.org


Mime
View raw message