博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
五、参数绑定
阅读量:5750 次
发布时间:2019-06-18

本文共 7880 字,大约阅读时间需要 26 分钟。

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的情况下,表单输入项不能获得焦点,用户的所有操作无意义,在提交表单时,表单输入项不会被提交。

转载于:https://www.cnblogs.com/zhoanghua/p/9292242.html

你可能感兴趣的文章
rhel6.8安装elasticsearch-6.1.3.tar.gz遇到的问题以及集群配置
查看>>
文本文件命令(wc,cut,sort,uniq)及常用参数
查看>>
IIS默认网站密码解决办法
查看>>
23. PowerShell -- 定义文本,密码和用户交互处理
查看>>
我的友情链接
查看>>
Tomcat的性能与最大并发(1000)
查看>>
正弦定理、余弦定理
查看>>
IT人的自我导向型学习:学习的1个理念和2个心态(1)
查看>>
Eclipse有用的快捷键
查看>>
Bitlocker企业安全加密管理系列-2
查看>>
关于rip的跳数
查看>>
最短无序连续子数组 Shortest Unsorted Continuous Subarray
查看>>
MariaDB-SQL语句
查看>>
SQL: DDL, DML,表定义与含义
查看>>
Java并发笔记(未完待续)
查看>>
我的友情链接
查看>>
HP iLO There are pending changes that may not take effect until ILO is reset
查看>>
如何生成linux动态库
查看>>
关于switchport Port-security 使用遇到的一些问题
查看>>
我的友情链接
查看>>