Java 什么';当使用Commons BeanUtils时,为特定类的所有子类注册转换器的最佳方法是什么?

Java 什么';当使用Commons BeanUtils时,为特定类的所有子类注册转换器的最佳方法是什么?,java,apache-commons-beanutils,Java,Apache Commons Beanutils,例如,如果我希望为java.util.Map的所有实例注册一个转换器,有没有办法做到这一点: new BeanUtilsBean().getConvertUtils().register(new MyConverter(), Map.class); 其中将为映射的任何实例(例如HashMap)调用MyConverter\convert()方法 其背景是我使用BeanUtils从数据库中填充各种不同的bean。它们的一些属性是实现特定接口的枚举,要设置它们的值,需要一个自定义例程。我本来希望为所

例如,如果我希望为java.util.Map的所有实例注册一个转换器,有没有办法做到这一点:

new BeanUtilsBean().getConvertUtils().register(new MyConverter(), Map.class);
其中将为映射的任何实例(例如HashMap)调用
MyConverter\convert()
方法

其背景是我使用BeanUtils从数据库中填充各种不同的bean。它们的一些属性是实现特定接口的枚举,要设置它们的值,需要一个自定义例程。我本来希望为所讨论接口的所有实现注册一个转换器类,但找不到这样做的方法,因此不得不通过检查bean中每个属性的类并注册我的转换器类(如果它们恰好是此接口的实例):

BeanUtilsBean b = new BeanUtilsBean();
Class< ? > propertyType = pu.getPropertyType(this, setterName);

if (isImplementationOfMyInterface(propertyType)) {
    b.getConvertUtils().register(new MyConverter(), propertyType);
}

b.setProperty(this, setterName, value);
BeanUtilsBean b=新的BeanUtilsBean();
类<?>propertyType=pu.getPropertyType(这个,setterName);
if(i实现多接口(propertyType)){
b、 getConvertUtils().register(新的MyConverter(),propertyType);
}
b、 setProperty(this、setterName、value);

这似乎相当令人讨厌,我相信一定有更好的方法来实现这一点?

试图实现同样的目标(我的用例是所有类型枚举的通用转换器)但从代码ConvertUtils中可以看出,它只支持转换器和类之间的直接映射,无法注册基类或接口


基本上,它使用一个映射,其中键是类和转换器的值,为了在类中获得适当的转换器,它只需执行一个映射即可。

您可以覆盖
ConvertUtilsBean
。下面的代码添加了对
Enum
的支持,但是您可以对
Map
执行相同的操作:

BeanUtilsBean.setInstance(new BeanUtilsBean(new EnumAwareConvertUtilsBean()));
类别定义:

public class EnumAwareConvertUtilsBean extends ConvertUtilsBean2 {

    private static final EnumConverter ENUM_CONVERTER = new EnumConverter();

    @Override
    public Converter lookup(Class pClazz) {
        final Converter converter = super.lookup(pClazz);

        if (converter == null && pClazz.isEnum()) {
            return ENUM_CONVERTER;
        } else {
            return converter;
        }
    }

}

public class EnumConverter extends AbstractConverter {

    private static final Logger LOGGER = LoggerFactory.getLogger(EnumConverter.class);

    @Override
    protected String convertToString(final Object pValue) throws Throwable {
        return ((Enum) pValue).name();
    }

    @Override
    protected Object convertToType(final Class pType, final Object pValue)
        throws Throwable
    {
        // NOTE: Convert to String is handled elsewhere

        final Class<? extends Enum> type = pType;
        try {
            return Enum.valueOf(type, pValue.toString());
        } catch (final IllegalArgumentException e) {
            LOGGER.warn("No enum value \""
                + pValue
                + "\" for "
                + type.getName());
        }

        return null;
    }

    @Override
    protected Class getDefaultType() {
        return null;
    }

}
公共类EnumawarConvertutilsBean扩展ConvertUtilsBean2{
私有静态最终EnumConverter ENUM_CONVERTER=新EnumConverter();
@凌驾
公共转换器查找(pClazz类){
最终转换器=超级查找(pClazz);
if(converter==null&&pClazz.isEnum(){
返回ENUM_转换器;
}否则{
回流转换器;
}
}
}
公共类EnumConverter扩展了AbstractConverter{
私有静态最终记录器Logger=LoggerFactory.getLogger(EnumConverter.class);
@凌驾
受保护的字符串convertToString(最终对象pValue)抛出Throwable{
return((Enum)pValue.name();
}
@凌驾
受保护对象转换类型(最终类pType,最终对象pValue)
扔掉的
{
//注意:转换为字符串在别处处理

最后一个类使用java 6/7和泛型,EnumConverter必须变成这样:
私有类EnumConverter实现转换器{@Override public T convert(类类型,对象值){return type.cast(type.getMethod(“fromValue”,String.class).invoke(null,value.toString());}
。然而,我无法摆脱反射。