1. 概述
在本系列的第一篇文章中,我们介绍了 Spring MVC 表单标签库的基本用法,以及如何将表单数据绑定到 Controller。
本文将深入探讨 Spring MVC 提供的各种表单标签,帮助我们更高效地构建和校验表单。
2. input
标签
我们先从最常用的 input
标签开始。该标签默认会渲染一个 HTML <input type="text">
元素,并绑定指定字段的值:
<form:input path="name" />
从 Spring 3.1 开始,支持 HTML5 中的多种 type
类型,如 email
、date
等。例如,创建一个邮箱输入框:
<form:input type="email" path="email" />
同样地,创建一个日期输入框(HTML5 浏览器会自动显示日期选择器):
<form:input type="date" path="dateOfBirth" />
3. password
标签
这个标签用于渲染一个密码输入框(<input type="password">
),绑定的值不会明文显示:
<form:password path="password" />
4. textarea
标签
用于渲染 HTML <textarea>
多行文本输入框:
<form:textarea path="notes" rows="3" cols="20"/>
与原生 HTML 一样,可以设置 rows
和 cols
属性来控制显示区域大小。
5. checkbox
与 checkboxes
标签
checkbox
标签用于渲染 <input type="checkbox">
复选框。
✅ 单个复选框通常用于布尔值绑定:
<form:checkbox path="receiveNewsletter" />
如果绑定的值为 true
,则默认选中。
✅ 多个复选框绑定同一个字段,字段类型为数组或 java.util.Collection
:
Bird watching: <form:checkbox path="hobbies" value="Bird watching"/>
Astronomy: <form:checkbox path="hobbies" value="Astronomy"/>
Snowboarding: <form:checkbox path="hobbies" value="Snowboarding"/>
对应 Java 字段:
String[] hobbies;
✅ checkboxes
标签用于动态生成多个复选框选项:
<form:checkboxes items="${favouriteLanguageItem}" path="favouriteLanguage" />
其中 items
可以是 Array
、List
或 Map
,通常在 Controller 中初始化:
List<String> favouriteLanguageItem = new ArrayList<String>();
favouriteLanguageItem.add("Java");
favouriteLanguageItem.add("C++");
favouriteLanguageItem.add("Perl");
对应的 Java 字段:
List<String> favouriteLanguage;
6. radiobutton
与 radiobuttons
标签
用于渲染 <input type="radio">
单选按钮。
✅ 多个 radiobutton
绑定同一个字段,每个按钮对应一个值:
Male: <form:radiobutton path="sex" value="M"/>
Female: <form:radiobutton path="sex" value="F"/>
对应 Java 字段:
private String sex;
✅ radiobuttons
动态生成单选按钮选项:
<form:radiobuttons items="${jobItem}" path="job" />
Controller 中初始化选项:
List<String> jobItem = new ArrayList<String>();
jobItem.add("Full time");
jobItem.add("Part time");
7. select
标签
用于渲染 HTML <select>
下拉选择框:
<form:select path="country" items="${countryItems}" />
选项可以是 Array
、List
或 Map
,Controller 中示例:
Map<String, String> countryItems = new LinkedHashMap<String, String>();
countryItems.put("US", "United States");
countryItems.put("IT", "Italy");
countryItems.put("UK", "United Kingdom");
countryItems.put("FR", "France");
✅ 支持嵌套 option
和 options
标签:
<form:select path="book">
<form:option value="-" label="--Please Select--"/>
<form:options items="${books}" />
</form:select>
✅ 多选下拉框(列表框):
<form:select path="fruit" items="${fruit}" multiple="true"/>
对应 Java 字段为数组或 Collection
:
List<String> fruit;
8. hidden
标签
用于渲染隐藏域(<input type="hidden">
):
<form:hidden path="id" value="12345" />
9. errors
标签
用于展示字段校验失败时的错误信息。错误信息由 Controller 关联的 Validator 生成:
<form:errors path="name" cssClass="error" />
默认渲染为 <span>
标签,ID 为 字段名.errors
,并可指定 CSS 类:
<span id="name.errors" class="error">Name is required!</span>
✅ 可通过 element
属性更换包装标签:
<form:errors path="name" cssClass="error" element="div" />
输出:
<div id="name.errors" class="error">Name is required!</div>
✅ 显示所有字段的错误信息(使用通配符):
<form:errors path="*" />
9.1. 自定义 Validator
要展示字段错误,需要定义一个 Validator:
public class PersonValidator implements Validator {
@Override
public boolean supports(Class clazz) {
return Person.class.isAssignableFrom(clazz);
}
@Override
public void validate(Object obj, Errors errors) {
ValidationUtils.rejectIfEmptyOrWhitespace(errors, "name", "required.name");
}
}
错误信息定义在 messages.properties
中:
required.name = Name is required!
在 Spring 配置文件中注册资源文件:
<bean class="org.springframework.context.support.ResourceBundleMessageSource" id="messageSource">
<property name="basename" value="messages" />
</bean>
或使用 Java 配置:
@Bean
public MessageSource messageSource() {
ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
messageSource.setBasenames("messages");
return messageSource;
}
在 Controller 中使用 Validator:
@RequestMapping(value = "/addPerson", method = RequestMethod.POST)
public String submit(
@ModelAttribute("person") Person person,
BindingResult result,
ModelMap modelMap) {
validator.validate(person, result);
if (result.hasErrors()) {
return "personForm";
}
modelMap.addAttribute("person", person);
return "personView";
}
9.2. JSR 303 Bean 校验
从 Spring 3 开始,支持使用 @Valid
注解进行 JSR 303 校验。需要引入 Hibernate Validator:
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<version>8.0.1.Final</version>
</dependency>
启用注解驱动支持:
<mvc:annotation-driven/>
或 Java 配置:
@EnableWebMvc
@Configuration
public class ClientWebConfigJava implements WebMvcConfigurer {
// All web configuration will go here
}
在 Controller 方法中使用 @Valid
:
@RequestMapping(value = "/addPerson", method = RequestMethod.POST)
public String submit(
@Valid @ModelAttribute("person") Person person,
BindingResult result,
ModelMap modelMap) {
if(result.hasErrors()) {
return "personForm";
}
modelMap.addAttribute("person", person);
return "personView";
}
实体字段上使用注解校验:
@NotEmpty
private String password;
默认错误信息是 “may not be empty”,可通过资源文件覆盖:
NotEmpty.person.password = Password is required!
10. 总结
本文详细介绍了 Spring MVC 表单标签库中各个标签的使用方式,以及如何结合 Validator 和 JSR 303 实现表单校验与错误提示。
所有示例代码可从 GitHub 项目 获取,导入 Eclipse 即可运行。
启动项目后访问地址: