Tuesday, May 24, 2011

Binding Boolean properties in Spring MVC forms

While designing Spring MVC forms you might often encounter bind errors such as follows:

Failed to convert property value of type [java.lang.String] to required type [java.util.Date] for property 'updateStamp'; nested exception is java.lang.IllegalArgumentException:xxxxxx

Usually these errors are the result of Spring not being able to bind java primitive Wrapper classes like Integer, Boolean, etc. or user defined types such as Customer, to <form:input> or other form fields.

However, this issue can be resolved simply by registering custom property editors with your spring controller. Spring by defaults provides you with set of built-in property editors, that you can use in your controller. For user defined types, you must create your own.

As you know, Spring 3.x makes writing your controller a lot easier and here is how you register customer property editor within your controller:

In the example below, I've added built in property editors for Date, String, and Boolean.
    @InitBinder
    public void setPropertyBinder(WebDataBinder dataBinder) {
        SimpleDateFormat dateFormat = new SimpleDateFormat("MM-dd-yyyy");
        dateFormat.setLenient(false);
        dataBinder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, false));
        dataBinder.registerCustomEditor(String.class, new StringTrimmerEditor(true));
        dataBinder.registerCustomEditor(Boolean.class, new CustomBooleanEditor(false));
    }

One important note: In some cases specifically for Boolean properties you may encounter following error even after you have registered custom property editor for it.

org.springframework.beans.NotReadablePropertyException: Invalid property 'newCustomer' of bean class [org.sample.domain.customer.Customer]: Bean property 'newCustomer' is not readable or has an invalid getter method: Does the return type of the getter match the parameter type of the setter?

This error is coming from your Customer domain object. Most likely, newCustomer property is defined as follows:
public class Customer {
    private Boolean newCustomer;

    public Boolean getNewCustomer() {
        return newCustomer;
    }

    public void isNewCustomer(Boolean newCustomer) {
        this.newCustomer = newCustomer;
    }
   
}

If you change the method name from isNewCustomer() to getNewCustomer() the above mentioned error will disappear. This is because a standard java bean convention is to use set/get for property methods.

No comments:

Post a Comment