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 |
运行效果与上面的类似.