Tag Archives: spring

Date fields in forms using Spring and AppFuse

I had some problems getting date fields to work (and return a friendly error message) so here comes a little documentation for future reference. This was in an AppFuse based Spring Framework project.

The model contains a java.util.Date property and simply exposing it as usual in a form will cause an exception since Spring doesn’t know how to convert the string into a Date:

Failed to convert property value of type [java.lang.String] to required type [java.util.Date] for property startTime; nested exception is java.lang.IllegalArgumentException: Cannot convert value of type [java.lang.String] to required type [java.util.Date] for property startTime: no matching editors or conversion strategy found

To solve this we need a custom property editor. It may be registered by overriding the initBinder() method of a controller. Spring already contains a CustomDateEditor that we may use for this purpose.

protected void initBinder(HttpServletRequest request, 
                          ServletRequestDataBinder binder) {
    SimpleDateFormat dateFormat =
        new SimpleDateFormat(getText("date.format", request.getLocale()));
    binder.registerCustomEditor(Date.class, null, new CustomDateEditor(dateFormat, true));

Note that you may replace the getText() call with a hard-coded “yyyy-MM-dd” or similar, at least for debugging purposes.

If it is an AppFuse project and the controller extends BaseFormController then you don’t need this since the CustomDateEditor is already registered in the BaseFormController.initBinder() method.

Now it should work, however, the error message isn’t especially user-friendly when entering an invalid date:

Failed to convert property value of type [java.lang.String] to required type [java.util.Date] for property startTime; nested exception is java.lang.IllegalArgumentException: Could not parse date: Unparseable date: “2008-37-09”

Better error messages may be provided using the resource file of the application (make sure you have a ResourceBundleMessageSource set up) by specifying typeMismatch error message for this type:

typeMismatch.java.util.Date={0} is an invalid date.

The {0} will be replaced by the property name, in this case startTime, which may not be desired. This may be overridden by setting a custom error message for this specific property:

typeMismatch.startTime=Start time is an invalid date.

Do also make sure to update validation.xml accordingly.

I18n workaround for Spring form:options tag

Spring Framework provides the convenient form:options tag to render a list of <option> tags for a form <select>. Here is an example:

<form:select id="status" path="status" cssClass="text large" cssErrorClass="text large error" >
    <form:options items="${statusList}" itemValue="id" itemLabel="label"></form:options>

It does iteratate through statusList and will output each item as an option with the value statusList[i].id and the text statusList[i].label and automatically make the option corresponding to status selected.

Unfortunately form:options does not support i18n (internationalization), which make it in some cases rather worthless. I18n support is currently scheduled for inclusion in 3.0 M1.

To support internationalization we have to do a workaround that is somewhat more clunky:

<select id="status" name="status" class="text large">
  <c:set var="currentStatus">${currentStatus}</c:set>
  <c:forEach var="status" items="${statusList}">
      <c:when test="${status == currentStatus}">
        <option value="${status.id}" selected><fmt:message key="status.${status.label}"/></option>
        <option value="${status.id}"><fmt:message key="status.${status.label} quot;/></option>