springMVC的数据绑定

来源:互联网 发布:图片上传java 编辑:程序博客网 时间:2024/05/18 18:55

1、基本数据类型

    @RequestMapping(value = "/base.do",method = RequestMethod.POST)    @ResponseBody    public String testBaseData(@RequestParam(value = "xage",defaultValue = "10",required = false) int age){        return "age:"+age;    }

method = RequestMethod.POST表示只接受post类型的请求,不加该属性表示所有类型的请求都可以处理@RequestParam(value = "xage",defaultValue = "10",required = false)中value表示age属性的别名,前台传过来的需要时xage而不是age(localhost:8080/base.do?xage=10),defaultvalue表示age的默认值,不添加表示没有默认值,required表示age是否必须传,设置为true时如果不传则会报错

@RequestMapping注解中的value属性也可以是一个数组,如value={"/base.do","/base2.do"}

如果不加@RequestParam注解,则前台传过来的需要是age属性:http://localhost:8080/base.do?age=10,另外基本数据类型在传值时如果没传则会报如下异常:

如果是简单类型的封住类则可以不传,结果为age:null

2、包装类&数组

    @RequestMapping("/array.do")    @ResponseBody    public String testArray(String[] name){        StringBuilder builder=new StringBuilder();        for(String str:name){            builder.append(str);        }        return builder.toString();    }
http://localhost:8080/array.do?name=jim&name=tom&name=bob

或者在表单中有多个name属性为“name”的<input>标签

如果不传值的话会报以下异常:


3、简单对象

public class User {    private Integer age;    private String name;    public Integer getAge() {        return age;    }    public void setAge(Integer age) {        this.age = age;    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    @Override    public String toString() {        return "User{" +                "age=" + age +                ", name='" + name + '\'' +                '}';    }}
    @RequestMapping("/simpleObject.do")    @ResponseBody    public String testSimpleObject(User user){        return user.toString();    }

http://localhost:8080/simpleObject.do   :返回的结果为:User{age=null, name='null'},不会报空指针异常,因为user类中的字段都是封装类型,如果把age字段改为int类型,会报异常吗?返回的结果为:User{age=0, name='null'},没有报异常,因为在User对象实例化的时候,会给基本数据类型赋初值,int类型的初值为0

http://localhost:8080/simpleObject.do?age=10&name=aaa   :返回的结果为:User{age=10, name='aaa'}

http://localhost:8080/Object.do?user.name=tom&user.age=10 : 返回的结果为:User{age=0, name='null'},

数据不会象想象中传入age和name属性中,所以给对象的属性传值需要传入该对象的属性名,而不能自作聪明的使用‘对象名.属性名'的方式

4、多层级对象

public class User {    private int age;    private String name;    private Address address;    public Address getAddress() {        return address;    }    public void setAddress(Address address) {        this.address = address;    }    public int getAge() {        return age;    }    public void setAge(int age) {        this.age = age;    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    @Override    public String toString() {        return "User{" +                "age=" + age +                ", name='" + name + '\'' +                ", address=" + address +                '}';    }}

public class Address {    private String provice;    private String city;    public String getProvice() {        return provice;    }    public void setProvice(String provice) {        this.provice = provice;    }    public String getCity() {        return city;    }    public void setCity(String city) {        this.city = city;    }    @Override    public String toString() {        return "Address{" +                "provice='" + provice + '\'' +                ", city='" + city + '\'' +                '}';    }}
    @RequestMapping("/Object.do")    @ResponseBody    public String testObject(User user){        return user.toString();    }

多层级对象传值时要用:该对象包含的对象的属性名 包含的对象的属性

5、同属性多对象

public class Admin {    private int age;    private String name;    private Address address;    @Override    public String toString() {        return "Admin{" +                "age=" + age +                ", name='" + name + '\'' +                ", address=" + address +                '}';    }    public int getAge() {        return age;    }    public void setAge(int age) {        this.age = age;    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public Address getAddress() {        return address;    }    public void setAddress(Address address) {        this.address = address;    }}

在以前的基础上加上Admin类,与User类有相同的属性,Action如下:

    @RequestMapping("/object2.do")    @ResponseBody    public String testObject2(User user, Admin admin){        return user.toString()+"  "+admin.toString();    }
① 访问URL如下:http://localhost:8080/object2.do?name=tom&age=10 页面显示结果如下:User{age=10, name='tom', address=null} Admin{age=10, name='tom', address=null}

可以看到属性相同是会共享的,
② 访问URL如下:http://localhost:8080/object2.do?user.name=tom&admin.age=10 页面显示结果如下:User{age=0, name='null', address=null} Admin{age=0, name='null', address=null}

可以看到这种方法是行不通的,数据不会象想象中传入age和name属性中,所以给对象的属性传值需要传入该对象的属性名,而不能自作聪明的使用‘对象名.属性名'的方式

③ 在controller中添加方法如下:

    @InitBinder("user")    public void initUser(WebDataBinder binder){        binder.setFieldDefaultPrefix("user.");    }    @InitBinder("admin")    public void initAdmin(WebDataBinder binder){        binder.setFieldDefaultPrefix("admin.");    }
访问URL如下:http://localhost:8080/object2.do?user.name=tom&admin.age=10   页面显示结果如下:User{age=0, name='tom', address=null} Admin{age=10, name='null', address=null}
程序运行到controller的时候,会先运行@InitBinder("...")注解的方法给对应的对象的属性加上传递值时对应的前缀做以区分同属性的多对象

6、list集合

①list集合不能如下进行参数绑定:

    @RequestMapping("/list.do")    @ResponseBody    public String list(List<User> userList){        return userList.toString();    }
这种情况下会出现如下异常:Could not instantiate bean class [java.util.List]: Specified class is an interface这个异常

②构建一个含有list<User>类型属性的封装vo如下:

public class UserVo {    private List<User> users;    public List<User> getUsers() {        return users;    }    public void setUsers(List<User> users) {        this.users = users;    }    @Override    public String toString() {        return "UserVo{" +                "users=" + users +                '}';    }}
然后通过传递UserVo对象来进行数据绑定:
    @RequestMapping("/list.do")    @ResponseBody    public String list(UserVo userVo){        return userVo.toString();    }
访问URL为:localhost:8080/list.do?users[0].name=tom&users[1].address.city=beijing

页面呈现结果为:UserVo{users=[User{age=0, name='tom', address=null}, User{age=0, name='null', address=Address{provice='null', city='beijing'}}]}

那我们碰到第一种情况怎么办呢?把它变成第二种方式进行处理,也就是说新建一个包装类专门来包装类似的需要接收的list参数。

为什么第一种方式不行了?

因为spring mvc 中获取参数的方式不管有多少种,他的本质依然是

request.getParameter("name")

那把这个参数封装到一个对象中,也只能是同setter方法,那问题的关键是如何找到这个setter方法?肯定是setName中的name和request中的name对应。这才能找到。你想,如果你单纯接收一个list参数,list虽然有get和set方法,但是没有名字呀,只能根据数组下标来判断参数位置。所以只能通过第二种方法进行参数传递

7、map集合① 首先构建一个封装vo

public class UserMapVo {    private Map<String, User> users;    @Override    public String toString() {        return "UserMapVo{" +                "users=" + users +                '}';    }    public Map<String, User> getUsers() {        return users;    }    public void setUsers(Map<String, User> users) {        this.users = users;    }}
② 编写action
    @RequestMapping("/map.do")    @ResponseBody    public String map(UserMapVo userMapVo){        return userMapVo.toString();    }
③ 访问URL如下形式:http://localhost:8080/map.do?users['X'].name=tom&users['Y'].age=10

④ 页面呈现结果如下:UserMapVo{users={X=User{age=0, name='tom', address=null}, Y=User{age=10, name='null', address=null}}}
8、json
要使用json首先要提供jar包支持:
    <!-- 用于支持json -->    <dependency>      <groupId>org.codehaus.jackson</groupId>      <artifactId>jackson-mapper-asl</artifactId>      <version>1.9.12</version>    </dependency>

传递json数据时,是把json放在RequestBody里面,利用@RequestBody注解将RequestBody数据域里面的的json数据反序列化为JavaBean的对象里面的属性的值

request的context-type需要改为:application/json

    @RequestMapping("/textjson.do")    @ResponseBody    public String textjson(@RequestBody User user){        return user.toString();    }
传递的json数据为:

{    "age": 10,    "name": "tom",    "address": {        "provice": "广东",        "city": "深圳"    }}   注意:如果传递的json数据里面的某一个属性名在对应的Javabean里面没有,会报400错误
页面上显示的结果为:User{age=10, name='tom', address=Address{provice='广东', city='深圳'}}


9、xml


① 要使用xml,首先需要jar包支持:

    <!-- 对xml提供支持,里面提供了xml的序列化和反序列化 -->    <dependency>      <groupId>org.springframework</groupId>      <artifactId>spring-oxm</artifactId>      <version>${org.springframework.version}</version>    </dependency>
② 其次需要在对应的Javabean上添加注解如下:

@XmlRootElement(name = "admin")public class Admin {    private int age;    private String name;    private Address address;    @Override    public String toString() {        return "Admin{" +                "age=" + age +                ", name='" + name + '\'' +                ", address=" + address +                '}';    }    @XmlElement(name = "age")    public int getAge() {        return age;    }    public void setAge(int age) {        this.age = age;    }    @XmlElement(name = "name")    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    @XmlElement(name = "address")    public Address getAddress() {        return address;    }    public void setAddress(Address address) {        this.address = address;    }}
@XmlRootElement(name = "address")public class Address {    private String provice;    private String city;    @XmlElement(name = "provice")    public String getProvice() {        return provice;    }    public void setProvice(String provice) {        this.provice = provice;    }    @XmlElement(name = "city")    public String getCity() {        return city;    }    public void setCity(String city) {        this.city = city;    }    @Override    public String toString() {        return "Address{" +                "provice='" + provice + '\'' +                ", city='" + city + '\'' +                '}';    }}
注意:Admin类上的注解必须要有,否则会报415错误,类下面的属性包括类对象属性对应的类上的注解都可以不加

action编写如下,(依然要用@RequestBody注解,如果不加该注解,不会报错,但是数据不会匹配到对应的Javabean上):

    @RequestMapping("/xml.do")    @ResponseBody    public String xml(@RequestBody Admin admin){        return admin.toString();    }

③ 设置请求的context-type为:application/xml

传递的xml数据如下:

<?xml version="1.0" encoding="UTF-8"?><admin>    <age>12</age>    <name>tom</name>    <address>        <provice>广东</provice>        <city>深圳</city>    </address></admin>
页面返回的结果如下:Admin{age=12, name='tom', address=Address{provice='广东', city='深圳'}}





 
原创粉丝点击