SpringMVC 数据绑定流程、参数绑定、数据类型绑定、自定义数据类型
• 1. Spring MVC 主框架将 ServletRequest 对象及目标方 法的入参实例传递给 WebDataBinderFactory 实例,以创 建 DataBinder 实例对象
• 2. DataBinder 调用装配在 Spring MVC 上下文中的 ConversionService 组件进行数据类型转换、数据格式 化工作。将 Servlet 中的请求信息填充到入参对象中
• 3. 调用 Validator 组件对已经绑定了请求消息的入参对象 进行数据合法性校验,并最终生成数据绑定结果 BindingData 对象
• 4. Spring MVC 抽取 BindingResult 中的入参对象和校验 错误对象,将它们赋给处理方法的响应入参
• Spring MVC 通过反射机制对目标处理方法进行解析,将请 求消息绑定到处理方法的入参中。数据绑定的核心部件是 DataBinder,运行机制如下:
数组类型的绑定
我们查询出所有User 的信息,并且在JSP页面遍历显示,这时候点击提交按钮,需要在 Controller 中获得页面中显示 User 类的 id 的所有值的数组集合。
JSP 页面:注意用户id的name值定义为 userId
Controller.java
SpringMVC 参数绑定
在 SpringMVC 中,提交请求的数据是通过方法形参来接收的。从客户端请求的 key/value 数据,经过参数绑定,将 key/value 数据绑定到 Controller 的形参上,然后在 Controller 就可以直接使用该形参。
这里涉及到参数绑定组件,那么什么是参数组件,这里可以先理解为将请求的数据转换为我们需要的数据称为参数绑定组件,也就是参数绑定转换器。SpringMVC 内置了很多参数转换器,只有在极少数情况下需要我们自定义参数转换器。
默认支持的类型
SpringMVC 有支持的默认参数类型,我们直接在形参上给出这些默认类型的声明,就能直接使用了。如下:
①、HttpServletRequest 对象
②、HttpServletResponse 对象
③、HttpSession 对象
④、Model/ModelMap 对象
Controller 代码:
@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;
}
表单代码:(截取主要代码)
<body>
request:${requestParameter}
session:${sessionParameter}
model:${modelParameter}
modelMap:${modelMapParameter}
</body>
注意:Model/ModelMap,ModelMap是Model接口的一个实现类,作用是将Model数据填充到request域,即使使用Model接口,其内部绑定还是由ModelMap来实现
基本数据类型的绑定
基本数据类型:
-
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 页面代码:
<form action="basicData" method="post">
<input name="username" value="10" type="text"/>
<input type="submit" value="提交">
</form>
Controller 代码:
@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或”",所以,在开发过程中,对可能为空的数据,最好将参数数据类型定义成包装类型,具体参见下面的例子。
包装数据类型的绑定
包装类型如Integer、Long、Byte、Double、Float、Short,(String 类型在这也是适用的)
以 Integer 为例
Controller 代码为:
和基本数据类型基本一样,不同之处在于,表单传递过来的数据可以为null或”",以上面代码为例,如果表单中num为”"或者表单中无num这个input,那么,Controller方法参数中的num值则为null。
自定义转换器
需要自定义Date类型的转换器。
①、定义由String类型到 Date 类型的转换器
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 文件中配置转换器
<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>
注意事项
form表单无法提交input输入框属性设置为 disabled 的内容,比如:
<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的情况下,表单输入项不能获得焦点,用户的所有操作无意义,在提交表单时,表单输入项不会被提交。