SpringMVC详解------参数绑定

目录


  参数绑定,简单来说就是客户端发送请求,而请求中包含一些数据,那么这些数据怎么到达 Controller ?这在实际项目开发中也是用到的最多的,那么 SpringMVC 的参数绑定是怎么实现的呢?下面我们来详细的讲解。

1、SpringMVC 参数绑定

  在 SpringMVC 中,提交请求的数据是通过方法形参来接收的。从客户端请求的 key/value 数据,经过参数绑定,将 key/value 数据绑定到 Controller 的形参上,然后在 Controller 就可以直接使用该形参。

  

  这里涉及到参数绑定组件,那么什么是参数组件,这里可以先理解为将请求的数据转换为我们需要的数据称为参数绑定组件,也就是参数绑定转换器。SpringMVC 内置了很多参数转换器,只有在极少数情况下需要我们自定义参数转换器。

回到顶部

2、默认支持的类型

  SpringMVC 有支持的默认参数类型,我们直接在形参上给出这些默认类型的声明,就能直接使用了。如下:

  ①、HttpServletRequest 对象

  ②、HttpServletResponse 对象

  ③、HttpSession 对象

  ④、Model/ModelMap 对象 

  Controller 代码:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

@RequestMapping("/defaultParameter")

    public ModelAndView defaultParameter(HttpServletRequest request,HttpServletResponse response,

                            HttpSession session,Model model,ModelMap modelMap) throws Exception{

        request.setAttribute("requestParameter""request类型");

        response.getWriter().write("response");

        session.setAttribute("sessionParameter""session类型");

        //ModelMap是Model接口的一个实现类,作用是将Model数据填充到request域

        //即使使用Model接口,其内部绑定还是由ModelMap来实现

        model.addAttribute("modelParameter""model类型");

        modelMap.addAttribute("modelMapParameter""modelMap类型");

        

        ModelAndView mv = new ModelAndView();

        mv.setViewName("view/success.jsp");

        return mv;

    }

  表单代码:(截取主要代码)

1

2

3

4

5

6

<body>

    request:${requestParameter}

    session:${sessionParameter}

    model:${modelParameter}

    modelMap:${modelMapParameter}

</body>

  然后访问,页面显示如下:

  

  这里我们重点说一下 Model/ModelMap,ModelMap是Model接口的一个实现类,作用是将Model数据填充到request域,即使使用Model接口,其内部绑定还是由ModelMap来实现

3、基本数据类型的绑定

  哪些是基本数据类型,我们这里重新总结一下: 

1

2

3

4

5

6

7

8

9

一、byte,占用一个字节,取值范围为 -128-127,默认是“\u0000”,表示空

二、short,占用两个字节,取值范围为 -32768-32767

三、int,占用四个字节,-2147483648-2147483647

四、long,占用八个字节,对 long 型变量赋值时必须加上"L"或“l”,否则不认为是 long 

五、float,占用四个字节,对 float 型进行赋值的时候必须加上“F”或“f”,如果不加,会产生编译错误,因为系统

自动将其定义为 double 型变量。double转换为float类型数据会损失精度。float a = 12.23产生编译错误的,float a = 12是正确的

六、double,占用八个字节,对 double 型变量赋值的时候最好加上“D”或“d”,但加不加不是硬性规定

七、char,占用两个字节,在定义字符型变量时,要用单引号括起来

八、boolean,只有两个值“true”和“false”,默认值为false,不能用0或非0来代替,这点和C语言不同

  我们以 int 类型为例:

  JSP 页面代码:

1

2

3

4

<form action="basicData" method="post">

    <input name="username" value="10" type="text"/>

    <input type="submit" value="提交">

</form>

  Controller 代码:

1

2

3

4

@RequestMapping("/basicData")

    public void basicData(int username){

        System.out.println(username);//10

    }

  结果是 打印出了表单里面的 value 的值。

  注意:表单中input的name值和Controller的参数变量名保持一致,就能完成数据绑定。那么如果不一致呢?我们使用 @RequestParam 注解来完成,如下:

  JSP页面代码不变,<input name="username">保持原样,Controller 代码如下

  

  使用注解 @RequestParam ,我们可以使用任意形参,但是注解里面的 value 属性值要和表单的name属性值一样。

  问题:我们这里的参数是基本数据类型,如果从前台页面传递的值为 null 或者 “”的话,那么会出现数据转换的异常,就是必须保证表单传递过来的数据不能为null或”",所以,在开发过程中,对可能为空的数据,最好将参数数据类型定义成包装类型,具体参见下面的例子。

4、包装数据类型的绑定

  包装类型如Integer、Long、Byte、Double、Float、Short,(String 类型在这也是适用的)这里我们以 Integer 为例

  Controller 代码为:

  

  和基本数据类型基本一样,不同之处在于,表单传递过来的数据可以为null或”",以上面代码为例,如果表单中num为”"或者表单中无num这个input,那么,Controller方法参数中的num值则为null。

5、POJO(实体类)类型的绑定

  User.java

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

package com.ys.po;

import java.util.Date;

public class User {

    private Integer id;

    private String username;

    private String sex;

    private Date birthday;

    public Integer getId() {

        return id;

    }

    public void setId(Integer id) {

        this.id = id;

    }

    public String getUsername() {

        return username;

    }

    public void setUsername(String username) {

        this.username = username == null null : username.trim();

    }

    public String getSex() {

        return sex;

    }

    public void setSex(String sex) {

        this.sex = sex == null null : sex.trim();

    }

    public Date getBirthday() {

        return birthday;

    }

    public void setBirthday(Date birthday) {

        this.birthday = birthday;

    }

}

  JSP页面:注意输入框的 name 属性值和上面 POJO 实体类的属性保持一致即可映射成功。

1

2

3

4

5

6

7

<form action="pojo" method="post">

        用户id:<input type="text" name="id" value="2"></br>

        用户名:<input type="text" name="username" value="Marry"></br>

        性别:<input type="text" name="sex" value="女"></br>

        出生日期:<input type="text" name="birthday" value="2017-08-25"></br>

        <input type="submit" value="提交">

    </form>

  注意看:这里面我们数据都写死了,直接提交。有Integer类型的,String类型的,Date类型的。

  Controller :

1

2

3

4

@RequestMapping("/pojo")

    public void pojo(User user){

        System.out.println(user);

    }

  我们在上面代码打个断点,然后输入URL,进入到这个Controller中:

  上面是报错了,User.java 的birthday 属性是 Date 类型的,而我们输入的是字符串类型,故绑定不了

  那么问题来了,Date 类型的数据绑定失败,如何解决这样的问题呢?这就是我们前面所说的需要自定义Date类型的转换器。

  ①、定义由String类型到 Date 类型的转换器

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

package com.ys.util;

import java.text.ParseException;

import java.text.SimpleDateFormat;

import java.util.Date;

import org.springframework.core.convert.converter.Converter;

//需要实现Converter接口,这里是将String类型转换成Date类型

public class DateConverter implements Converter<String, Date> {

    @Override

    public Date convert(String source) {

        //实现将字符串转成日期类型(格式是yyyy-MM-dd HH:mm:ss)

        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        try {

            return dateFormat.parse(source);

        catch (ParseException e) {

            // TODO Auto-generated catch block

            e.printStackTrace();

        }

        //如果参数绑定失败返回null

        return null;

    }

}

  ②、在 springmvc.xml 文件中配置转换器

1

2

3

4

5

6

7

8

<mvc:annotation-driven conversion-service="conversionService"></mvc:annotation-driven>

    

    <bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">

        <property name="converters">

            <!-- 自定义转换器的类名 -->

            <bean class="com.ys.util.DateConverter"></bean>

        </property>

    </bean>

  输入 URL,再次查看Controller的形参:

  

6、复合POJO(实体类)类型的绑定

  这里我们增加一个实体类,ContactInfo.java

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

package com.ys.po;

public class ContactInfo {

    private Integer id;

    private String tel;

    private String address;

    public Integer getId() {

        return id;

    }

    public void setId(Integer id) {

        this.id = id;

    }

    public String getTel() {

        return tel;

    }

    public void setTel(String tel) {

        this.tel = tel == null null : tel.trim();

    }

    public String getAddress() {

        return address;

    }

    public void setAddress(String address) {

        this.address = address == null null : address.trim();

    }

}

  然后在上面的User.java中增加一个属性 private ContactInfo contactInfo

  

  JSP 页面:注意属性name的命名,User.java 的复合属性名.字段名

   

      

  Controller

  

  User对象中有ContactInfo属性,但是,在表单代码中,需要使用“属性名(对象类型的属性).属性名”来命名input的name。

7、数组类型的绑定

  需求:我们查询出所有User 的信息,并且在JSP页面遍历显示,这时候点击提交按钮,需要在 Controller 中获得页面中显示 User 类的 id 的所有值的数组集合。

  JSP 页面:注意用户id的name值定义为 userId

  

  Controller.java

  

8、List类型的绑定

  需求:批量修改 User 用户的信息

  第一步:创建 UserVo.java,封装 List<User> 属性

1

2

3

4

5

6

7

8

9

10

11

12

13

14

package com.ys.po;

import java.util.List;

public class UserVo {

    private List<User> userList;

    public List<User> getUserList() {

        return userList;

    }

    public void setUserList(List<User> userList) {

        this.userList = userList;

    }

}

  第二步:为了简化过程,我们直接从 Controller 中查询所有 User 信息,然后在页面显示

  Controller

1

2

3

4

5

6

7

8

@RequestMapping("selectAllUserAndList")

    public ModelAndView selectAllUserAndList(){

        List<User> listUser = userService.selectAllUser();

        ModelAndView mv = new ModelAndView();

        mv.addObject("listUser", listUser);

        mv.setViewName("list.jsp");

        return mv;

    }

  JSP 页面

  第三步:修改页面的值后,点击提交

  

  由于我们在 JSP 页面 input 输入框定义的name属性名是 userList[${status.index}].id 这种形式的,这里我们直接用 UserVo 就能获取页面批量提交的 User信息

8、Map类型的绑定

  首先在 UserVo 里面增加一个属性 Map<String,User> userMap

  

  第二步:JSP页面,注意看 <input >输入框 name 的属性值

  

  第三步:Controller 中获取页面的属性

9、遇到的问题

  ①、form表单无法提交input输入框属性设置为 disabled 的内容

  比如:

1

<input type="text" disabled="disabled" name="metadataName"   maxlength="50" placeholder="这里输入模型英文名称" title="模型英文名称" "/>

  具有 disabled="disabled" 的属性,提交到 Controller后,metadataName 的值为null

  解决办法:改为 readonly="readonly"

  readonly:针对input(text / password)和textarea有效,在设置为true的情况下,用户可以获得焦点,但是不能编辑,在提交表单时,输入项会作为form的内容提交。

  disabled:针对所有表单元素(select,button,input,textarea等),在设置为disabled为true的情况下,表单输入项不能获得焦点,用户的所有操作无意义,在提交表单时,表单输入项不会被提交。

SpringMVC详解------参数绑定的更多相关文章

  1. SpringMVC详解一、@RequestMapping注解与Controller接收参数

    SpringMVC详解一.@RequestMapping注解与Controller接收参数 https://blog.csdn.net/mxcsdn/article/details/80719258 ...

  2. 第5章—构建Spring Web应用程序—SpringMVC详解

    SpringMVC详解 5.1.跟踪Springmvc的请求 SpringMVC的核心流程如下: 具体步骤: 第一步:发起请求到前端控制器(DispatcherServlet) 第二步:前端控制器请求 ...

  3. springmvc的初始化参数绑定

    一.springmvc的初始化参数绑定 此种和我们之前说的类型转换非常相似,可以看作是一种类型转换 在初始化参数绑定时  重要的是参数类型 -------------------单日期的绑定 二. 配 ...

  4. [Spring MVC] - SpringMVC的各种参数绑定方式

    SpringMVC的各种参数绑定方式 1. 基本数据类型(以int为例,其他类似):Controller代码: @RequestMapping("saysth.do") publi ...

  5. SpringMVC的各种参数绑定方式

    1. 基本数据类型(以int为例,其他类似):2. 包装类型(以Integer为例,其他类似):3. 自定义对象类型:4. 自定义复合对象类型:5. List绑定:6. Set绑定:7. Map绑定: ...

  6. [转载]SpringMVC的Model参数绑定方式

    SpringMVC的各种参数绑定方式 http://www.cnblogs.com/HD/p/4107674.html springMVC中复杂嵌套对象.List等集合类型数据绑定 http://ww ...

  7. SpringMVC介绍及参数绑定

    本节内容: SpringMVC介绍 入门程序 SpringMVC架构 SpringMVC整合MyBatis 参数绑定 SpringMVC和Struts2的区别 一.SpringMVC介绍 1. 什么是 ...

  8. 【Kafka】Kafka-配置参数详解-参数调优

    Kafka-配置参数详解-参数调优 kafka 目录_百度搜索 为什么kafka使用磁盘而不是内存 - CSDN博客 Kafka 配置说明 - 風吹云动 - 博客园 kafka生产服务器配置 - Or ...

  9. SpringMVC中的参数绑定总结

    众所周知,springmvc是用来处理页面的一些请求,然后将数据再通过视图返回给用户的,前面的几篇博文中使用的都是静态数据,为了能快速入门springmvc,在这一篇博文中,我将总结一下springm ...

随机推荐

  1. Vue 从入门到进阶之路(十四)

    之前的文章我们对 vue 的基础用法已经有了很直观的认识,本章我们来看一下 vue 中的生命周期函数. 上图为 Vue官方为我们提供的完整的生命周期函数的流程图,下面的案例我们只是走了部分情况流程,但 ...

  2. vue获取后端数据放在created还是mounted方法里面?

    问题提出: 我们知道一般vue使用ajax或者axios来获取后端数据,并且好像放在created里面和mounted里面都可以获取数据并正确渲染.那么放在created里面和mounted里面有什么 ...

  3. maven中servlet报错:不识别此servlet问题的解决办法

    原因 使用maven集成的tomcat插件的时候,tomcat的lib中,自带servlet-api和jsp. 如果maven中再次导入了这两个jar,会造成jar包冲突现象. 解决办法 我们只是想编 ...

  4. C# show Environment property info name and value retrieve, Maximize the Console Window based on window resolution

    using System.Reflection; static void ShowEnvironmentInfoDemo() { Type type = typeof(Environment); Pr ...

  5. 【重学Git】基础命令篇

    1.git commit :在提交树中增加一个提交节点,注意:分支是指向提交节点的. 2.git branch newImage : 表示创建一个名为newImage的分支. 3.git checko ...

  6. IntelliJ IDEA中你应该知道的快捷键

    IDEA官方所有快捷键:参考:https://resources.jetbrains.com/storage/products/intellij-idea/docs/IntelliJIDEA_Refe ...

  7. css字体标签相关

    斜体: i:斜体em:斜体,强调的意思,有特殊含义,尽量用i或者cssfont-style:字体风格 normal默认值,italic斜体,oblique倾斜的字体 粗体: b,strong:粗体fo ...

  8. oracle数据库自动生成数据库表结构文档(亲测有效)

    import java.awt.Color; import java.io.FileOutputStream; import java.sql.Connection; import java.sql. ...

  9. Linux 和 Windows 查看当前运行的 python 进程及 GPU、CPU、磁盘利用率

    目录 查看当前 python 进程 Linux Windows 查看 GPU 利用率 Linux Windows Linux CPU 利用率 Linux 磁盘利用率 查看当前 python 进程 Li ...

  10. 四、读取一系列dcm图片,然后重新写入

    一.程序功能 读取一系列的CT dcm图片,然后重新写入到一个文件夹 二.代码 #pragma warning(disable:4996) #include "itkGDCMImageIO. ...