1. 表单标签
通过 SpringMVC 的表单标签可以实现将模型数据中的属性和 HTML 表单元素相绑定,以实现表单数据更便捷编辑和表单值的回显。
SpringMVC 提供了多个表单组件标签,如 <form:input/>、<form:select/> 等,用以绑定表单字段的属性值,它们的共有属性如下:
- path:表单字段,对应 html 元素的 name 属性,支持级联属性
- htmlEscape:是否对表单值的 HTML 特殊字符进行转换,默认值为 true
- cssClass:表单组件对应的 CSS 样式类名
- cssErrorClass:表单组件的数据存在错误时,采取的 CSS 样式。
form:input、form:password、form:hidden、form:textarea: 对应 HTML 表单的 text、password、hidden、textarea标签。
form:radiobutton:单选框组件标签,当表单 bean 对应的属性值和 form:radiobuttons: 单选框组标签,用于构造多个单选框。
- items:可以是一个 List、String[] 或 Map
- itemValue:指定 radio 的 value 值。可以是集合中 bean 的一个属性值
- itemLabel:指定 radio 的 label 值
- delimiter:多个单选框可以通过 delimiter 指定分隔符 value 值相等时,单选框被选中。
form:checkbox: 复选框组件。用于构造单个复选框。
form:checkboxs: 用于构造多个复选框。使用方式同form:radiobuttons 标签
form:select:用于构造下拉框组件。使用方式同form:radiobuttons 标签
form:option:下拉框选项组件标签。使用方式同form:radiobuttons 标签
form:errors:显示表单组件或数据校验所对应的错误
- <form:errors path= “ *” /> :显示表单所有的错误
- <form:errors path= “ user*” /> :显示所有以 user 为前缀的属性对应的错误
- <form:errors path= “ username” /> :显示特定表单对象属性的错误
注意:form:errors将结合数据校验一起讲。
下面简单演示一下一些表单标签的使用:
- 首先需要在控制器类EmployeeHandler上添加如下方法:
1
2
3
4
5
6
7
8
9
10"/emp",method=RequestMethod.GET) (value=
public String input(Map<String,Object> map) {
Map<Integer,Department> departmentMap = new HashMap<>();
departmentMap.put(101, new Department(101, "D-AA"));
departmentMap.put(102, new Department(102, "D-BB"));
//需要将所有部门信息放在请求域中,在员工信息添加页面以下拉列表的形式显示部门名称
//values方法获取键对应的值
map.put("departments", departmentMap.values());
return "input";
}
当我们在页面上点击超链接时会有该方法进行处理,将所有的部门信息添加到Map数据模型中,以方便在input.jsp页面进行数据的读取和回显。
- 下面是input.jsp界面的具体实现:
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<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page import="java.util.*" %>
<!-- 导入SpringMVC的表单标签 -->
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>添加员工</title>
</head>
<body>
<form:form action="${pageContext.request.contextPath }/emp" method="POST" >
<!-- path:表单字段,对应 html 元素的 name 属性,支持级联属性
对应指定类的属性名
-->
LastName: <form:input path="lastName"/><br/>
Email: <form:input path="email"/><br/>
<!--
form:radiobuttons:单选框组标签,用于构造多个单选框.
items:可以是一个 List、String[] 或 Map
-->
<%
//注意:new HashMap<>();这种格式JDK1.7以上才支持,否则JSP编译出错
Map<String,String> genders = new HashMap();
genders.put("1", "Male");
genders.put("0", "Female");
//需要放入请求域中,否则EL表达式无法取到值
request.setAttribute("genders", genders);
%>
<!-- 多个单选框可以通过 delimiter 指定分隔符 -->
Gender: <br/><form:radiobuttons path="gender" items="${genders }" delimiter="<br>"/><br/>
<!-- 下拉列表
itemValue:指定 radio 的 value 值。可以是集合中 bean 的一个属性值
itemLabel:指定 radio 的 label 值
-->
Department: <form:select path="department.id"
items="${departments}" itemLabel="departmentName" itemValue="id"/><br/>
<input type="submit" name="提交"/>
</form:form>
</body>
</html>
注意: SpringMVC会通过 modelAttribute 属性指定绑定的模型属性,若没有指定该属性,则默认从 request 域对象中读取command 的表单 bean,如果该属性值也不在,则会发生错误java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name ‘command’ available as request attribute。
那么需要在<form:form>上配置modelAttribute属性,即modelAttribute=”employee”。接着需要在控制器类的input加上如下代码:
1
2//键"employee"匹配input.jsp页面的form表单的modelAttribute的属性值
map.put("employee", new Employee());运行结果如下所示:
2. 静态资源处理
在web.xml文件中,若将 DispatcherServlet 请求映射配置为 /,则 Spring MVC 将捕获WEB 容器的所有请求,包括静态资源的请求, 如JQuery的请求。SpringMVC 会将他们当成一个普通请求处理,因找不到对应处理器将导致错误。
我们可以在 SpringMVC 的配置文件中配置 <mvc:default-servlethandler/> 的方式解决静态资源的问题:
- <mvc:default-servlet-handler/> 将在 SpringMVC 上下文中定义一个DefaultServletHttpRequestHandler,它会对进入 DispatcherServlet 的请求进行筛查,如果发现是没有经过映射的请求,就将该请求交由 WEB应用服务器默认的 Servlet处理,如果不是静态资源的请求,才由DispatcherServlet 继续处理;因此,我们在配置上述的default-servlet时,同时还需要配置annotation-driven,以对非静态资源进行映射处理。
- 一般 WEB 应用服务器默认的 Servlet 的名称都是 default。若所使用的WEB 服务器的默认 Servlet 名称不是 default,则需要通过 defaultservlet-name 属性显式指定。
假如现在需要进行REST风格的操作,也就是点击超链接然后删除一个员工信息。显然,超链接是GET请求,而REST风格的删除操作则是DELETE请求,那么现在则需要导入JQuery以实现将GET请求转换为DELETE请求。具体示例如下:
编写如下index.jsp页面,具体代码如下:
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<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<!-- 导入JQuery -->
<script type="text/javascript" src="scripts/jquery-1.9.1.min.js"></script>
<script type="text/javascript">
$(function(){
//拦截delete的超链接,然后执行对应的表单
$(".delete").click(function(){
//获取链接
var href = $(this).attr("href");
//使用链接提交对应的form表单,从而完成get到delete请求的转化
$("#deleteForm").attr("action",href).submit();
return false;
})
})
</script>
<title>Insert title here</title>
</head>
<body>
<!-- 实现将GET请求转化为DELETE请求,需借助JQuery -->
<form id="deleteForm" action="" method="POST">
<input type="hidden" name="_method" value="DELETE"/>
</form>
<a class="delete" href="emp/1">Delete Employee</a>
</body>
</html>我们知道,Spring MVC 将捕获WEB 容器的所有请求,包括静态资源的请求。那么此时JQuery的导入和使用是不成功的,那么现在需要在MVC配置中进行如下配置:
1
2<mvc:default-servlet-handler/>
<mvc:annotation-driven/>控制器类的对应方法如下所示:
1
2
3
4
5"/emp/{id}",method=RequestMethod.DELETE) (value=
public String delete(@PathVariable("id") Integer id) {
System.out.println("删除了" + id + "号员工");
return "list";
}