4

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

new BeanUtilsBean().getConvertUtils().register(new MyConverter(), Map.class);

MyConverter#convert()对于 Map 的任何实例(例如 HashMap),该方法会在哪里调用?

这样做的背景是我使用 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);

这似乎很讨厌,我敢肯定一定有更好的方法来做到这一点?

4

2 回答 2

6

您可以覆盖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;
    }

}

我通过阅读博客文章和来自http://www.bitsandpix.com/entry/java-beanutils-enum-support-generic-enum-converter/的评论得到了解决方案

于 2012-12-23T05:19:30.753 回答
2

试图做同样的事情(我的用例是所有类型枚举的通用转换器)但是从我在代码中看到的 ConvertUtils 仅支持转换器和类之间的直接映射,并且无法注册基类或一个界面。

基本上它使用一个映射,其中键是类,值是转换器,并且要在类中获取正确的转换器,它只需执行 Map#get。

于 2011-10-06T14:49:35.850 回答