1.使用Formatter格式化数据
6.3 数据格式化
Spring使用Converter转换器进行源类型对象到目标类型对象的转换,Spring的转换器并不承担输入以及输出信息格式化的工作。如果需要转换的源类型数据是从客户端界面中传过来的,比如日期、时间、数字、货币等数据,它们往往都拥有一定的格式。在不同的本地化环境中,同一类型的数据还会相应地呈现不同的显示格式
如何从格式化的数据中获取真正的数据以完成数据绑定,并将处理完成的数据输出为格式化的数据是Spring格式化框架需要解决的问题。Spring从3.0开始引入了格式化转换框架,这个框架位于org.springframework.format包中,其中最重要的是Formatter<T>接口
Converter和Formatter的区别
Converter完成任意Object与Object之间的类型转换,Formatter完成任意Object与String之间的类型转换,即格式化和解析,
它和PropertyEditor功能类似,可以替代PropertyEditor来进行对象的解析和格式化,而且支持细粒度的字段级别的格式化解析。Formatter只能将String转换成另一种Java类型。例如,将String转换成Date但它不能将Long转换成Date。
因此Formatter更适用于Web层的数据转换。而Converter则可以用在任意层中。
因此,在Spring MVC的应用程序当中,如果想转换表单中的用户输入,则建议选择Formatter,而不是Converter.
Spring MVC格式化接口
Formatter格式化转换是Spring通用的,定义在org.springframework.format包中,其不仅仅在Spring Web MVC场景下使用。在org.springframework.format包中定义的接口如下:
Printer接口
Printer<T>接口。格式化显示接口,其将T类型的对象根据 Locale信息以某种格式进行打印显示(即返回字符串形式)。该接口中定义了一个 print方法,其根据本地化信息将T类型的对象输出为不同格式的字符串。
1 | String print(T object,Locale locale) |
Parser接口
Parser<T>接口。解析接口,其根据 Locale信息解析字符串到T类型的对象。该接口中定义了一个 parse方法,其参考本地化信息将一个格式化的字符串转换为T类型的对象
1 | T parse(String text,Locale locale) throws ParseException |
Formatter接口
Formatter<T>接口。格式化接口,继承自 Printer<T>和 Parser<T>接口,它完成T类型对象的格式化和解析功能。
FormatterRegistrar接口
FormatterRegistrar接口。注册格式化转换器。该接口中定义registerFormatters方法,其参数就是 FormatterRegistry对象,用于注册多个格式化转换器。
1 | void registerFormatters(FormatterRegistry registry) |
AnnotationFormatterFactory接口
AnnotationFormatterFactory< A extends Annotation>接口。注解驱动的字段格式化工厂,用于创建带注解的对象字段的 Printer和 Parser,即用于格式化和解析带注解的对象字段。该接口中定义了以下几个方法:
Set<Class<?>> getFieldTypes()。注解A的应用范围,即哪些属性类可以标注A注解。Printer<?> getPrinter( a Annotation, Class<?> fieldType)。**根据注解A获取特定属性类型Printer**。Parser<?> getParser( A annotation, Class<?> fieldType)。根据注解A获取特定属性类型的Parser。
示例 使用Formatter格式化数据
使用自定义的格式化类
DateFormatter
1 | // 实现Converter<S,T>接口 |
DateFormatter类实现了org. springframework. format. Formatter接口。实现了接口中的两个方法:
parse方法,使用指定的Locale将一个String解析成目标T类型;print方法,用于返回T类型的字符串表示形式。
在 DateFormatter类中使用 SimpleDateFormat对象将 String转换成Date类型,日期类型模板yyy-M-dd会通过配置文件的依赖注入设置。
springmvc-config.xml
1 | <!-- 装配自定义格式化 --> |
Spring在格式化模块中定义了一个实现ConversionService接口的FormattingConversionService实现类,该类既具有类型转换功能,又具有格式化的功能
而FormattingConversionServiceFactoryBean工厂类用于在 Spring上下文中构造一个FormattingConversionService对象,通过这个工厂类可以注册自定义的格式化转换器
以上配置使用FormattingConversionServiceFactoryBean对自定义的格式化转换器DateFormatter进行了注册。 FormattingConversionServiceFactoryBean类有一个属性converters,可以用它注册Converter;有一个属性formatters,可以用它注册Formatter。
值得注意的是,在mvc:annotation-driven标签内部默认创建的conversionService实例就是一个FormattingConversionServiceFactoryBean,有了FormattingConversionServiceFactoryBean之后, Spring MVC对处理方法的参数就绑定格式化功能了。
User.java
1 | // 域对象,实现序列化接口 |
UserController.java
1 |
|
registerForm.jsp
1 | <%@ page language="java" contentType="text/html; charset=UTF-8" |
success.jsp
1 | <%@ page language="java" contentType="text/html; charset=UTF-8" |
测试
测试链接
1 | <a href="registerForm">测试使用格式化类</a> |
填写数据

转换效果

控制台输出
1 | 实现的parse方法:String转Date |
使用Spring提供的格式化类
以上使用实现Formatter<T>接口的方式完成数据转换,而Spring本身提供了很多常用的Formatter实现。在org.springframework.format.datetime包中提供了一个用于时间对象格式化的DateFormatter实现类
在org.springframework.format.number包中提供了3个用于数字对象格式化的实现类:
Numberformatter。用于数字类型对象的格式化CurrencyFormatter。用于货币类型对象的格式化PercentFormatter。用于百分数数字类型对象的格式化
例如,如果要使用org.springframework.format.datetime包中提供的DateFormatter实现类完成字符串到日期对象的转换,则只需要在配置文件中配置就可以了:
1 | <bean |
运行效果与上面的类似.