我有很多实现名为Codeable的接口的Enums。我想从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);
}
}
}
这是spring config
<!-- 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,为什么会这样?如何让我优先于另一个呢?
答案 0 :(得分:2)
我注意到的是DefaultConversionService的默认值包括StringToEnumConversion,它首先出现在服务的可能转换器列表中。因此,我从未被击中,每次都在尝试标准的Enum转换。
我的解决方法是:
registry.removeConvertible(String.class, Enum.class)
其中registry是FormatterRegistry的实例MyEnumType.class.isAssignableFrom(targetType)
)的无所不包的字符串到枚举转换器,并根据结果委托给我的自定义转换器或默认的字符串到枚举转换器注意这种方法有几个问题,其中包括:StringToEnumConverter
是一个包私有类,所以我不得不将它复制粘贴到我自己的代码库中。另外,这不是解决这个问题的理想方法;它不是很“有弹性”。
很想听到替代答案。
值得注意的是,我正在使用Spring 3.2.6
我找到了一种更清洁的方式,请注意我使用的是注释配置而不是xml,但是主体应该是相同的。
在Spring的文档中,我发现:
GenericConversionService是一个旨在实现的通用实现 显式配置,以编程方式或声明方式配置为 春豆。 DefaultConversionService是一个预注册的子类 核心.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);
}
现在一切正常,感觉不那么骇人听闻。