SpringMVC笔记(8):表单标签库
原创: 南风 Java大联盟 2018-08-09
前言:
我们为什么要使用Spring MVC表单标签库?一句话,使用它是为了简化代码的开发,提高我们的效率,其实我们使用任何一款框架或者工具都是出于这个目的,实现快速开发。
Spring MVC表单标签库是如何来提高我们的开发效率呢?首先来做一个对比,业务场景:控制层返回模型数据到视图层,视图层需要使用EL将模型数据绑定到HTML页面表单中。
实体类
package com.southwind.entity;
public class Student {
private int id;
private String name;
private int age;
private String gender;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
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 String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public Student(int id, String name, int age, String gender) {
super();
this.id = id;
this.name = name;
this.age = age;
this.gender = gender;
}
}
Handler
package com.southwind.controller;
import java.util.ArrayList;
import java.util.List;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import com.southwind.entity.Student;
@Controller
@RequestMapping("/hello")
public class HelloHandler {
@RequestMapping(value="/get")
public String get(Model model) {
Student student = new Student(1,"张三",22,"男");
model.addAttribute("student", student);
return "index";
}
}
JSP
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page isELIgnored="false" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>修改学生信息</h1>
<form action="" method="post">
学生编号:<input type="text" name="id" value=${student.id } readonly="readonly"/><br/>
学生姓名:<input type="text" name="name" value=${student.name } /><br/>
学生年龄:<input type="text" name="age" value=${student.age } /><br/>
学生性别:<input type="text" name="gender" value=${student.gender } /><br/>
<input type="submit" value="提交"/><br/>
</form>
</body>
</html>
使用Spring MVC表单标签可以直接将模型数据绑定到HTML表单中,非常简单。
1.JSP页面导入Spring MVC标签库,与导入JSTL标签库的语法非常相似,前缀prefix可以自定义,通常定义为form。
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
2.将form表单与模型数据进行绑定,通过modelAttribute属性完成绑定,将modelAttribute的值设置为控制器向model对象存值时的name即可。
3.form表单与模型数据完成绑定之后,接下来就是将模型数据中的值取出绑定到不同的标签中,通过设置标签的path属性完成,将path属性的值设置为模型数据对应的属性名即可。
完整代码如下
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page isELIgnored="false" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>修改学生信息</h1>
<form:form modelAttribute="student">
学生编号:<form:input path="id" readonly=""/><br/>
学生姓名:<form:input path="name" /><br/>
学生年龄:<form:input path="age" /><br/>
学生性别:<form:input path="gender" /><br/>
<input type="submit" value="提交"/><br/>
</form:form>
</body>
</html>
重新运行程序,看到结果如下图。
完成绑定。
接下来我们详细讲解常用标签的使用方法。
1.form标签
<form:form modelAttribute="student" method="post">
渲染的是HTML中的<form></form>,通过modelAttribute属性绑定具体的模型数据。
2.input标签
<form:input path="name" />
渲染的是HTML中的<input type="text"/>,form标签绑定的是模型数据,input标签绑定的就是模型数据中的属性值,通过path与模型数据的属性名对应,并支持级联属性。
创建Address实体类。
package com.southwind.entity;
public class Address {
private int id;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Address(int id, String name) {
super();
this.id = id;
this.name = name;
}
}
修改Student实体类,添加Address属性。
package com.southwind.entity;
public class Student {
private int id;
private String name;
private int age;
private String gender;
private Address address;
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
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 String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public Student(int id, String name, int age, String gender) {
super();
this.id = id;
this.name = name;
this.age = age;
this.gender = gender;
}
}
模型对象添加Address。
@RequestMapping(value="/get")
public String get(Model model) {
Student student = new Student(1,"张三",22,"男");
Address address = new Address(1,"科技路");
student.setAddress(address);
model.addAttribute("student", student);
return "index";
}
修改JSP页面,设置级联。
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page isELIgnored="false" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>修改学生信息</h1>
<form:form modelAttribute="student">
学生编号:<form:input path="id" readonly=""/><br/>
学生姓名:<form:input path="name" /><br/>
学生年龄:<form:input path="age" /><br/>
学生性别:<form:input path="gender" /><br/>
学生住址:<form:input path="address.name" /><br/>
<input type="submit" value="提交"/><br/>
</form:form>
</body>
</html>
3.password标签
<form:password path="password" />
渲染的是HTML中的<input type="password"/>,通过path与模型数据的属性名对应,password标签的值不会在页面显示。
4.checkbox标签:
<form:checkbox path="hobby" value="读书" />读书
渲染的是HTML中的<input type="checkbox"/>,通过path与模型数据的属性名对应,可以绑定boolean,数组和集合。
如果绑定boolean类型的变量,该变量值为true,则表示选择,false表示不选中。
student.setFlag(true);
checkbox:<form:checkbox path="flag" />
如果绑定数组或集合类型,集合中的元素等于checkbox的vlaue值,则该项选中,否则不选中。
student.setHobby(Arrays.asList("读书","看电影","旅行"));
<form:checkbox path="hobby" value="读书" />读书
<form:checkbox path="hobby" value="看电影" />看电影
<form:checkbox path="hobby" value="打游戏" />打游戏
<form:checkbox path="hobby" value="听音乐" />听音乐
<form:checkbox path="hobby" value="旅行" />旅行<br/>
5.checkboxs标签:
<form:checkboxes items="${student.hobby }" path="selectHobby" />
渲染的是HTML中的一组<input type="checkbox"/>,这里需要结合items和path两个属性来使用,items绑定被遍历的集合或数组,path绑定被选中的集合或数组,可以这样理解,items为全部选型,path为默认选中的选型。
student.setHobby(Arrays.asList("读书","看电影","打游戏","听音乐","旅行"));
student.setSelectHobby(Arrays.asList("读书","看电影"));
<form:checkboxes items="${student.hobby }" path="selectHobby" />
需要注意的是path可以直接绑定模型数据的属性,items则需要通过EL的方式从域对象中取值,不能直接写属性名。
6.radiobutton标签
<form:radiobutton path="radioId" value="0" />
渲染的是HTML中的一个<input type="radio"/>,绑定的数据与标签的value值相等为选中状态,否则为不选中状态。
student.setRadioId(1);
<form:radiobutton path="radioId" value="0" />男
<form:radiobutton path="radioId" value="1" />女
7.radiobuttons标签
<form:radiobuttons items="${student.grade }" path="selectGrade" />
渲染的是HTML中的一组<input type="radio"/>,这里需要结合items和path两个属性来使用,items绑定被遍历的集合或数组,path绑定被选中的值,可以这样理解,items为全部选型,path为默认选中的选型,用法与<form:checkboxs />一致。
Map<Integer,String> gradeMap=new HashMap<Integer,String>();
gradeMap.put(1, "一年级");
gradeMap.put(2, "二年级");
gradeMap.put(3, "三年级");
gradeMap.put(4, "四年级");
gradeMap.put(5, "五年级");
gradeMap.put(6, "六年级");
student.setGrade(gradeMap);
student.setSelectGrade(3);
<form:radiobuttons items="${student.grade }" path="selectGrade" />
8.select标签
<form:select items="${student.citys }" path="selectCity" />
渲染的是HTML中的一个<select/>,这里需要结合items和path两个属性来使用,items绑定被遍历的集合或数组,path绑定被选中的值,用法与<form:radiobuttons/>一致。
Map<Integer,String> cityMap=new HashMap<Integer,String>();
cityMap.put(1, "北京");
cityMap.put(2, "上海");
cityMap.put(3, "广州");
cityMap.put(4, "深圳");
cityMap.put(5, "西安");
cityMap.put(6, "武汉");
student.setCitys(cityMap);
student.setSelectCity(5);
<form:select items="${student.citys }" path="selectCity" />
9.form:select结合form:options的使用,form:select只定义path属性,在form:select标签内部添加一个子标签form:options,设置items属性,获取被遍历的集合。
<form:select path="selectCity">
<form:options items="${student.citys }"></form:options>
</form:select>
10.form:select结合form:option的使用,form:select定义path属性,给每一个form:option设置values属性,path与哪个value相等,该项默认选中。
<form:select path="selectCity">
<form:option value="5">杭州</form:option>
<form:option value="6">成都</form:option>
<form:option value="7">南京</form:option>
</form:select>
11.textarea标签
渲染的是HTML中的一个<textarea/>,path绑定模型数据的属性值,作为文本输入域的默认值。
student.setIntroduce("你好,我叫...");
<form:textarea path="introduce"/>
12.hidden标签
渲染的是HTML中的一个<input type="hidden"/>,path绑定模型数据的属性值。
13.errors标签
该标签需要结合Spring MVC的Validator验证器来使用,将验证结果的error信息渲染到HTML页面中。
创建验证器,实现Validator接口。
package com.southwind.validator;
import org.springframework.validation.Errors;
import org.springframework.validation.ValidationUtils;
import org.springframework.validation.Validator;
import com.southwind.entity.Student;
public class StudentValidator implements Validator{
public boolean supports(Class<?> clazz) {
// TODO Auto-generated method stub
return Student.class.equals(clazz);
}
public void validate(Object target, Errors errors) {
// TODO Auto-generated method stub
ValidationUtils.rejectIfEmpty(errors, "name", null, "姓名不能为空");
ValidationUtils.rejectIfEmpty(errors, "password", null, "密码不能为空");
}
}
springmvc.xml中添加Validator配置。
<mvc:annotation-driven validator="studentValidator"/>
<bean id="studentValidator" class="com.southwind.validator.StudentValidator"/>
创建业务方法,第一个login方法用来生成模型数据,跳转到login.jsp,第二个login方法用来做验证判断。
@GetMapping(value = "/login")
public String login(Model model){
model.addAttribute(new Student());
return "login";
}
@PostMapping(value="/login")
public String register(@Validated Student student,BindingResult br) {
if (br.hasErrors()) {
return "login";
}
return "success";
}
login.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ page isELIgnored="false" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>修改学生信息</h1>
<form:form modelAttribute="student" action="login" method="post">
学生姓名:<form:input path="name" /><form:errors path="name"/><br/>
学生密码:<form:password path="password" /><form:errors path="password"/><br/>
<input type="submit" value="提交"/>
</form:form>
</body>
</html>
运行。