Introducing java in jails, alpha

Dead simple (and pretty) form creation, client and server side validation, and request parameter to object mapping. No configuration required.

Here's how it works:

Create your model classes

Create your model using the javax.validation validation Annotations (JSR 303).

public class AccountForm {
    @NotBlank(groups = RequiredChecks.class)
    @Size(min = 2, max = 25)
    private String name;
...
}

(See below for actual classes)

Create a form

Use the jails taglib to present your form, make sure input names match your model fields names.

<%@ taglib uri="http://org.jails.org/form/taglib" prefix="s" %>
<s:form name="accountForm" action="/jails-demo/jails" label="Your Account Details" style="side">
    <s:text name="name" label="Name" size="25" />
    <s:text name="accountName" label="Account Name" size="15" />
    <s:password name="password" label="Password" size="25" />
    <s:password name="confirmPassword" label="Confirm Password" size="25" />
    <s:text name="creditCardNumber" label="Credit Card" size="20" />
    <s:text name="address.street" label="Street" size="50" />
    <s:text name="address.city" label="City" size="25" />
    <s:state_select name="address.state" label="Street" />
    <s:text name="address.zip" label="Zip" size="25" />
    <s:country_select name="address.country" label="Country" />
    <s:text name="balance" label="Limit" size="25" />
    <s:text name="age" label="Age" size="5" />
    <s:date_select name="birthday" label="Birthday" format="@MM-dd-yyyy"/>
    <s:submit label="Submit" />
</s:form>

Now validate it!

public class SimpleFormServlet extends HttpServlet {
    @Override
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        SimpleValidator validator = new SimpleValidator();

        if ("Submit".equals(request.getParameter("submit"))) {
            Map<String, List<String>> errors = validator.validate(AccountForm.class, request.getParameterMap());

            if (errors != null) {
                AccountForm account = validator.getMapper().toObject(AccountForm.class, request.getParameterMap());
                //do something with valid account
            } else {
                SimpleForm.validateAs(AccountForm.class).inRequest(request).setErrors(errors);
                //handle error
            }
        } else {
            SimpleForm.validateAs(AccountForm.class).inRequest(request);
            //forward to formPage
        }
    }
}

Client side validation

Server side validation

For more detailed documentation, check out the using jails page or read the javadocs.

Model

Below are the model classes.

@FieldMatch(field = "password", matchField = "confirmPassword", message = "Passwords must match.")
@AcceptsNestedAttributes
public class AccountForm {
    @NotBlank(groups = RequiredChecks.class)
    @Size(min = 2, max = 25)
    private String name;

    @NotBlank(groups = RequiredChecks.class)
    @Pattern(regexp = "[0-9a-zA-Z]*", message = "may only contain letters and numbers.")
    private String accountName;

    @NotBlank(groups = RequiredChecks.class)
    @StrongPassword
    private String password;

    @NotBlank(groups = RequiredChecks.class)
    @StrongPassword
    private String confirmPassword;

    @NotNull
    @Valid
    private AddressForm address;

    @NotBlank(groups = RequiredChecks.class)
    @CreditCardNumber
    private String creditCardNumber;

    @NotNull(groups = RequiredChecks.class)
    @DecimalMin(value = "1000.00")
    @DecimalMax(value = "7000.00")
    private Double balance;

    @Max(value = 123)
    @Min(value = 18)
    private Integer age;

    @Past
    private Date birthday;

    public AccountForm() {}

    public AccountForm(String name, String accountName, String password,
                       String creditCardNumber, Double balance, Integer age, Date birthday) {
        this.name = name;
        this.accountName = accountName;
        this.password = password;
        this.creditCardNumber = creditCardNumber;
        this.balance = balance;
        this.age = age;
        this.birthday = birthday;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAccountName() {
        return accountName;
    }

    public void setAccountName(String accountName) {
        this.accountName = accountName;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getConfirmPassword() {
        return confirmPassword;
    }

    public void setConfirmPassword(String confirmPassword) {
        this.confirmPassword = confirmPassword;
    }

    public AddressForm getAddress() {
        return address;
    }

    public void setAddress(AddressForm address) {
        this.address = address;
    }

    public String getCreditCardNumber() {
        return creditCardNumber;
    }

    public void setCreditCardNumber(String creditCardNumber) {
        this.creditCardNumber = creditCardNumber;
    }

    public Double getBalance() {
        return balance;
    }

    public void setBalance(Double balance) {
        this.balance = balance;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }
}

public class AddressForm {
    @NotBlank(groups = RequiredChecks.class)
    @Size(min = 2, max = 125)
    private String street;
    private String apt;

    @NotBlank(groups = RequiredChecks.class)
    @Size(min = 2, max = 75)
    private String city;

    @NotBlank(groups = RequiredChecks.class)
    @Size(min = 2, max = 2)
    private String state;

    @NotBlank(groups = RequiredChecks.class)
    @Size(min = 5, max = 15)
    private String zip;

    @NotBlank(groups = RequiredChecks.class)
    @Size(min = 2, max = 2)
    private String country;

    public AddressForm() {}

    public AddressForm(String street, String city, String state, String zip, String country) {
        this.street = street;
        this.city = city;
        this.state = state;
        this.zip = zip;
        this.country = country;
    }

    public String getStreet() {
        return street;
    }

    public void setStreet(String street) {
        this.street = street;
    }

    public String getApt() {
        return apt;
    }

    public void setApt(String apt) {
        this.apt = apt;
    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

    public String getState() {
        return state;
    }

    public void setState(String state) {
        this.state = state;
    }

    public String getZip() {
        return zip;
    }

    public void setZip(String zip) {
        this.zip = zip;
    }

    public String getCountry() {
        return country;
    }

    public void setCountry(String country) {
        this.country = country;
    }
}