β

Spring 3.x自动将枚举的ordinal值转换为枚举类型

Java堂 295 阅读

Spring MVC会自动将前台表单中的数据转换为JavaBean,默认情况下如果JavaBean中使用枚举类型的话,会将枚举的name自动转换为枚举类型,这一点是通过系统自带的org.springframework.core.convert.support.StringToEnumConverterFactory类型转换器来实现的,可以参考这个类来实现将ordinal转换为枚举类型。

在Spring 3.x之前通常使用PropertyEditor来实现数据的类型转换,3.x开始可以使用实现了SPI接口的类型转换系统(如Converter等)来进行转换。PropertyEditor通常用在对表单进行单独进行处理的场合,而类型转换系统适用于批量和通用的场合,我们这里想将所有的枚举类型的ordinal值转换为枚举类型,因此采用类型转换器的方式。

在Spring MVC 3.x中有三种类型转换系统的实现接口:(1)Converter类型转换器接口,只能实现单一的从一种类型S转换为另一种类型T,但不能进行多类型转换或子类型转换,我们这里因为要实现所有的枚举类型自动转换,因此这种方式不适合;(2)GenericConverter和ConditionalGenericConverter接口,前者可以实现多种类型之间的转换,后者同时还可以在特定条件下实现多种功能类型转换,但二者都不能实现所有子类型的转换;(3)ConverterFactory 工厂模式的接口,用于指定Converter即转换器,但提供了三种类型:S源类型、R目标类型的父类型、T目标类型且为R类型的子类型,这种方式非常适合我们,因此我们采用这种方式,代码如下:

  1. public class OrdinalToEnumConverterFactory implements ConverterFactory<String, Enum<?>> {
  2. @Override
  3. public <T extends Enum<?>> Converter<String, T> getConverter(Class<T> targetType) {
  4. return new OrdinalToEnum<T>(targetType);
  5. }
  6. private class OrdinalToEnum<T extends Enum<?>> implements Converter<String, T> {
  7. private final Class<T> enumType;
  8. public OrdinalToEnum(Class<T> enumType) {
  9. this.enumType = enumType;
  10. }
  11. @Override
  12. public T convert(String source) {
  13. // 转换成数字
  14. int ordinal = Numbers.toInt(source, Integer.MIN_VALUE);
  15. if(ordinal == Integer.MIN_VALUE) {
  16. return null;
  17. }
  18. return Enums.valueOf(enumType, ordinal);
  19. }
  20. }
  21. }

其中Enums.valueOf方法可以自己实现,思路是首先通过Enum Class的getEnumConstants方法获取所有的枚举类型的数组,然后使用ordinal索引号进行自动匹配,需要注意溢出的情况。

做完了上面的工作之后还需要在配置文件中进行定义和引入,配置片段如下:

  1. <mvc:annotation-driven conversion-service="conversionService">
  2. </mvc:annotation-driven>
  3. <bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
  4. <property name="converters">
  5. <set>
  6. <!-- 自动将枚举类型的序列号解析称枚举类型 -->
  7. <bean class="com.javatang.web.converter.support.OrdinalToEnumConverterFactory" />
  8. </set>
  9. </property>
  10. </bean>

虽然官方文档中说只要将bean的id设置成conversionService就会自动启用,但是我测试下来还需要在mvc:annotation-driven中使用conversion-service进行调用才有效。

参考资料:
Spring custom converter for all Enums
Spring MVC type conversion : PropertyEditor or Converter?
SpringMVC数据类型转换
Spring Doc ConverterFactory

Related Posts:

作者:Java堂
荣辱不惊闲看庭前花开花谢,去留无意漫随天外云卷云舒。——马寅初
原文地址:Spring 3.x自动将枚举的ordinal值转换为枚举类型, 感谢原作者分享。

发表评论