Get a new form
Export a JavaBean to the view as the “form bean” or “form backing object”
Can pre-populate form using initial bean property values or client query parameters
Convenient form tags/macros exist to simplify rendering form fields
1. Invoked on every request
@ModelAttribute
public void ajaxAttribute(WebRequest request, Model model) {
model.addAttribute("ajaxRequest", AjaxUtils.isAjaxRequest(request));
}
2. Invoked initially to create the "form" attribute
@ModelAttribute("formBean")
public FormBean createFormBean() {
return new FormBean();
}
@RequestMapping(method=RequestMethod.GET)
public void form() {
}
Post a form
Declare JavaBean argument to trigger binding and validation
Declare a BindingResult argument to query binding and validation results
Re-render form view if validation errors are present
Redirect after successful post by returning target resource URL prefixed with special “redirect:” directive
Store any success messages in a flash map cleared after the next request: Flash map contents are cached temporarily in the session until the next request
completes, then cleared
@RequestMapping(method=RequestMethod.POST)
public String processSubmit(@Valid FormBean formBean, BindingResult result,
@ModelAttribute("ajaxRequest") boolean ajaxRequest,
Model model, RedirectAttributes redirectAttrs) {
if (result.hasErrors()) {
return null;
}
// Typically you would save to a db and clear the "form" attribute from the session
// via SessionStatus.setCompleted(). For the demo we leave it in the session.
String message = "Form submitted successfully. Bound " + formBean;
// Success response handling
if (ajaxRequest) {
// prepare model for rendering success message in this request
model.addAttribute("message", message);
return null;
} else {
// store a success message for rendering on the next request after redirect
// redirect back to the form to render the success message along with newly bound values
redirectAttrs.addFlashAttribute("message", message);
return "redirect:/form";
}
}
FormBean.java
import java.math.BigDecimal;
import java.util.Date;
import java.util.Map;
import javax.validation.constraints.Min;
import javax.validation.constraints.Past;
import org.hibernate.validator.constraints.NotEmpty;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.format.annotation.NumberFormat;
import org.springframework.format.annotation.DateTimeFormat.ISO;
import org.springframework.format.annotation.NumberFormat.Style;
import org.springframework.samples.mvc.convert.MaskFormat;
public class FormBean {
@NotEmpty
private String name;
@Min(21)
private int age;
@DateTimeFormat(iso=ISO.DATE)
@Past
private Date birthDate;
@MaskFormat("(###) ###-####")
private String phone;
@NumberFormat(pattern="$###,###.00")
private BigDecimal currency;
@NumberFormat(style=Style.PERCENT)
private BigDecimal percent;
private InquiryType inquiry;
private String inquiryDetails;
private boolean subscribeNewsletter;
private Map<String, String> additionalInfo;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Date getBirthDate() {
return birthDate;
}
public void setBirthDate(Date birthDate) {
this.birthDate = birthDate;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public BigDecimal getCurrency() {
return currency;
}
public void setCurrency(BigDecimal currency) {
this.currency = currency;
}
public BigDecimal getPercent() {
return percent;
}
public void setPercent(BigDecimal percent) {
this.percent = percent;
}
public InquiryType getInquiry() {
return inquiry;
}
public void setInquiry(InquiryType inquiry) {
this.inquiry = inquiry;
}
public String getInquiryDetails() {
return inquiryDetails;
}
public void setInquiryDetails(String inquiryDetails) {
this.inquiryDetails = inquiryDetails;
}
public boolean isSubscribeNewsletter() {
return subscribeNewsletter;
}
public void setSubscribeNewsletter(boolean subscribeNewsletter) {
this.subscribeNewsletter = subscribeNewsletter;
}
public Map<String, String> getAdditionalInfo() {
return additionalInfo;
}
public void setAdditionalInfo(Map<String, String> additionalInfo) {
this.additionalInfo = additionalInfo;
}
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("properties name=");
if (name != null) {
sb.append("'").append(name).append("', ");
} else {
sb.append(name).append(", ");
}
sb.append("age=").append(age).append(", ");
sb.append("birthDate=").append(birthDate).append(", ");
sb.append("phone=");
if (phone != null) {
sb.append("'").append(phone).append("', ");
} else {
sb.append(phone).append(", ");
}
sb.append("currency=").append(currency).append(", ");
sb.append("percent=").append(percent).append(", ");
sb.append("inquiry=").append(inquiry).append(", ");
sb.append("inquiryDetails=");
if (inquiryDetails != null) {
sb.append("'").append(inquiryDetails).append("', ");
} else {
sb.append(inquiryDetails).append(", ");
}
sb.append("subscribeNewsletter=").append(subscribeNewsletter).append(", ");
sb.append("additionalInfo=").append(additionalInfo);
return sb.toString();
}
}