February 20th, 2010

I’ve spent most of the last few days migrating an old perl cgi form to Java.  We’ve decided to host all our forms on Tomcat (the bulk are already there) and there were a couple of support tickets outstanding for this old perl form that made it worthwhile switching now.  Now I’m getting to grips with Spring 3.0 annotations it makes simple forms very easy indeed.  We’re using it in combination with Hibernate’s javax.validation (JSR 303) implementation which simplifies things even further.  For example to bind and validate a simple bean with one mandatory string property:


public class MyBean {
    @org.hibernate.validator.constraints.NotEmpty
    @javax.validation.constraints.Size(max = 100)
    private String myProperty;
        // ... also need getters and setters ...
    }
}

import org.springframework.stereotype.Controller
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RequestMethod;

@Controller
@RequestMapping("/my-form")
public class MyFormController {
    // also need view methods

    @RequestMapping(method=RequestMethod.POST)
    public String handleSubmit(@javax.validation.Valid MyBean myBean, BindingResult result) {
         if (result.hasErrors()) {
             return null; // this just shows the form again
         }
         // ... do something with myBean ...
         return "success-page";
    }
}

Spring also ships with a form tag library that facilitates binding your bean to HTML form controls. This is all great and an improvement from Spring 2.0 but I’m greedy.  I want more.

Integrate Spring form tag library with javax.validation meta data

The Hibernate validation implementation provides the javax.validation annotations plus a few useful additions.  In short we can specify things like:

  • @NotEmpty to specify that a String field is required
  • @NotNull to specify that basic type properties are required
  • @Size(min =y, max = x) to specify a String field should be a maximum of  x characters and minimum of y characters; also to specify maximum and minimum values of numeric fields
  • @Email to specify a String field is an email address

In HTML form controls it is common to:

  • Add a class to form controls that are required
  • Add a maxlength attribute to input controls to specify maximum length

Wouldn’t it be great if the Spring form tag library could inspect the validator and supplement the HTML as appropriate.  It could do some things automatically and with a few more attributes you could achieve a lot.  In particular I’m thinking a cssRequiredClass on label, input, select etc would be useful but it could simply add a class of “required” by default.

This would mean jsp code like:

<form:form command="myBean">
    <form:label path="myProperty" label="My Property"/>
    <form:input path="myProperty"/>
</form:form>

would render as:

<form method="post">
    <label for="myProperty" class="required">My Property</label>
    <input id="myProperty" name="myProperty"  class="required" maxlength="100"/>
</form>

HTML 5

If you start thinking about HTML 5 then the possibilities really broaden.  You now have:

  • A required attribute to specify controls are required
  • type attribute to specify type (e.g. number, email etc)
  • max and min attributes to specify maximum and minimum values

I don’t think you could add integration of these features by default as we’re a long way from HTML 5 browsers being mainstream (IE 6 numbers are still stuck at 15%!).