SpringMVC数据绑定是针对前端传过来参数时,我们如何去对应不同数据类型,来绑定参数,包括:
基本类型,包装类,数组,类对象(简单对象和复杂对象),集合(List,Set,Map),json,xml
例如基本类int和包装类Integer
int和Integer类型
@Controller
public class MyController {
@RequestMapping("baseType.do")
@ResponseBody
public String demo1(int age){
return "age: "+age;
}
}
但是,int不能传null,Integer可以传空
@RequestParam注解
@RequestParam(value = “xage”,defaultValue = “1”,required = true)
value =========绑定参数的名(与请求中的参数名称对应)
defaultValue ====默认值
required=======传的参数是否为必须
这里用@RequestParam注解对参数进行绑定
@RequestMapping("baseType.do")
@ResponseBody
public String demo1(@RequestParam(value = "xage") int age){
return "age: "+age;
}
数组类型绑定
@RequestMapping("array.do")
@ResponseBody
public String demo2(String[] name){
StringBuffer sb = new StringBuffer();
for (int i = 0;i<name.length;i++){
sb.append(name[i]+" ");
}
return sb.toString();
}
对象绑定
简单对象绑定
@RequestMapping("pojo.do")
@ResponseBody
public String demo3(User user){
return user.toString();
}
多层级对象绑定
例如想绑定到User对象中的ContactInfo对象属性,他的telephone和adddress属性
@RequestMapping("pojo2.do")
@ResponseBody
public String demo4(User user){//User中新增加了一个ContactInfo(联系方式)对象字段
return user.toString();
}
同属性的多对象对象绑定
例如有两个对象,但对象的属性相同,那么该如何绑定这两个属性呢?
用@InitBinder注解,为Controller中方法的参数加上前缀
@RequestMapping("pojo3.do")
@ResponseBody
public String demo4(User user, Person person){
return user.toString()+" "+person.toString();
}
@InitBinder("user")
public void initUser(WebDataBinder webDataBinder){
webDataBinder.setFieldDefaultPrefix("user.");
}
@InitBinder("person")
public void initPerson(WebDataBinder webDataBinder){
webDataBinder.setFieldDefaultPrefix("person.");
}
如果不加@InitBinder注解的话会报500错误,提示Controller中没有这个方法
集合对象绑定
List对象绑定
list应用场景、例如想要接收表单中的personList
SpringMVC对于集合绑定,需要创建一个data收集对象
@RequestMapping("list.do")//错误示范,这种是不可以的了
@ResponseBody
public String demo5(List<Person> personList){
return personList.toString();
}
//应该这样
@RequestMapping("list.do")
@ResponseBody
public String demo5(ListObj personList){
return personList.toString();
}
ListObj.class
public class ListObj {
private List<Person> personList;
public List<Person> getPersonList() {
return personList;
}
public void setPersonList(List<Person> personList) {
this.personList = personList;
}
@Override
public String toString() {
return "ListObj{" +
"personList=" + personList +
'}';
}
}
传list时可能会经历的坑!
注:如果传参数时,传个personList[20].name,跳过了许多,会导致中间全是null,这样会导致后台资源的浪费,所以对于list绑定,要尽可能的传连续的参数
Set对象绑定
Set的应用场景,同List应用场景相同,但是与List不同的是,Set使用时需要初始化而List不需要,并且Set在实际应用中一般用于对象的 重复判断 或者是 排除重复,,SpringMVC对于Set的绑定支持的还是不够好
@RequestMapping("set.do")
@ResponseBody
public String demo6(SetObj personSet){
return personSet.toString();
}
case1:不初始化
不初始化
可见,不管下角标传什么都不好使
Set初始化
public class SetObj {
private Set<Person> personSet;
//定义一个构造器,实例化两个personSet
private SetObj(){
personSet = new LinkedHashSet<Person>();
personSet.add(new Person());
personSet.add(new Person());
}
public Set<Person> getPersonSet() {
return personSet;
}
public void setPersonSet(Set<Person> personSet) {
this.personSet = personSet;
}
@Override
public String toString() {
return "SetObj{" +
"personSet=" + personSet +
'}';
}
}
case2: 下标越界
case3:实例的set为重复的
上面 set初始化 的时候初始化了两个空的Person对象,那么set判定重复的时候,就会判定为是两个相同的对象,就会出现虽然实例化了两个person,但是因为重复,就只添加进了一个
先重写equals()和hashCode()方法!
因为我们要判定是否为重复内容,所以要重写equals()方法
但equals重写时,一定要重写hashCode!
既然自定义类重写了equals方法,说明类设计者不希望通过内存地址来比较两个对象是否相等了。而Object的hashCode也是对象的内存地址,既然不希望通过地址比较对象,那么以内存地址作为hashCode也就没有实际使用意义了,索性将自定义对象的hashCode方法也重写了吧!
Person类中添加
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
if (name != null ? !name.equals(person.name) : person.name != null) return false;
return email != null ? email.equals(person.email) : person.email == null;
}
@Override
public int hashCode() {
int result = name != null ? name.hashCode() : 0;
result = 31 * result + (email != null ? email.hashCode() : 0);
return result;
}
所以对集合绑定一般情况下使用List
Map对象绑定
Map对象绑定使用情景同List,但用的是学生姓名为key,email为value的形式,一旦学生重名了,就会只保留一个,这是map的特性,value可以相同,但key不可以相同
Controller
@RequestMapping("map.do")
@ResponseBody
public String demo7(MapObj personMap){
return personMap.toString();
}
MapObj.class
public class MapObj {
//这里是一个String的Key,对应一个person
private Map<String,Person> map;
public Map<String, Person> getMap() {
return map;
}
public void setMap(Map<String, Person> map) {
this.map = map;
}
@Override
public String toString() {
return "MapObj{" +
"map=" + map +
'}';
}
}