- Http请求传递的数据都是字符串String类型的,上面这个方法在Controller中定义
- 如果该方法对应的地址接收到到浏览器的请求的话,并且请求中含有num和birth参数,
- 那么num会被自动转换成Integer对象;birth会被自动转为Date对象(Date转换需要配置属性编辑器)。
PropertyEditor是属性编辑器的接口
- 有个方法setAsText很重要。 比如String对象"1"要使用属性编辑器转换成Integer对象,通过setAsText里Integer.parseInt(text)得到Integer对象,然后将Integer对象保存到属性中。
- 它的基本实现类是PropertyEditorSupport,一般我们要编写自定义的属性编辑器只需要继承这个类即可。
- Spring中有很多自定义的属性编辑器,都在spring-beans jar包下的org.springframework.beans.propertyeditors包里。
springmvc是如何实现参数的自动收集的
对于String,number(int double float..)以及boolean类型,springmvc会自动将它们与我们的po bean进行绑定
ServletRequestDataBinder
- PropertyEditorRegistry接口
- 封装方法来给JavaBean注册对应的属性编辑器。
- PropertyEditorRegistrySupport:PropertyEditorRegistry接口的基础实现类
- PropertyEditorRegistrySupport类有个createDefaultEditors方法,会创建默认的属性编辑器。
- TypeConverter接口 类型转换接口。 通过该接口,可以将value转换为requiredType类型的对象。
- TypeConverterSupport:TypeConverter基础实现类,并继承了PropertyEditorRegistrySupport
有个属性typeConverterDelegate,类型为TypeConverterDelegate,TypeConverterSupport将类型转换委托给typeConverterDelegate操作。
- TypeConverterDelegate
类型转换委托类。具体的类型转换操作由此类完成。
- SimpleTypeConverter
TypeConverterSupport的子类,使用了PropertyEditorRegistrySupport(父类TypeConverterSupport的父类PropertyEditorRegistrySupport)中定义的默认属性编辑器。
- PropertyAccessor接口
对类中属性操作的接口。
- BeanWrapper接口
继承ConfigurablePropertyAccessor(继承PropertyAccessor、PropertyEditorRegistry、TypeConverter接口)接口的操作Spring中JavaBean的核心接口。
- BeanWrapperImpl类
BeanWrapper接口的默认实现类,TypeConverterSupport是它的父类,可以进行类型转换,可以进行属性设置。
- DataBinder类
实现PropertyEditorRegistry、TypeConverter的类。支持类型转换,参数验证,数据绑定等功能。
有个属性SimpleTypeConverter,用来进行类型转换操作。
- WebDataBinder
DataBinder的子类,主要是针对Web请求的数据绑定。
- 在程序内部,DataBinder实例内部使用一个BeanWrapperImpl实例,负责设置命令对象的值。
- 通过getPropertyType方法,获取属性类型。
- 对于request请求,spring将会调用
BeanWrapperImpl beanWrapper = new BeanWrapperImpl(person);
Clazz requiredType = beanWrapper.getPropertyType("name");
接下来完成类型的转换 beanWrapper.convertIfNecessary("Tom", requiredType, methodParam)
springmvc自定义类型转换
- 如果springmvc遇到了其内部不能进行转换的request parameter呢?那么就需要注册PropertyEditor
- 举例来说,java.util.Date 不知道
13/09/2010
代表什么, - 所有要由我们程告诉spring(因为Date的格式有多种,所以spring不好来进行直接转换,需要我们自己定义格式来转换)
binder.registerCustomEditor(Date.class, new PropertyEditorSupport() {
public void setAsText(String value) {
try {
setValue(new SimpleDateFormat("dd/MM/yyyy").parse(value));
} catch(ParseException e) {
setValue(null);
}
}
/**
* 这个方法似乎没什么用
*/
public String getAsText() {
return new SimpleDateFormat("dd/MM/yyyy").format((Date) getValue());
}
});
- 当调用convertIfNecessary方法时,spring会寻找所有注册了的PropertyEditor来处理数据的绑定。
- 为了注册我们的PropertyEditor,在spring3.0中,使用
@InitBinder
public void binder(WebDataBinder binder) {
// as shown above 上面的代码
}
- controller有两种写法
- 写法二是原始写法,直接new PropertyEditorSupport类,
- 写法一使用spring提供的CustomDateEditor实现类,其实际上继承了PropertyEditorSupport类
@Controller
@RequestMapping(value = "/user")
public class UserAction {
//自定义类型转换器 如果springmvc遇到不能进行转换的Date类型
//通过名称来对应调用这个方法
//写法1 使用spring提供的CustomDateEditor实现类,其实际上继承了PropertyEditorSupport类
@InitBinder
public void initBinder(ServletRequestDataBinder binder){
binder.registerCustomEditor(Date.class, new CustomDateEditor(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"),
true));
}
//写法2 直接使用PropertyEditorSupport类
@InitBinder
public void binder(WebDataBinder binder){
binder.registerCustomEditor(Date.class, new PropertyEditorSupport(){
@Override
public void setAsText(String text) throws IllegalArgumentException {
try {
setValue(new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").parse(text));
} catch (ParseException e) {
setValue(null);
}
}
});
}
@RequestMapping("/register")
public String register(Model model, User user){
System.out.println(user);
Date date = user.getHiredate();
System.out.println(date.toLocaleString());
model.addAttribute("message", "员工注册成功");
return "success";
}
}