SpringMVC(十一)_数据绑定流程之数据转换

       前言:本篇主要介绍SpringMVC的数据绑定流程中数据转换的相关概念与用法

本篇文章重点关注以下问题:

  • SpringMVC內建转换器
  • 自定义转化器

1. 內建转化器

        Spring MVC 上下文中内建了很多转换器,可完成大多数 Java 类型的转换工作。

第一组:标量转换器

类名说明StringToBooleanConverterString—–>Boolean(true:true/on/yes/1;false:false/off/no/0)ObjectToStringConverterObject—–>String (调用toString方法转换)StringToNumberConverterFactoryString—–>Number(如Integer、Long等)NumberToNumberConverterFactoryNumber子类型<——>Number子类型(Integer、Long、Double等)StringToCharacterConverterString —–>java.lang.Character 取字符串第一个字符NumberToCharacterConverterNumber子类型(Integer、Long、Double等)——> java.lang.CharacterCharacterToNumberFactoryjava.lang.Character ——>Number子类型(Integer、Long、Double等)StringToEnumConverterFactoryString—–>enum类型 (通过Enum.valueOf将字符串转换为需要的enum类型)EnumToStringConverterenum类型—–>String (返回enum对象的name()值)StringToLocaleConverterString—–>java.util.LocalPropertiesToStringConverterjava.util.Properties—–>String (默认通过ISO-8859-1解码)StringToPropertiesConverterString—–>java.util.Properties (默认通过ISO-8859-1解码)

 第二组:集合、数组相关转换器

ArrayToCollectionConverter任意S数组—->任意T集合(List、Set)
CollectionToArrayConverter任意T集合(List、Set)—->任意S数组
ArrayToArrayConverter任意S数组<—->任意T数组
CollectionToCollectionConverter任意T集合(List、Set)<—->任意T集合(List、Set) 即集合之间的类型转换
MapToMapConverterMap<—->Map之间的转换
ArrayToStringConverter任意S数组—->String类型
StringToArrayConverterString—–>数组 默认通过“,”分割,且去除字符串的两边空格(trim)
ArrayToObjectConverter任意S数组—->任意Object的转换 
(如果目标类型和源类型兼容,直接返回源对象;否则返回S数组的第一个元素并进行类型转换)
ObjectToArrayConverterObject—–>单元素数组
CollectionToStringConverter任意T集合(List、Set)—->String类型
StringToCollectionConverterString—–>集合(List、Set)(默认通过“,”分割,且去除字符串的两边空格(trim))
CollectionToObjectConverter任意T集合—->任意Object的转换 
(如果目标类型和源类型兼容,直接返回源对象;否则返回S数组的第一个元素并进行类型转换)
ObjectToCollectionConverterObject—–>单元素集合

第三组:默认(fallback)转换器:之前的转换器不能转换时调用

ObjectToObjectConverterObject(S)—–>Object(T)(首先尝试valueOf进行转换、没有则尝试new 构造器(S))
IdToEntityConverterId(S)—–>Entity(T) 
查找并调用public static T findEntityName获取目标对象,EntityName是T类型的简单类型
FallbackObjectToStringConverterObject—–>String ConversionService 
作为恢复使用,即其他转换器不能转换时调用(执行对象的toString()方法)

2 自定义转换器

         ConversionService是Spring类型转换体系的核心接口,可以利用 ConversionServiceFactoryBean在Spring的IOC容器中定义一个ConversionService,Spring 将自动识别出IOC 容器中的ConversionService,并在 Bean属性配置及Spring MVC 处理方法入参绑定等场合使用它进行数据的转换。可通过ConversionServiceFactoryBean的converters属性注册自定义的类型转换器口。

<!-- 配置 ConversionService -->
<bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
    <property name="converters">
        <set>
            <ref bean="addressConverter"/>
        </set>
    </property>
</bean>

        <mvc:annotation-driven conversion-service=“conversionService”/> 会将自定义的 ConversionService 注册到Spring MVC 的上下文中。

<!-- 开启注解 -->
<mvc:annotation-driven conversion-service="conversionService" />

2.1 SpringMVC支持的转化器

        Spring 定义了 3 种类型的转换器接口,实现任意一个转换器接口都可以作为自定义转换器注册到ConversionServiceFactroyBean中:

  1. Converter<S,T>:用于转换S类型到T类型,此接口的实现必须是线程安全的且可以被共享。(后面有此转化器的实例)
  2. GenericConverter 和ConditionalGenericConverter:GenericConverter 接口实现能在多种类型之间进行转换,ConditionalGenericConverter 是有条件的在多种类型之间进行转换。
  3. ConverterFactory:工厂模式的实现,用于选择将一种S源类型转换为R类型的子类型T的转换器的工厂接口。(例如将 String 转换为 Number 及 Number 子类(Integer、Long、Double 等)对象)

2.2 自定义转换器实例

         需求:前台以"江苏-南京"的形式传给后台,后台以实体类接收此信息:

SpringMVC(十一)_数据绑定流程之数据转换      SpringMVC(十一)_数据绑定流程之数据转换
         1. 利用Converter<S,T>实现自定义转换器,首先明确S,T的类型,此处自定义转化器将String类型转换为实体类AddressVo,因此S为String,T为AddressVo,先看下实体类:

public class AddressVo {

    private String province;
    private String city;
    
    public AddressVo(String province, String city) {
        this.province = province;
        this.city     = city;
    }

    public String getProvince() {
        return province;
    }

    public void setProvince(String province) {
        this.province = province;
    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

    @Override
    public String toString() {
        return "Address [province=" + province + ", city=" + city + "]";
    }
}

         2. 然后是转换器:

@Component
public class AddressConverter implements Converter<String, AddressVo> {

    @Override
    public AddressVo convert(String source) {
        if(source != null){
            String [] vals = source.split("-");
            // 江苏-南京
            if(vals != null && vals.length == 2){
                String province = vals[0];
                String city     = vals[1];
                return new AddressVo(province, city);
            }
        }
        return null;
    }

}

         3. 将此转化器注册到ConversionService,正如前面所示。

         自定义转化器就以上三步,比较简单。

相关推荐