如果處理 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!