3.4 类型转化

Coverter SPI

SPI是一种接口发现机制
接口
类型转换的简单形式
b spring之数据绑定--Converter SPI & Filed Formatting & DataBinder
实现Coverter接口即可,S是被转化的接口,T是目的接口。也可以去转化一个数组。
使用注意
对于convert(S)函数要求S参数不能为null。如果出错会报IllegalArgumentException异常,但是要确保你的Converter是线程安全的。
内置的实现
几个默认的coverter都在core.convert.supportpackage里面。
b spring之数据绑定--Converter SPI & Filed Formatting & DataBinder

3.4.2 Using ConverterFactory

当你需要中心化转化逻辑的时候,比如从String转化到Enum对象的时候,你可以实现ConverterFactory
b spring之数据绑定--Converter SPI & Filed Formatting & DataBinder
这个工厂是一个批量产生Converter的类,用到泛型编程,S是被转化类,R是你期待转化类型的基本类型。
如下是一个String获取Enum的converter过程
b spring之数据绑定--Converter SPI & Filed Formatting & DataBinder

3.4.3 使用GenericConverter

如果你需要一个通用的处理,可以考虑GenericConverter,比Coverter的强制定类型更弱化一点。
b spring之数据绑定--Converter SPI & Filed Formatting & DataBinder
注意getConvertibleTypes()可以描绘能够转化类型的具体类型

带条件的转化ConditionalGenericConverter

附带了match逻辑
b spring之数据绑定--Converter SPI & Filed Formatting & DataBinder
实现时可以用自动类型转化来匹配

3.4.4 ConversionService API

定义了一套API,目的在运行时进行转化
b spring之数据绑定--Converter SPI & Filed Formatting & DataBinder
大多数实现了ConversionService的类,也实现了ConverterRegistry类,目的是运行时动态注册。
core.convert.support包还有GenericConversionServiceConversionServiceFactory–创建ConversionService的工厂方法。

3.4.5 配置ConversionService

ConversionService是一个无状态的对象,被用来在应用启动时实例化在多线程间共享。你可以典型的配置一个ConversionService示例在每个ApplicationContext里面。需要类型转化时,spring会自主调用,或者注入到bean中手动调用。

没有ConfigService的情况下,PropertyEdit-based的系统会被调用。

xml注册
b spring之数据绑定--Converter SPI & Filed Formatting & DataBinder

在Spring MVC中典型的用的多一点。

3.4.6. Using a ConversionService Programmatically

定义为@Service,能看出如何使用,会自动注入
CoversionService
b spring之数据绑定--Converter SPI & Filed Formatting & DataBinder
但是对用更复杂的类型,比如集合则需要手动调用TypeDescriptor可以帮你
b spring之数据绑定--Converter SPI & Filed Formatting & DataBinder
注意DefaultConversionService在大多数场景会自动注册 converters:collection converters, scalar converters,和 基础的Object-to-String converters.
你也可以是用ConverterRegistry的addDefaultConverters方法手动转化。

3.5 Spring Field Formatting

如上一节所述,core.convert是一种通用类型转换系统。它提供了统一的ConversionService API和强类型的Converter SPI,用于实现从一种类型到另一种类型的转换逻辑。 Spring容器使用此系统绑定bean属性值。此外,Spring Expression Language(SpEL)和DataBinder都使用此系统绑定字段值。例如,当SpEL需要强制将Short转换为Long来完成expression.setValue(Object bean,Object value)尝试时,core.convert系统将执行强制转换。

现在考虑典型客户端环境(例如Web或桌面应用程序)的类型转换要求。在这样的环境中,您通常会从String转换为支持客户端回发过程,然后又转换为String以支持视图渲染过程。另外,您通常需要本地化String值。更通用的core.convert Converter SPI不能直接满足此类格式化要求。为了直接解决这些问题,Spring 3引入了便利的Formatter SPI,它为客户端环境提供了PropertyEditor实现的简单而强大的替代方案。

通常,当您需要实现通用类型转换逻辑时(例如,用于在java.util.Date和Long之间进行转换),可以使用Converter SPI。在客户端环境(例如Web应用程序)中工作并且需要解析和打印本地化的字段值时,可以使用Formatter SPI。 ConversionService为两个SPI提供统一的类型转换API。

3.5.1 the Formatter SPI

Formatter接口的定义
b spring之数据绑定--Converter SPI & Filed Formatting & DataBinder
Printer和Parser的接口定义
b spring之数据绑定--Converter SPI & Filed Formatting & DataBinder
要创建自己的格式化程序,请实现前面显示的Formatter程序接口。将T参数化为您希望格式化的对象的类型(例如java.util.Date)。实现print()操作以打印T的实例以在客户端语言环境中显示。实现parse()操作,以从客户端语言环境返回的格式化表示形式解析T的实例。如果解析尝试失败,则Formatter应该抛出ParseExceptionIllegalArgumentException。注意确保您的Formatter实现是线程安全的。

format 子包提供了几个Formatter的实现。

  • number包,提供了NumberStyleFormatter, CurrencyStyleFormatter, 和 PercentStyleFormatter用java.text.NumberFormat去格式化Number对象。
  • datetime 包提供了DateFormatter通过使用java.text.DateFormat去格式化。
  • The datetime.joda包提供了全面的joda-Time library

下面是DateFormatter的实现例子
b spring之数据绑定--Converter SPI & Filed Formatting & DataBinder

*注解驱动的格式化

去绑定一个Formatter到注解上去,需要实现AnnotationFormatterFactory
b spring之数据绑定--Converter SPI & Filed Formatting & DataBinder
要创建一个实现:将A参数化为要与annotationType逻辑关联的字段注解类型,例如org.springframework.format.annotation.DateTimeFormat。 。让getFieldTypes()返回可在其上使用注释的字段类型。 让getPrinter()返回打印机以打印带注释的字段的值。 。让getParser()返回解析器以解析带注释字段的clientValue。

以下示例AnnotationFormatterFactory实现将@NumberFormat批注绑定到格式化程序,以指定数字样式或模式:
b spring之数据绑定--Converter SPI & Filed Formatting & DataBinder
使用注解来选择
b spring之数据绑定--Converter SPI & Filed Formatting & DataBinder

格式化Format Annotation API

便携式格式注释API存在于org.springframework.format.annotation包中。您可以使用@NumberFormat格式化数字字段(例如Double和Long),并使用@DateTimeFormat格式化java.util.Date,java.util.Calendar,Long(用于毫秒时间戳)以及JSR-310 java.time和Joda-时间值类型。

以下示例使用@DateTimeFormat将java.util.Date格式化为ISO日期(yyyy-MM-dd)
b spring之数据绑定--Converter SPI & Filed Formatting & DataBinder

3.5.3 The FormatterRegistry SPI

FormatterRegistry是用于formatters and converters的SPI。 FormattingConversionService是FormatterRegistry的实现,适用于大多数环境。您可以通过编程方式或声明方式将此变体配置为Spring Bean,例如通过使用FormattingConversionServiceFactoryBean。由于此实现还实现了ConversionService,因此您可以直接将其配置为与Spring的DataBinder和Spring表达式语言(SpEL)一起使用。
b spring之数据绑定--Converter SPI & Filed Formatting & DataBinder
FormatterRegistry SPI使您可以集中配置格式设置规则,而不必在控制器之间复制此类配置。例如,您可能需要强制以某种方式设置所有日期字段的格式或以某种方式设置带有特定批注的字段的格式。使用共享的FormatterRegistry,您可以一次定义这些规则,并在需要格式化时应用它们。

3.5.4. The FormatterRegistrar SPI

FormatterRegistrar是一个SPI,用于通过FormatterRegistry注册Formatters和converters。以下清单显示了其接口定义
b spring之数据绑定--Converter SPI & Filed Formatting & DataBinder
在为给定的格式类别(例如日期格式)注册多个相关的转换器和格式器时,FormatterRegistrar很有用。在声明式注册不足的情况下(例如,当格式化程序需要在不同于其自身的特定字段类型下建立索引或注册打印机/解析器对时),它也很有用。下一节将提供有关转换器和格式化程序注册的更多信息。

3.5.5. Configuring Formatting in Spring MVC

See Conversion and Formatting in the Spring MVC chapter.

3.6 配置全局日期格式

默认情况下,未使用@DateTimeFormat注释的日期和时间字段是使用DateFormat.SHORT样式从字符串转换的。如果愿意,可以通过定义自己的全局格式来更改此设置。

为此,您需要确保Spring不注册默认格式器。相反,您应该手动注册所有格式化程序。根据是否使用Joda-Time库,使用org.springframework.format.datetime.joda.JodaTimeFormatterRegistrar或org.springframework.format.datetime.DateFormatterRegistrar类。

例如,以下Java配置注册了全局yyyyMMdd格式(此示例不依赖于Joda-Time库):b spring之数据绑定--Converter SPI & Filed Formatting & DataBinder

3.7 Spring Validation

Spring 3对其验证支持进行了一些增强。首先,完全支持JSR-303 Bean验证API。其次,以编程方式使用时,Spring的DataBinder可以验证对象并绑定到对象。第三,Spring MVC支持声明式验证@Controller输入。

3.7.1 JSR-303 Bean Validation API 一览

b spring之数据绑定--Converter SPI & Filed Formatting & DataBinder
JSR-303允许您针对此类属性定义声明性验证约束,如以下示例所示
b spring之数据绑定--Converter SPI & Filed Formatting & DataBinder

3.7.2 Configuring a Bean Validation Provider

Spring提供了对Bean验证API的全面支持。这包括对将JSR-303或JSR-349 Bean验证提供程序引导为Spring Bean的便捷支持。这样,您可以在应用程序中需要验证的任何地方注入javax.validation.ValidatorFactory或javax.validation.Validator。

您可以使用LocalValidatorFactoryBean将默认的Validator配置为Spring Bean,如以下示例所示:
b spring之数据绑定--Converter SPI & Filed Formatting & DataBinder

注入Validator

b spring之数据绑定--Converter SPI & Filed Formatting & DataBinder

配置自定义的约束Configuring Custom Constraints

用注解关联
b spring之数据绑定--Converter SPI & Filed Formatting & DataBinder
每个bean验证约束由两部分组成:* @Constraint批注,用于声明约束及其可配置属性。 * javax.validation.ConstraintValidator接口的实现,用于实现约束的行为。

要将声明与实现相关联,每个@Constraint批注都引用一个对应的ConstraintValidator实现类。在运行时,当在域模型中遇到约束注释时,ConstraintValidatorFactory实例化引用的实现。

默认情况下,LocalValidatorFactoryBean配置一个SpringConstraintValidatorFactory,该工厂使用Spring创建ConstraintValidator实例。这使您的自定义ConstraintValidators像其他任何Spring bean一样受益于依赖项注入。

以下示例显示了一个自定义@Constraint声明,后跟一个关联的ConstraintValidator实现,该实现使用Spring进行依赖项注入:
b spring之数据绑定--Converter SPI & Filed Formatting & DataBinder

方法驱动的验证

Spring-driven Method Validation
您可以通过MethodValidationPostProcessor Bean定义将Bean验证1.1(以及作为自定义扩展,还包括Hibernate Validator 4.3)支持的方法验证功能通过Spring的MethodValidationPostProcessor Bean定义集成到Spring上下文中:
b spring之数据绑定--Converter SPI & Filed Formatting & DataBinder

为了符合Spring驱动的方法验证的条件,所有目标类都必须使用Spring的@Validated注释进行注释。 (可选地,您也可以声明要使用的验证组。)有关Hibernate Validator和Bean Validation 1.1提供程序的设置详细信息,请参见MethodValidationPostProcessor javadoc。

Additional Configuration Options

在大多数情况下,默认LocalValidatorFactoryBean配置就足够了。从消息插值到遍历解析,有许多用于各种Bean验证构造的配置选项。有关这些选项的更多信息,请参见LocalValidatorFactoryBean Javadoc。

3.7.3. 配置 a DataBinder

从Spring 3开始,您可以使用Validator配置DataBinder实例。配置完成后,您可以通过调用binder.validate()来调用Validator。任何验证错误都会自动添加到binder的BindingResult中。

下面的示例演示如何在绑定到目标对象后,以编程方式使用DataBinder来调用验证逻辑:
b spring之数据绑定--Converter SPI & Filed Formatting & DataBinder

您还可以通过dataBinder.addValidators和dataBinder.replaceValidators配置具有多个Validator实例的DataBinder。当将全局配置的bean验证与在DataBinder实例上本地配置的Spring Validator结合使用时,这很有用。请参阅[validation-mvc-configuring]。

3.7.3 Spring MVC 3 Validation

相关文章: