文章目录
一、Spring支持的转换器
Spring定义了3种类型的转换器接口,实现任意一个转换器接口都可以作为自定义转换器注册到ConversionServiceFactroyBean
中:
Converter<S,T>
:将S类型对象转为T类型对象。- ConverterFactory:将相同系列多个同质Converter封装在一起。如果希望将一种类型的对象转换为另一种类型及其子类的对象(例如将String转换为Number及Number子类(Integer、Long、Double等)对象)可使用该转换器工厂类。
- GenericConverter:会根据源类对象及目标类对象所在的宿主类中的上下文信息进行类型转换.
由于后两种形式并不常用,本文仅介绍第一种,实现Converter<S,T>接口的方法。
二、自定义转换器的步骤
ConverterService是一个接口,它有一个实现类Converter(转换器)进行工作。自定义转换器,步骤如下
- ①先实现Converter接口,写一个自定义的类型转换器。
- ②将Converter配置在ConverterService组件中。
- ③将组件声明在annotation-driven标签中。
在页面添加一个快速添加的按钮
list.jsp
<form action="${ctp }/quickadd">
<input name="empinfo" value="empAdmin-admin@qq.com-1-101"/>
<input type="submit" value="快速添加" />
</form>
点击发送/quickadd请求到handler处理器
。
@RequestMapping("/quickadd")
public String quickAdd(@RequestParam("empinfo") Employee employee) {
System.out.println("封装:" + employee);
employDao.save(employee);
return "redirect:/emps";
}
handler处理器
中调用保存方法后发送/emps请求,进而返回list.jsp页面
。
第一步:实现Converter接口
页面提交的将要转换的字符串为:
empAdmin-admin@qq.com-1-101
- 自定的转换器实现的功能:将String类型转换为Employee对象。
/**
* S:Source
* T:Target
* 将String转换为Employee对象
* @guoqianliang
*/
public class MyStringToEmployeeConverter implements Converter<String, Employee> {
@Autowired
DepartmentDao dpartmentDao;
@Override
public Employee convert(String source) {
System.out.println("页面提交的将要转换的字符串:" + source);
Employee employee = new Employee();
if (source.contains("-")) {
String[] split = source.split("-");
employee.setLastName(split[0]);
employee.setEmail(split[1]);
employee.setGender(Integer.parseInt(split[2]));
employee.setDepartment(dpartmentDao.getDepartment(Integer.parseInt(split[3])));
}
return employee;
}
}
第二步:将Converter配置到ConverterService组件中
- 将自定义的Converter实现类配置到ConverterService组件中。
<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
<!-- 添加自定义的类型转换器 -->
<property name="converters">
<set>
<bean class="com.gql.component.MyStringToEmployeeConverter"></bean>
</set>
</property>
</bean>
后续为了与日期格式化兼容,通常使用下面的写法:
<bean id="conversionService"
class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
<!-- 添加自定义的类型转换器 -->
<property name="converters">
<set>
<bean class="com.gql.component.MyStringToEmployeeConverter"></bean>
</set>
</property>
</bean>
第三步:将组件声明在annotation-driven标签中
<mvc:annotation-driven conversion-service="conversionService"></mvc:annotation-driven>
自定义转换器设置完成,控制台输出:
页面提交的将要转换的字符串:empAdmin-admin@qq.com-1-101
封装:Employee [id=null, lastName=empAdmin, email=admin@qq.com, gender=1, department=Department [id=101, departmentName=D-AA]]
三、关于annotation-driven标签
-
<mvc:annotation-driven /"> 标签会自动注册
RequestMappingHandlerMapping
、RequestMappingHandlerAdapter
与ExceptionHandlerExceptionResolver
三个bean。 -
支持使用ConverterService实例对表单参数进行类型转换。
-
支持使用
@NumberFormat annotation
、@DateTimeFormart
注解完成数据类型的格式化。 -
支持使用
@Valid
注解对JavaBean实例进行JSR303校验。 -
支持使用
@RequestBody
和@ResponseBody
注解。
四、日期格式化
对属性对象的输入和输出进行格式化,本质上还是类型转换的范畴。
Spring在格式化模块中定义了一个实现ConverterService接口的FormattingConversionService实现类
,该实现类扩展了GenericConversionService
,因此它即具有类型转换的功能,又具有格式化的功能。
- FormattingConversionService拥有一个工厂类FormattingConversionServiceFactoryBean,后者用于在Spring上下文中构造前者。
- FormattingConversionServiceFactoryBean内部已经注册了
①NumberFormatAnnotationFormatterFactory:支持对数字类型的属性使用@NumberFormat注解
。
如:@NumberFormat(pattern="#,###,###")
②JodaDateTimeFormatAnnotationFormatterFactory:支持对日期类型的属性使用@DateTimeFormat注解
。
如:@DateTimeFormat(pattern = “yyyy-MM-dd”)
另外,需要注意的是ConversionServiceFactoryBean
所创建的ConversionService组件没有格式化器,使用时需要在SpringMVC配置中将其替换为FormattingConversionServiceFactoryBean
组件。