一、数据绑定
在web应用中,如何将页面的值传递给控制器,是很重要的一个内容,这就是数据绑定。
SpringMVC中的数据绑定非常简单。因为SpringMVC的每个请求指向的都是方法,那么页面的数据直接和方法的形参对应,数据绑定就实现了。常用的数据绑定方式(或者说形参样式)有两种:
- 基本类型的数据绑定,如String、int等;
- POJO类型的数据绑定。
(一)基本类型的数据绑定
基本类型的数据绑定,使用@RequestParam注解来实现,如下:
@RequestMapping(value="/saveProduct")
public ModelAndView saveProduct(@RequestParam(value="name",required=true) String name,@RequestParam String description,@RequestParam String price){
product.setName(name);
product.setDescription(description);
product.setPrice(price);
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("product", product);
modelAndView.setViewName("productDetails");
return modelAndView;
}
@RequestParam注解的value属性指定了页面传入参数的名称,如果没有指定该属性,则页面传入的参数名称必须和方法的形参名称一样,否则无法接收到值;
required属性指定了页面必须传入该参数,否则就会报错。
(二)POJO类型的数据绑定
POJO类型的数据绑定更加简单了,不需要写任何注解,如下:
@RequestMapping(value="/saveProduct1")
public ModelAndView saveProduct1(Product product){
logger.info("saveProduct1 been called!");
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject("product", product);
modelAndView.setViewName("productDetails");
return modelAndView;
}
因为SpringMVC的每个请求指向的都是方法,所以页面传递值过来时,会去Product类中去寻找相应的属性,如果找不到属性则会报错。注意,POJO类中的属性都必须有相应的getter/setter方法。
在给Product类添加Date类型的createTime属性之前,上述过程是没有问题的。但是,在添加了createTime属性之后,就会报错,报错的原因是:web应用中,从页面传递回来的数据都是String类型的,进行数据绑定时如果类型不同就会报错。这里就涉及到了类型转换。
二、类型转换
在SpringMVC中,类型转换有两种方法。
(一)Converter
Converter是一个接口,实现了该接口的类可以将任意类型转换成另一种指定的类型的对象。下面的StringToDateConverter类可以将字符串类型转换成Date类型。
package converter;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.springframework.core.convert.converter.Converter;
public class StringToDateConverter implements Converter<String,Date> {
@Override
public Date convert(String dateString) {
// TODO Auto-generated method stub
SimpleDateFormat date = new SimpleDateFormat("YYYY-MM-DD HH:mm:ss");
try {
return date.parse(dateString);
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}
要使用Converter,需要在SpringMVC的配置文件(在本例中时springmvc1.xml)做如下配置:
<mvc:annotation-driven conversion-service="conversionService"></mvc:annotation-driven>
<!-- 配置转换器Converter -->
<bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
<property name="converters">
<list>
<bean class="converter.StringToDateConverter"></bean>
</list>
</property>
</bean>
(二)Formatter
Formatter只能将String类型转换成其他指定类型的对象。因为web层中,页面传递的都是String类型的,所以Formatter是适合的。下面的类同样将字符串转换成Date类型的对象。
package formatter;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import org.springframework.format.Formatter;
public class DateFormatter implements Formatter<Date> {
@Override
public String print(Date date, Locale arg1) {
// TODO Auto-generated method stub
return null;
}
@Override
public Date parse(String dateStr, Locale local) throws ParseException {
// TODO Auto-generated method stub
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
try{
return sdf.parse(dateStr);
}
catch(Exception e){
e.printStackTrace();
}
return null;
}
}
要使用Formatter,需要在SpringMVC的配置文件(在本例中时springmvc1.xml)做如下配置:
<mvc:annotation-driven conversion-service="conversionService"></mvc:annotation-driven>
<!-- 配置转换器Formatter -->
<bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
<property name="formatters">
<list>
<bean class="formatter.DateFormatter "></bean>
</list>
</property>
</bean>
三、神奇的<mvc:annotation-driven />
前面的博客中有讲到,<mvc:annotation-driven></mvc:annotation-driven>
做了很多事情,其中就包括了两种类型转换:数字类型转换和日期/时间类型转换。
这里推荐一篇博客,讲得很全面:
如果只是将String类型转换成数字(int/long/double等类型)或者Date类型,完全可以不写上面的Converter和Formatter,直接在相应的属性上添加注解即可,如下:
package model;
import java.util.Date;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.format.annotation.NumberFormat;
import org.springframework.format.annotation.NumberFormat.Style;
import org.springframework.stereotype.Component;
@Component("product")
public class Product {
private String name;
private String description;
private String price;
@DateTimeFormat(pattern="yyyy-MM-dd HH:mm:ss")
private Date createTime;
@NumberFormat(style=Style.NUMBER)
private int id;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getPrice() {
return price;
}
public void setPrice(String price) {
this.price = price;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
如有错误之处,还望留言指正。