表单标签

SpringMVC 也提供了一组类似 JSTL 的标签,供我们在页面上简化开发。下面是个例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<form:form
action="${pageContext.request.contextPath }/emp"
method="post"
modelAttribute="employee"
>
<input type="hidden" name="_method" value="put" />
<form:hidden path="empId" />
<table align="center">
<tr>
<td colspan="2" align="center">编辑员工</td>
</tr>
<tr>
<td>姓名</td>
<td>
<form:input path="empName" />
</td>
</tr>
<tr>
<td>社会保险号</td>
<td>${requestScope.employee.ssn }</td>
</tr>
<tr>
<td>所在部门</td>
<td>
<form:select
path="department.deptId"
items="${requestScope.deptList }"
itemValue="deptId"
itemLabel="deptName"
/>
</td>
</tr>
<tr>
<td colspan="2" align="center">
<input type="submit" value="更新" />
</td>
</tr>
</table>
</form:form>

1、导入标签库

1
<%@ taglib uri="http://www.springframework.org/tags/form" prefix="form" %>

2、form:form 标签

①action 属性

和 HTML 标签中的 form 标签的 action 属性作用一致,用来设置表单提交的 URL 地址。如果 form:form 标签省略 action 属性,那么会使用当前表单所在页面的 URL 地址作为 action 属性的值。

②modelAttribute 属性

该标签无论是执行保存还是更新操作,都要从请求域中读取模型数据。如果没有设置 modelAttribute 属性那么就以 command 为属性名从请求域中读取。如果找不到则会抛出异常。 所以要想 form:form 标签正常工作一定要将一个模型对象保存到请求域中,哪怕是保存数据时也要创建一个空对象保存。

3、表单标签的共同属性

①path

表单字段,对应 HTML 元素的 name 属性,支持级联属性。

②htmlEscape

是否对表单值的 HTML 特殊字符进行转换,默认值为 true。

③cssClass

表单组件对应的 CSS 样式类名。

④cssErrorClass

表单组件的数据存在错误时,采取的 CSS 样式。

4、form:radiobuttons

单选框组标签,用于构造多个单选框

①items

可以是一个 List、String[]或 Map

②itemValue

通过指定 bean 的一个属性名生成 radio 的 value 值。可以是集合中 bean 的一个属性值

③itemLabel

通过指定 bean 的一个属性名生成 radio 的 label 值

④delimiter

多个单选框可以通过 delimiter 指定分隔符

5、form:errors

显示表单组件或数据校验所对应的错误
<form:errors path=””/>:显示表单所有的错误
<form:errors path=”user”/>:显示所有以 user 为前缀的属性对应的错误
<form:errors path=”userName”/>:显示特定表单对象属性的错误

6、单个多选框

JSP 页面上的标签:

1
<form:checkbox path="agreeProtocal" />

生成的 HTML 标签:

1
2
3
4
5
6
7
8
<input
id="agreeProtocal1"
name="agreeProtocal"
type="checkbox"
value="true"
checked="checked"
/>
<input type="hidden" name="_agreeProtocal" value="on" />

提交时的效果:

images

images

7、表单隐藏域

需要将 POST 请求转为 PUT 请求时,会用_method 请求参数,但是模型对象中没有,所以只能使用 HTML 标签。

1
2
3
4
<!-- 如果path属性指定的属性名在模型对象中不存在,则会抛出异常:org.springframework.beans.NotReadablePropertyException -->
<%--<form:hidden path="_method" value="PUT" />--%>
<!-- 此时就不能使用SpringMVC的表单标签,只能使用HTML标签 -->
<input type="hidden" name="_method" value="PUT" />

8、测试

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ taglib
prefix="form" uri="http://www.springframework.org/tags/form" %>
<html>
<head>
<title>表单标签</title>
</head>
<body>
<!-- 使用form:form来生成HTML的form标签,主要作用是便于我们实现表单回显 -->
<!-- modelAttribute属性:会从请求域中读取和属性名对应的属性,如果没有获取到对应的对象会抛出异常 -->
<!-- java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'employee' available as request attribute -->
<!-- 说明SpringMVC在底层会调用request.setAttribute("employee") -->
<form:form action="" method="post" modelAttribute="employee">
<!-- 在具体表单标签中,访问模型对象的属性时,如果属性名不匹配,会抛出下面异常: -->
<!-- org.springframework.beans.NotReadablePropertyException: Invalid property 'empName' of bean class [java.lang.Object]: Bean property 'empName' is not readable or has an invalid getter method: Does the return type of the getter match the parameter type of the setter? -->
<!-- 说明SpringMVC底层会根据这里指定的名称作为属性名访问实体类对象(属性名和getXxx()、setXxx()方法按照默认规则对应) -->
<!-- form:input标签:生成普通文本框,path属性生成文本框的name属性,SpringMVC负责实现表单回显 -->
员工姓名:<form:input path="empName" /><br />

<!-- form:password标签:生成密码框,path属性生成文本框的name属性,没有自动回显 -->
员工密码:<form:password path="empPwd" /><br />

<!-- form:textarea标签:生成多行文本框 -->
员工介绍:<form:textarea path="empDesc" /><br />

<!-- form:checkbox生成一个单个的多选框,通常用来表示是否同意协议 -->
同意协议:<form:checkbox path="agreeProtocal" /><br />

<!-- form:hidden标签:生成表单隐藏域 -->
<form:hidden path="empSalary" />

<!-- 如果path属性指定的属性名在模型对象中不存在,则会抛出异常:org.springframework.beans.NotReadablePropertyException -->
<%--<form:hidden path="_method" value="PUT" />--%>
<!-- 此时就不能使用SpringMVC的表单标签,只能使用HTML标签 -->
<input type="hidden" name="_method" value="PUT" />

<!-- form:checkboxes标签生成一组多选框。为了能够生成多个标签,需要从请求域读取一个集合。 -->
<!-- 集合中的实体类要求封装两个数据:一个是value属性值;一个是用户看到的值。 -->
<!-- items属性:使用EL表达式传入集合,集合中包含用来生成多选框的数据 -->
<!-- SpringMVC底层会遍历这个集合,遍历得到的每一个对象用于生成一个标签 -->
<!-- SpringMVC底层根据itemValue属性指定的属性名,从实体类对象中获取对应的属性值,从而生成HTML标签里的value属性值 -->
<!-- SpringMVC底层根据itemLabel属性指定的属性名,从实体类对象中获取对应的属性值,从而生成HTML标签里的给用户看的部分 -->
<form:checkboxes
path="favoriteSeason"
items="${requestScope.seasonList}"
itemValue="valueProp"
itemLabel="userCanSee"
/>

<!-- 单个单选按钮:form:radiobutton -->
<!-- 一组单选按钮:form:radiobuttons path="" items="" itemLabel="" itemValue="" -->
<!-- 下拉列表:form:select path="" items="" itemValue="" itemLabel="" -->

<br />

<!-- 使用form:checkboxes标签希望能够生成如下的HTML标签 -->
<!-- <input type="checkbox" name="favoriteSeason" value="spring" />春天 -->
<!-- <input type="checkbox" name="favoriteSeason" value="summer" />夏天 -->
<!-- <input type="checkbox" name="favoriteSeason" value="autumn" />秋天 -->
<!-- <input type="checkbox" name="favoriteSeason" value="winter" />冬天 -->

<button type="submit">保存</button>
</form:form>
</body>
</html>