数据绑定
在执行程序时,Spring MVC会根据客户端请求参数的不同,将请求消息中的信息以一定的方式转换并绑定到控制器类的方法参数中。这种将请求消息数据与后台方法参数建立连接的过程就是Spring MVC中的数据绑定。
数据绑定流程
-
Spring MVC将ServletRequest对象传递给DataBinder;
-
将处理方法的入参对象传递给DataBinder;
-
DataBinder调用ConversionService组件进行数据类型转换、数据格式化等工作,并将ServletRequest对象中的消息填充到参数对象中;
-
调用Validator组件对已经绑定了请求消息数据的参数对象进行数据合法性校验;
根据客户端请求参数类型和个数的不同,我们将Spring MVC中的数据绑定主要分为简单数据绑定和复杂数据绑定
简单类型数据绑定
常见默认参数类型:
- HttpServletRequest:通过request对象获取请求信息;
- HttpServletResponse:通过response处理响应信息;
- HttpSession:通过session对象得到session中存放的对象;
- Model/ModelMap:Model是一个接口,ModelMap是一个接口实现,作用是将model数据填充到request域。
java类型 String(基本类型) form表单 name="attr" value="val" AJAX:data{"attr":"val"} Controller类: @RequestParam(value="user_id")Integer id
@RequestMapping("/selectUser")
public String selectUser(HttpServletRequest request) {
String id = request.getParameter("id");
System.out.println("id="+id);
return "success";
}
前端请求中参数名和后台控制器类方法中的形参名不一样的情况,可以考虑使用Spring MVC提供的@RequestParam注解类型来进行间接数据绑定。前端请求中参数名和后台控制器类方法中的形参名不一样的情况,可以考虑使用Spring MVC提供的@RequestParam注解类型来进行间接数据绑定。
@RequestParam注解的属性声明如下:
@RequestMapping("/selectUser")
public String selectUser(@RequestParam(value="user_id")Integer id) {
System.out.println("id="+id);
return "success";
}
绑定pojo类型
针对多类型、多参数的请求,可以使用POJO类型进行数据绑定。
POJO类型的数据绑定就是将所有关联的请求参数封装在一个POJO中,然后在方法中直接使用该POJO作为形参来完成数据绑定。
在使用POJO类型数据绑定时,前端请求的参数名(本例中指form表单内各元素的name属性值)必须与要绑定的POJO类中的属性名一样
Object(实体类) form表单 对应PO类属性名称 name="attr" value="val" name="attr1" value="val1" Controller类: public String registerUser(User user)
public String registerUser(User user) {
String username = user.getUsername();
Integer password = user.getPassword();
return "success";
}
绑定数组
在处理多个相同类型数据时使用,例如提交多个用户数据:
List类型 form表单 name="attr[0]" value="val1" name="attr[1]" value="val2" Ajax:data{"attr[0]":"val1","attr[1]":"val2"} @RequestParam("attr") String[] s 或自定义类:String attr[]
<c:forEach items="${itemList}" var="item" varStatus="status">
<tr>
<td> <input type="hidden" name="itemList[${status.index}].itemsId" value="${item.itemId}"/></td>
<td> <input type="text" name="itemList[${status.index}].itemsName" value="${item.itemsName}"/></td>
</tr>
</c:forEach>
@RequestMapping("/deleteUsers")
public String deleteUsers(Integer[] ids) {
if(ids !=null){
for (Integer id : ids) {
System.out.println("删除了id为"+id+"的用户!");
}
}else{
System.out.println("ids=null");
}
return "success";
}
绑定集合
Map类型 form表单 name="map[key1].attr” value=”val1” name=”map[key2].attr" value="val2" AJAX:data{"map[key1].attr":"val1","map[key2].attr":"val2"} Controller类: 封装在另一个自定义类里:Map<String,Object> map
private Map<String,Object>mapuser;
public void setMapuser(Map<String, Object> mapuser) {
this.mapuser = mapuser;
}
public Map<String, Object> getMapuser() {
return mapuser;
}
Controler类定义方法返回一个Map类型
自定义类型绑定
开发者自定义转换器(Converter)或格式化(Formatter)来进行数据绑定。
Spring框架提供了一个Converter用于将一种类型的对象转换为另一种类型的对象。
自定义Converter类需要实现org.springframework.core.convert.converter.Converter接口。
Formatter与Converter的作用相同,只是Formatter的源类型必须是一个String类型,而Converter可以是任意类型。
使用Formatter自定义转换器类需要实现org.springframework.format.Formatter接口。
public interface Converter<S, T> {
T convert(S source);
}
public interface Formatter<T> extends Printer<T>, Parser<T> {}
public class DateConverter implements Converter<String, Date> {
// 定义日期格式
private String datePattern = "yyyy-MM-dd HH:mm:ss";
@Override
public Date convert(String source) {
// 格式化日期
SimpleDateFormat sdf = new SimpleDateFormat(datePattern);
try {
return sdf.parse(source);
} catch (ParseException e) {
throw new IllegalArgumentException(
"无效的日期格式,请使用这种格式:"+datePattern);
}
}
}
public class DateFormatter implements Formatter<Date>{
// 定义日期格式
String datePattern = "yyyy-MM-dd HH:mm:ss";
// 声明SimpleDateFormat对象
private SimpleDateFormat simpleDateFormat;
@Override
public String print(Date date, Locale locale) {
return new SimpleDateFormat().format(date);
}
@Override
public Date parse(String source, Locale locale) throws ParseException
{
simpleDateFormat = new SimpleDateFormat(datePattern);
return simpleDateFormat.parse(source);
}
}