在利用struts框架来作为表示层的架构时,用FormBean来实现从页面到业务的数据交换,如果formBean中有涉及到金额的算法时要用BigDecimal来代替float,因为float的精度是有问题的。
如果简单的用BigDecimal代替float来声明变量,在编译阶段完全没有问题,但在运行阶段会出现问题。系统会抛出一个org.apache.commons.beanutil.ConversionException异常。原因在于BigDecimal的初始化。 在struts中,ActionForm从页面读取数据是一个反射的过程,对于BigDecimal类型的数据来说,其反射的源代码如下:
public Objiect convert(Class type,Obect value){
//判断页面值是否为null
if(value==null){
if(useDefault){ return (defaultValue); }
}else{ throw new ConvesionException("No value specified"); }
//判断值类型是否为BigDecimal
if (value instanceof BigDecimal){ return (value);}
try{
return (new BigDecimal(value.toString()));
}catch(Exception e){
if (useDefault) { return (defaultValue); }
else{
throw new ConversionException(e);
}
}
}
在BigDecimalConversion.java的convert()的方法中,对于页面为"空值"的传入,即value="",其将跳过之前的判断直接运行:return (new BigDecimal (value.toString()));但是BigDecimal实例化时无法实例化new BigDecimal('')因此抛出了异常。
归纳原因:
问题出在页面输入值为空,而BigDecimalConverter的convert()方法不支持反射实例化空值的BigDecimal。
解决办法:
1.声明金融类为String类型,然后处理String到BigDecimal的类型转换。
2.利用struts的ActiveServlet,在其中初始化。这种方式是Struts框架提供的将“空”值转化为null的小技巧,只需在web.xml中设置。
<init-param>
<param-name>convertNull</param-name>
<param-value>true</param-value>
</init-param>