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 } } }
For more detailed documentation, check out the using jails page or read the javadocs.
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; } }