例如,如果我希望为java.util.Map的所有实例注册一个Converter,有没有办法做到这一点:
new BeanUtilsBean().getConvertUtils().register(new MyConverter(), Map.class);
在哪里为任何Map实例(例如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);
这看起来很讨厌,我相信一定有更好的办法吗?
答案 0 :(得分: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/
的评论中得到了解决方案答案 1 :(得分:2)
试图做同样的事情(我的用例是所有类型的Enum的常见转换器)但是从我在代码中看到的ConvertUtils只支持转换器和类之间的直接映射,并且没有办法注册基类或接口。
基本上它使用的是Map,其中键是类和转换器的值,并且在类中获得正确的转换器它只是执行Map#get。