【问题标题】:Spring type conversion not taking effect弹簧类型转换不生效
【发布时间】:2013-07-14 00:56:50
【问题描述】:

我有很多枚举实现了一个名为 Codeable 的接口。我想在从 json 反序列化并尝试使用 ConverterFactory 时进行反向查找

public class StringToCodeableConverterFactory implements ConverterFactory<String, Codeable> {

@Override
public <T extends Codeable> Converter<String, T> getConverter(
        Class<T> targetType) {
    return new StringToCodeableConverter<T>(targetType);
}

private final class StringToCodeableConverter<T extends Codeable> implements Converter<String, T> {

    private Class<T> enumType;

    public StringToCodeableConverter(Class<T> enumType) {
        this.enumType = enumType;
    }

    @Override
    public T convert(String source) {
        return CodeableUtil.get(this.enumType, source);
    }

}

}

这是弹簧配置

<!-- Custom Converters from String to Java Type-->
<bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
    <property name="converters">
        <list>
            <bean class="com.duetto.model.StringToCodeableConverterFactory" />
        </list>    
    </property>
</bean>

<mvc:annotation-driven conversion-service="conversionService">

经过一番挖掘,我发现 Spring 采用默认的 StringToEnumConverterFactory 而不是我的 StringToCodeableConverterFactory,为什么会这样?我怎样才能让我的优先级高于另一个?

【问题讨论】:

    标签: spring-mvc type-conversion


    【解决方案1】:

    我注意到发生的事情是 DefaultConversionService 的默认值包括一个 StringToEnumConversion,它首先出现在服务的可能转换器列表中。因此,我的从未被击中,并且每次都在尝试标准的 Enum 转换。

    我的解决方法是:

    1. 取消注册默认的字符串到枚举转换器 - registry.removeConvertible(String.class, Enum.class),其中 registry 是 FormatterRegistry 的一个实例
    2. 编写一个字符串到 mycustomenum 的转换器
    3. 编写一个包罗万象的字符串到枚举转换器,它进行类型检查 (MyEnumType.class.isAssignableFrom(targetType)) 并根据结果委托给我的自定义转换器或默认的字符串到枚举转换器

    注意这种方法有几个问题,其中:StringToEnumConverter 是一个包私有类,所以我不得不将它复制粘贴到我自己的代码库中。此外,这不是解决此问题的理想方法;它不是很“有弹性”。

    希望听到对此的替代答案。

    值得注意的是,我使用的是 Spring 3.2.6

    重大更新

    我找到了一种更简洁的方法,注意我使用的是注解配置而不是 xml,但主体应该是相同的。

    在 Spring 的文档中,我发现:

    GenericConversionService 是一个通用实现,旨在 以编程方式或以声明方式显式配置为 春豆。 DefaultConversionService 是预注册的子类 core.converter 包中的常用转换器,以方便使用。

    所以,我现在的覆盖配置如下:

    @Override
    public FormattingConversionService mvcConversionService() {
        // use FormattingConversionService here rather than GenericFormattingConversionService (the default) 
        // because it does not automatically register defaults
        FormattingConversionService conversionService = new FormattingConversionService();
        addFormatters(conversionService);
        return conversionService;
    }
    
    @Override
    protected void addFormatters(FormatterRegistry registry) {
        // register custom enum handler first
        registry.addConverterFactory(new MyCustomEnumConverterFactory());
        // now add in spring's defaults
        DefaultConversionService.addDefaultConverters(registry);
        DefaultFormattingConversionService.addDefaultFormatters(registry);
    }
    

    现在一切正常,感觉不那么老套了。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-25
      • 1970-01-01
      • 1970-01-01
      • 2015-09-17
      • 2018-05-11
      相关资源
      最近更新 更多