如果處理 BigDecimal 的 property 賦值, 而其值為 null 時, 會出現...
Exception in thread "main" org.apache.commons.beanutils.ConversionException: No value specified
at org.apache.commons.beanutils.converters.BigDecimalConverter.convert(BigDecimalConverter.java:...)
...
解決問題前, 先從 BeanUtils 取得 BeanUtilsBean.getInstance() 來處理 copyProperties() 的 source 中看到:
private static final ContextClassLoaderLocal beansByClassLoader = new ContextClassLoaderLocal() {
protected Object initialValue() {
return new BeanUtilsBean();
}
};
實際是使用了預設的 BeanUtilsBean() constructor:
public BeanUtilsBean() {
this(new ConvertUtilsBean(), new PropertyUtilsBean());
}
public BeanUtilsBean(ConvertUtilsBean convertUtilsBean, PropertyUtilsBean propertyUtilsBean) {
this.log = LogFactory.getLog(BeanUtils.class);
this.convertUtilsBean = convertUtilsBean;
this.propertyUtilsBean = propertyUtilsBean;
}
明顯的看到它使用了預設的 ConvertUtilsBean() constructor, 並在 deregister() method 中建構各類型的 converter 以便爾後的 properties 賦值處理: public ConvertUtilsBean() {
this.converters.setFast(false);
deregister();
this.converters.setFast(true);
}
...
public void deregister() {
...
register(BigDecimal.class, new BigDecimalConverter());
...
}
...
但, 當中 BigDecimalConverter() constructor 是不預設賦值的: public BigDecimalConverter() {
this.defaultValue = null;
this.useDefault = false;
}
另一 constructor 則是: public BigDecimalConverter(Object defaultValue) {
this.defaultValue = defaultValue;
this.useDefault = true;
}
也就是說, 可以使用另一組 BigDecimalConverter() constructor 來避免上述的 exception 發生: BeanUtilsBean defaultNullValueBeanUtils = new BeanUtilsBean(new ConvertUtilsBean() {
@Override
public void deregister() {
super.deregister();
// 這裡還是預設了 null 為其值
register(new org.apache.commons.beanutils.converters.BigDecimalConverter(null), BigDecimal.class);
...
}
}, new PropertyUtilsBean());
...
defaultNullValueBeanUtils.copyProperties(dest, orig);
...
done!
沒有留言:
張貼留言