A project of The Apache Software Foundation
Navigation

How to validate forms with annotations like @NotNull

Learn how to use Jakarta Bean Validation (JSR 303) annotations on your domain objects and have Wicket enforce them automatically

Standard JSR 303 defines a set of annotations and APIs to validate our domain objects at field-level. Wicket has introduced an experimental support for this standard since version 6.4.0 and with version 6.14.0 it has become an official Wicket module (named wicket-bean-validation). In this paragraph we will see the basic steps needed to use JSR 303 validation in our Wicket application. Code snippets are from example project JSR303validation.

In the example application we have a form to insert the data for a new Person bean and its relative Address. The code for class Person is the following

public class Person implements Serializable{

    @NotNull
    private String name;

    //regular expression to validate an email address
    @Pattern(regexp = "^[_A-Za-z0-9-]+(.[_A-Za-z0-9-]+)*[A-Za-z0-9-]+(.[A-Za-z0-9-]+)*((.[A-Za-z]{2,}){1}$)")
    private String email;

    @Range(min = 18, max = 150)
    private int age;

    @Past @NotNull
    private Date birthDay;

    @NotNull
    private Address address;
}

You can note the JSR 303 annotations used in the code above to declare validation constraints on class fields. Class Address has the following code:

public class Address implements Serializable {

    @NotNull
    private String city;

    @NotNull
    private String street;

    @Pattern(regexp = "\\d+", message = "{address.invalidZipCode}")
    private String zipCode;
}

You might have noted that in class Address we have used annotation Pattern using also attribute message which contains the key of the bundle to use for validation message. Our custom bundle is contained inside HomePage.properties:

address.invalidZipCode=The inserted zip code is not valid.

To tell Wicket to use JSR 303, we must register bean validator on Application’s startup:

public class WicketApplication extends WebApplication {
    @Override
    public void init(){
        super.init();

        new BeanValidationConfiguration().configure(this);
    }
}

The last step to harness JSR 303 annotations is to add validator org.apache.wicket.bean.validation.PropertyValidator to our corresponding form components:

public HomePage(final PageParameters parameters) {
    super(parameters);

    setDefaultModel(new CompoundPropertyModel<Person>(new Person()));

    Form<Void> form = new Form<Void>("form");

    form.add(new TextField("name").add(new PropertyValidator()));
    form.add(new TextField("email").add(new PropertyValidator()));
    form.add(new TextField("age").add(new PropertyValidator()));
        //...
}

Now we can run our application and see that JSR 303 annotations are fully effective:

JSR 303 form validation