Spring MVC數據綁定方式
定義:簡單綁定是將一個用戶界面元素(控件)的屬性綁定到一個類型(對象)實例上的某個屬性的方法。
基本類型、包裝類型、數組(以參數age為例)
一、基本類型
1、key是必須的,即age是必須傳值的
2、隻能是int類型,即傳給age的值必須為int類型且范圍也隻能是int類型
如果沒有傳age,後臺會報500錯誤,會提示當前的age是不可以為空的
如果age傳一個字符串abc,Spring MVC會進行攔截,報400參數錯誤異常
@Controller public class TestController{ /* RequestMapping註解 value:RequestMapping的屬性,指定請求的實際地址 method:RequestMapping的屬性,指定請求的method類型,分為GET、POST、PUT、DELETE等 headers:RequestMapping的屬性 指定request中必須包含指定的header值,才能處理該請求 */ @RequestMapping(value = "baseType.do", method = RequestMethod.GET) @ResponseBody //方法的返回值會放到ResponseBody數據區裡 /* RequestParam註解 value:RequestParam的屬性,起別名 required:RequestParam的屬性,是否必傳,默認值是true */ public String baseType(@RequestParam(value = "xage") int age){ return "age:" + age; } }
二、包裝類型
1、可以不傳key,即age可以為空
@Controller public class TestController{ @RequestMapping(value = "baseType.do") @ResponseBody public String baseType(Integer age){ return "age:" + age; } }
此時訪問localhost:8080/baseType.do,前臺顯示age:null
註意:在開發過程中,對可能為空的數據,最好將參數數據定義為包裝類型
三、數組
一次性傳多個值,例如基本類型、包裝類型、String的對象類型
@Controller public class TestController{ @RequestMapping(value = "array.do") @ResponseBody public String array(String[] age){ StringBuilder sdf = new StringBuilder(); for(String item : age){ sbf.append(item).append(" "); } return sbf.toString(); } }
此時訪問localhost:8080/array.do?age=17&age=18,前臺顯示17 18
簡單對象、多層級對象、同屬性對象
一、簡單對象(User類:name, age)
@Controller public class TestController{ @RequestMapping(value = "object.do") @ResponseBody public String object(User user){ return user.toString(); } }
此時訪問localhost:8080/object.do?name=Tom&age=18,前臺顯示User{name='Tom',age=18}
二、多層級對象(User類:name, age, contactInfo、ContactInfo類:phone, adress)
@Controller public class TestController{ @RequestMapping(value = "object.do") @ResponseBody public String object(User user){ return user.toString(); } }
此時訪問localhost:8080/object.do?name=Tom&age=18&contactInfo.phone=10000
前臺顯示User{name='Tom',age=18,contactInfo={phone='10000',address='null'}}
三、同屬性對象(User類:name, age、Admin類:name, age)
@Controller public class TestController{ @RequestMapping(value = "object.do") @ResponseBody public String object(User user, Admin admin){ return user.toString() + " " + admin.toString(); } }
此時訪問localhost:8080/object.do?name=Tom&age=18,前臺顯示User{name='Tom',age=18} Admin{name='Tom',age=18}
@Controller public class TestController{ @RequestMapping(value = "object.do") @ResponseBody public String object(User user, Admin admin){ return user.toString() + " " + admin.toString(); } } @InitBinder("user") //綁定前綴 public void initUser(WebDataBinder binder){ binder.setFieldDefaultPrefix("user."); } @InitBinder("admin") //綁定前綴 public void initUser(WebDataBinder binder){ binder.setFieldDefaultPrefix("admin."); }
此時訪問localhost:8080/object.do?user.name=Tom&admin.name=Lucy&age=18
前臺顯示User{name='Tom',age=18} Admin{name='Lucy',age=18}
如果沒有@InitBinder註解的輔助方法,這個方法如果傳遞user.name,admin.name結果會怎麼樣呢?
如果沒有@InitBinder註解的輔助方法,Spring MVC會認為是User類和Admin類裡面的user字段的name,所以前臺顯示null
List、Set、Map
一、List
@Controller public class TestController{ @RequestMapping(value = "list.do") @ResponseBody public String list(UserList userList){ return userList.toString(); } }
Spring MVC關於集合綁定需要一個data收集的對象,單純的綁定是無效的。
建一個UserList類:
public class UserList{ private List<User> users; public List<User> getUsers(){ return users; } public void setUsers(List<User> users){ this.users = users; } @Override public String toString(){ return "UserList{" + "users=" + users + '}'; } }
此時訪問localhost:8080/list.do?users[0].name=Tom&users[1].name=Lucy
前臺顯示UserList{users=[User{name='Tom', age=null, contactInfo=null}, User{name='Lucy', age=null, contactInfo=null}]}
註意:如果訪問傳值的時候,users[0]直接跨到users[10],即訪問
localhost:8080/list.do?users[0].name=Tom&users[10].name=Lucy
則前臺顯示users[1]到users[9]以及users[11]為空對象,所以請求索引的時候一定要是連續的,否則會浪費資源
二、Set
Set相對List來說有一定的局限性,它需要先初始化Set,而List是不需要的
Set在實際應用場景當中,大部分是做對象的重復判斷或排除重復
例如一個Student對象(姓名和Email),如果姓名和Email相同,則認為這個對象是重復的,此時需要重寫hashcode方法和equals方法,然後在方法裡寫重復判斷的邏輯(綁定到一個對象上)
@Controller public class TestController{ @RequestMapping(value = "set.do") @ResponseBody public String set(UserSet userSet){ return userSet.toString(); } }
Set和List一樣,也需要一個data收集的對象
public class UserSet{ private Set<User> users; //Set和List有一些區別,就是對它本身的初始化有一些要求 private UserSet(){ users = new LinkedHashSet<User>(); users.add(new User()); users.add(new User()); } public Set<User> getUsers(){ return users; } public void setUsers(Set<User> users){ this.users = users; } @Override public String toString(){ return "UserSet{" + "users=" + users + '}'; } }
此時訪問localhost:8080/set.do?users[0].name=Tom&users[1].name=Lucy
前臺顯示UserSet{users=[User{name='Tom', age=null, contactInfo=null}, User{name='Lucy', age=null, contactInfo=null}]}
如果跨界訪問,即訪問localhost:8080/set.do?users[0].name=Tom&users[10].name=Lucy
則會報錯,因為已經定義瞭Set的size為2
註意:如果沒有重寫hashcode方法和equals方法進行排重,則傳兩個相同對象的時候前臺還會顯示兩個對象
可是如果定義瞭Set的size為2,而又重寫瞭hashcode方法和equals方法進行排重,那麼當我們傳兩個相同對象的時候則會拋異常,因為初始化Set的時候定義的是兩個空對象,可是經過hashcode方法和equals方法判
斷完之後會認為是重復的對象,所以初始化的Set的size則為1,此時傳兩個對象就會報錯,所以Spring MVC對Set的支持並不友好
三、Map
@Controller public class TestController{ @RequestMapping(value = "map.do") @ResponseBody public String map(UserMap userMap){ return userMap.toString(); } }
Map和List一樣,也需要一個data收集的對象
public class UserMap{ private Map<String,User> users; public Map<User> getUsers(){ return users; } public void setUsers(Map<String,User> users){ this.users = users; } @Override public String toString(){ return "UserMap{" + "users=" + users + '}'; } }
此時訪問localhost:8080/map.do?users["X"].name=Tom&users["X"].age=10&users["Y"].name=Lucy
前臺顯示UserMap{users={X=User[name='Tom', age=10, contactInfo=null}, Y=User{name='Lucy', age=null, contactInfo=null}}}
JSON、XML
RequestBody註解用於讀取Request請求的Body部分數據,使用系統默認配置的HttpMessageConverter進行解析,然後把相應的數據綁定到要返回的對象上;再把HttpMessageConverter返回的對象數據綁定到Controller中方法的參數上。
RequestBody註解常用來處理Content-Type不是默認的application/x-www-form-urlcoded編碼的內容,比如說:application/json或者是application/xml等。一般情況下來說常用其來處理application/json類型。
一、JSON
@Controller public class TestController{ @RequestMapping(value = "json.do") @ResponseBody public String json(@RequestBody User user){ return user.toString(); } }
利用PostMan等工具傳值:
{ "name":"Jim", "age":16, "contactInfo":{ "address":"beijing", "phone":"10010" } }
返回值:
User{name='Jim', age=16, contactInfo=ContactInfo{phone='10010', address='beijing'}}
二、XML
這個功能需要spring-oxm依賴包提供支持以及在實體類中添加一些註解
@XmlRootElement(name="admin") public class Admin{ private String name; private String age; @XmlElement(name="name") public String getName() { return name; } public void setName(String name) { this.name = name; } @XmlElement(name="age") public Integer getAge() { return age; } public void setAge(String age) { this.age = age; } @Override public String toString(){ return "Admin{" + "name='" + name + '\'' + ", age=" + age + '}'; } } @Controller public class TestController{ @RequestMapping(value = "xml.do") @ResponseBody public String xml(@RequestBody User user){ return user.toString(); } }
利用PostMan等工具傳值:
<?xml version="1.0" encoding="UTF-8" ?> <admin> <name>Jim</name> <age>16</age> </admin>
返回值:
Admin{name='Jim', age=16}
以上為個人經驗,希望能給大傢一個參考,也希望大傢多多支持WalkonNet。
推薦閱讀:
- 淺談@RequestMapping註解的註意點
- 基於spring mvc請求controller訪問方式
- springboot @Controller和@RestController的區別及應用詳解
- springboot 實戰:異常與重定向問題
- SpringBoot獲取前臺參數的六種方式以及統一響應