将之前入门学习的springMVC粗略总结一下,技术有限,如有错误,望指出。
SpringMVC常见的几种常见的数据绑定
一、数据绑定的方式
1 . 通过注解 @RequestParam 绑定url参数, 如绑定url参数上的age属性:
- public String baseType(@RequestParam("age") Integer age){
- return "age: "+age;
- }
- public String baseType(@RequestParam User user){
- return "user: "+ user;
- }
2. 通过 @PathVariable("courseId")获取 不过需要在Mapping路径下加上/{courseId}
这是用/后加而不是加url参数的方式,如:
- @RequestMapping("/view2/{courseId}")
- public String viewCourse2(@PathVariable("courseId") Integer courseId)
3 SpringMVC自动注入
- @RequestMapping("/user")
- public String viewCourse2(User user)</span>
注意!!在使用SpringMVC绑定基本类型(如String,Integer等)参数时,应通过@RequestParam注解指定具体的参数名称,或者采取第二种方式,这是因为只有在debug模式下编译,其参数名称才存储在编译好的代码中。 否则,当代码在非debug模式下编译后,运行时会引发HandlerMethodInvocationException异常。
二、数据绑定的类型
1. 单个 基本数据类型的绑定
int类型的数据: Int 类型的参数不能为空Integer 却可以。因此如果允许为空时可使用 Integer 绑定int 数据。如
- public String baseType(@RequestParam("age") Integer age){
- return "age: "+age;
- }
2 多个相同数据的绑定
url请求有多个相同,如:http://localhost:8080/courses?courseId=1&courseId=2&courseId=3
用数组接收,此处可用int[] courseId 接收
3 传递一个对象,比如 User { name=”Tom”, age=10} (一个学生对象,传递名字和年龄时)当url请求为 http://localhost:8080/baseDemo/object?name=%22tom%22&age=12
- @RequestMapping(value = "/object",method = RequestMethod.GET)
- @ResponseBody
- // 传递对象只需要对象的key值,即 User 的name 和 age
- public String baseType(User user){
- return user.toString();
- }
4 绑定参数中对象的下级属性:
比如在User中加入联系信息的类ContactInfo。使得User类为: User{ name ; age ;contactInfo } ContactInfo{ phone; address ;}
想传递User的name,age,以及contactnfo的phone属性,使得
User{name='Tom',age=12, contactInfo=ContactInfo{phone='123', adress='null'}}(Json格式 下同),
可以在url中传递 name=Tom age=12 contactInfo.phone=123,即以
http://localhost:8080/baseDemo/object?name=Tom&age=12&contactInfo.phone=123 传递。
5 拥有同属性的多对象的情况
当有一个 admin { name ; age } 和 User{ name ; age ;contactInfo } 同时拥有name 和age的属性需要进行赋值,使得 User{name=”Tom”;age=16;contactInfo=null} admin{name=”Jerry”; age=16} ,Controller绑定代码如下:(直接让SpringMVC自动注入 User 和A d min 的参数)
- <span style="font-size:18px;">@RequestMapping(value = "/object_object2",method = RequestMethod.GET)
- @ResponseBody
- // 传递对象只需要对象的key值,即 User 的name 和 age
- public String object_object2(User user,Admin admin){
- return user.toString() +admin.toString();}
- </span>
http://localhost:8080/baseDemo/object_object2?name=Tom 会使得 user 和 Tom 都被注入了相同的 name 值,
结果为: User{ name='Tom', age=0, contactInfo=null } Admin{ name='Tom', age=0}
我们发现, User.name 和 Admin.name 相同,此时,我们可使用@InitBinder 注解先进行加前缀,从而区别两个name分别属于谁。
在Controller加入- @InitBinder("admin")
- public void initAdmin(WebDataBinder binder){
- binder.setFieldDefaultPrefix("admin.");
- }
- @InitBinder("user")
- public void initUser(WebDataBinder binder){
- binder.setFieldDefaultPrefix("user.");
- }
当进入一个Controller时会将含有 @InitBinder 注解的方法进行初始化,再调用对应的请求方法(指定的Controller方法)。此时使用
http://localhost:8080/baseDemo/object_object2?user.name=Tom&admin.name=Jerry&age=16
结果为: User{ name='Tom', age=16, contactInfo=null} Admin{name='Jerry',age=16}
我们发现,我们成功将 User 和 Admin 的 name 都赋值,同时由于 age没有使用
6 List集合的数据绑定。
当传递多个User 时,不可以用 List<User>users为方法参数进行接收。需要间接写一个有List<User> users 属性的类,UserForm。
- public class UserForm {
- private List<User> users;
- public List<User> getUsers() {
- return users;
- }
- public void setUsers(List<User> users) {
- this.users = users;
- }
- @Override
- public String toString() {
- return "UserForm{" +
- "users=" + users +
- '}';
- }
- }
Controller方法用UserForm 进行绑定数据
- @RequestMapping(value = "/list")
- @ResponseBody
- // List的数据绑定
- public String doList(UserForm userForm){
- return userForm.toString();
- }
传递多个User, url形式为 users[0].name=Tom&users[1].name=Jerry
访问 http://localhost:8080/baseDemo/list?users[0].name=Tom&users[1].name=Jerry
返回的UserForm.toString()显示为
UserForm{users=[User{name='Tom', age=0, contactInfo=null},User{name='Jerry', age=0, contactInfo=null}]}
此处应注意,当不对users[]集合按顺序赋值时,比如user[0]和user[5]赋值时,
访问 http://localhost:8080/baseDemo/list?users[0].name=Tom&users[21].name=Jerry
会发现输出为
UserForm{ users=[
User{name='Tom',age=0, contactInfo=null},
User{name='null', age=0, contactInfo=null},
User{name='null', age=0, contactInfo=null},
User{name='null', age=0, contactInfo=null},
User{name='null', age=0, contactInfo=null},
User{name='null', age=0,contactInfo=null},
User{name='Jerry', age=0, contactInfo=null }
] }
会导致List长度为7,有5个属性为Null,造成内存浪费。
7 Set类型的数据绑定
Set 与 List有所不同,对Set进行数据绑定的时候,需要对set进行初始化。
当Set没有初始化,与List按上述方法执行时,会抛出异常,提示Set的size为0。同时,赋值时不能越界。举个例子,同样用使用UserSetForm传递数据,
- public class UserSetForm {
- private Set<User> users;
- public UserSetForm(){
- users = new LinkedHashSet<User>();
- users.add(new User());
- users.add(new User());//需要对Set进行初始化
- }
- public Set<User> getUsers() {
- return users;
- }
- public void setUsers(Set<User> users) {
- this.users = users;
- }
- @Override
- public String toString() {
- return "UserSetForm{" +
- "users=" + users +
- '}';
- }
- }
当url请求为:
http://localhost:8080/baseDemo/set?users[0].name=Tom&users[1].name=Jerry
输出为
UserSetForm{ users= [
User{name='Tom',age=0, contactInfo=null},
User{name='Jerry', age=0, contactInfo=null}
] }
越界时,如对 users[0].name 和 users[6].name 赋值:
http://localhost:8888/baseDemo/set?users[0].name=Tom&users[6].name=Jerry
抛出异常,” Cannot get element with index 6 from Set of size 2”。即使用Set进行数据绑定时,要进行初始化,同时使用时不能越界。这是与List的区别。8. Map的数据绑定
同样用建立UserMapForm传递数据,
- public class UserMapForm {
- private Map<String,User> users;
- public Map<String, User> getUsers() {
- return users;
- }
- public void setUsers(Map<String, User> users) {
- this.users = users;
- }
- @Override
- public String toString() {
- return "UserMapForm{" +
- "users=" + users +
- '}';
- }
- }
Controller方法如下:
- @RequestMapping(value = "/map")
- @ResponseBody
- // map的数据绑定
- public String doMap(UserMapForm userMapForm){
- return userMapForm.toString();
- }
url参数形式以users[‘(key)’]索引 的形式进行赋值 如
http://localhost:8080/baseDemo/map?users[‘X’].name=Tom&users[‘Y’].name=Jerry
对 key 为 X 和 key 为 Y 分别赋值value
输出为
UserMapForm{ users={
X=User{name='Tom',age=0, contactInfo=null},
Y=User{name='Jerry', age=0, contactInfo=null}
} }
9. JSon数据绑定 添加@RequestBody 注解。此处就不需多举例了。要注意的是,之前我们举例的方法前加 @ResponseBody 注解是 让返回的数据为JSon格式。而绑定时需要在参数前加此注解。
10. xml的数据绑定。
(1) Controller 添加@RequestBody注解.
(2) 同时对传递对象添加@XmlRootElement(name=”(名称)”) 注解。在其的Getter方法添加@XmlElement(name=”名称(名称)”)的注解。
举个例子,以xml传递一个admin对象,Admin需要写成
- @XmlRootElement(name ="admin")
- public class Admin {
- private String name;
- private int age;
- @Override
- public String toString() {
- return "Admin{" +
- "name='" + name + '\'' +
- ", age=" + age +
- '}';
- }
- @XmlElement(name="name")
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- @XmlElement(name="age")
- public int getAge() {
- return age;
- }
- public void setAge(int age) {
- this.age = age;
- }
- }
Controller方法使用@RequestBody注解
- @RequestMapping(value = "/xml")
- // xml的数据绑定
- public String doXml(@RequestBody Admin admin){
- return admin.toString();
- }