处理方法的数据绑定过程
Spring MVC 通过反射对目标处理方法签名进行分析,见请求消息绑定到处理方法的入参中,数据绑定的核心组件为 DataBinder;
Spring MVC 数据绑定过程如下:
- Spring MVC 主框架将 ServletRequest 对象及处理方法入参对象实例传递到 DataBinder;
- DataBinder 调用装配在 Spring WebApplicationContext 的 ConversionService 组件进行数据转换、数据格式化,并将 ServletRequest 中的消息填充到入参对象中;
- DataBinder 调用 Validator 组件对已经绑定请求详细数据的入参对象进行数据合法性校验,最终生成对象保存在 BindingResult (包含已经完成数据绑定的入参、校验错误对象)中;
- Spring MVC 抽取 BindingResult 中的入参对象、校验错误对象,将他们赋予相应的方法入参;
数据转换
Spring 标准转接器装载
Spring 除了支持 Java 标准的转接器接口
java.beans.PropertyEditor
,同时本身在
org.springframework.core.convert
包中提供了一个通用的转接器模块,该模块的核心接口为
ConversionService
(该接口的核心功能类似于 PropertyEditor,但是提供了上下文支持);
Spring 提供了一个工厂类 org.springframework.context.support.
ConversionServiceFactoryBean 用于创建 ConversionService,该ConversionService 内建了多个转换器,可以完成大部分 Java 类型的转换工作,除了
将 String 对象转换为各种基础类型的对象外,还包括
String、Number、Array、Collection、Map、Properties、Object 之间的转换器;
在 Spring 中装载 ConvesionService ,可以 Spring MVC上下文文件(如:“assad-servlet.xml ”)中配置以下 bean,该bean已经包含了多个标准转换器:
自定义转接器的编写和装配
Spring 支持在向 ConversionService 注册自定义的转换器,对于自定义转换器的编写,支持2种方式:
- 基于 org.springframework.core.convert.converter 包中相关接口实现(Converter
, GenericConverter, ConverterFactory)的转换器:
- 基于 Java 标准 PropertyEditor 接口实现的编辑器;
1)基于Spring Converter 实现的转换器
假设要将一个格式化的请求参数字符串直接转化为 User 对象,该请求字符串格式如下:
编写转换器类
StringToUserConverter
在Spring-mvc配置文件 (如:”assad-servlet.xml“) 中注册该转换器:
当装配好 StringToUserConverter 转换器后,就可以在控制类的任何处理方法使用该转换器,如下 UserController 中:
启动 Web 容器,发送 URL :
"http://lcoalhost:8080/handle9?user=assad:2333:10",在逻辑视图 ”showUser“ 中可以获取到该请求参数字符串转化后的 User(name="assad",password="2333",credits=10);
2)基于Java标准 PropertyEditor 实现的编辑器
Spring 也支持 Java 标准的 PropertyEditor 编辑器,并提供了
@InitBinder 注解用于在控制器中添加自定义编辑器,
WebBindingInitializer 用于装配全局范围使用的编辑器;
在控制器中添加自定义编辑器,使用@InitBinder 标注:
在全局范围添加自定义编辑器:
实现 WebBindlingInitializer 接口,并在该实现类中注册 UserEditor
将该
WebBindlingInitializer 实现类绑定到 Spring-mvc 上下文:
※Spring MVC 查找自定义转化器/编辑器 的优先顺序:
- @InitBinder 装配的自定义编辑器;
- ConversionService 装载的自定义转换器;
- WeBindinginitializer 装载的自定义编辑器;
数据格式化
Spring MVC 支持在对数据绑定过程中,对数据进行格式化,在
org.springframework.fromat 包中提供了一个数据格式化框架,该框架最核心的接口为
Format 接口,拓展于 Printer 、Parser 接口,Printer 负责对象的格式化输出,Parser 负责对象的格式化输入;
Spring MVC 的数据格式化是基于它提供的数据转换框架之上的;
启动 Spring MVC 数据格式化功能
启动 Spring MVC 格式化功能,需要 Spring-mvc 上下文中装配 FormattingConversionServiceFactoryBean ,该类是ConversionServcieFactory 的一个子类,如下:
实际 会自动装配一个 FormattingConversionServiceFactoryBean 的实例;
如果装配一个自定义的格式化转换器,装配方法如同装配自定义转化器,因为格式化转换器就是一种特殊的转化器;
使用驱动格式化注解
Spring-mvc 提供了一系列的注解,用于在domain领域对象中对属性进行格式化注解,这些注解一般用在领域对象的属性中;
常用的注解如下:
@DateTimeFormat
对日期时间对象进行格式化,如:
java.util.Date、
java.util.Calendar、
java.long.Long、
Joda 时间类型;
含有以下互斥属性:
- iso:类型为 DateTimeFormat.ISO,以下为常用可选值:
- DateTimeFormat.ISO.DATE: 格式为 “yyyy-MM-dd”;
- DateTimeFormat.ISO.DATE_TIME:格式为 “yyyy-MM-dd hh:mm:ss.SSSZ”;
- DateTimeFormat.ISO.TIME: 格式为 “hh:mm:ss.SSSZ”;
- DateTimeFormat.ISO.NONE: 表示不使用 ISO 格式的时间;
- pattern:类型为 String,使用自定义的时间格式化串,如:“yyyy/MM/dd hh:mm:ss”;
- style:类型为 String,通过样式指定时间日期的格式,由2位字符组成,第一位表示日期样式,第二位表示时间样式,如 “MM”,常用可选值:
-
- S:短日期/时间格式,如 :“12/22/2017”,”13:27 PM“;
- M:中日期/时间格式,如 :“12-Dec-2017”,”13:27:35 PM“;
- L:长日期/时间格式,如 :“Decemenber 22,2017”,”13:27:35 PM EST“;
- F:完整日期/时间格式,如 :“Friday,Decemenber 22,2017”,”13:27:35 o'clock PM EST“;
- -:忽略日期/时间格式;
@NumberFromat
对数字类型进行格式,由以下互斥属性:
- pattern:类型为 String,使用自定义的数字格式化串,如:”##,###.##“
- style:类型为 NumberFormat.Style ,以下为常用可选值:
- NumberFormat.Style.CURRENCY:货币类型;
- NumberFormat.Style.NUMBER:正常数字类型;
- NumberFormat.Style.PERCENT:百分比数类型;
以下为一个使用实例:
领域对象 User