当用到了时间等非内置对象时,如果对象为NULL则,会出现此异常。最简单的方法就是保证非内置对象不为NULL。
还有其它高手给出的修改commons包相关源码的解决方案,也一并给出:
<1>时间解决方案:方案一:问题解决: 读了他的源程序,发现日期java.sql.date主要是用org.apache.commons.beanutils.converters.SqlDateConverter类进行转的:修改下面的代码就可以了 public SqlDateConverter(Object defaultValue) { this.defaultValue = defaultValue; this.useDefault = true; //原本为false; }
public SqlDateConverter() { this.defaultValue = null; this.useDefault = true; //原本为false; 我也不记是那个是false了,反正修改为true就可以了 }方案二:
1、ActionForm里面有java.util.Date类型,但是页面没有输入,遇到错误。
2、利用BeanUtils.copyProperties(ActionForm, Model)时,因为ActionForm里面的java.util.Date那个字段为null又出现错误。
这两个问题都与BeanUtils.copyProperties方法有关 故解决思路是与解决BeanUtils问题。由于BeanUtils的这个方法还未内置ava.util.Date类型转换支持,因此首先把java.util.Date类型切换成java.sql.Date类型。
对于1来说,利用下列代码来解决,接桥接模式:
private java.sql.Date date;
public String getDateDisplay() { if (this.date==null) return null; DateFormat dateFormatter = DateFormat.getDateInstance(DateFormat.default,this.getLocale()); return dateFormatter.format(this.date);}
public void setDateDisplay(String dispaly){ if (dispaly==null|| display.trim().equals(“”)) { this.date = null; } else { DateFormat dateFormatter = DateFormat.getDateInstance(DateFormat.default,this.getLocale()); this.date = dateFormatter.parse(display); }}
对第2个问题,方法是,,实现自己的SqlDateConverter和SqlTimestampConverter类的convert方法:
package org.study.common.util;
import java.sql.Date;
import org.apache.commons.beanutils.ConversionException;import org.apache.commons.beanutils.Converter;import org.apache.commons.logging.*;
public final class SqlDateConverter implements Converter {
private Log log = LogFactory.getLog(this.getClass());
public SqlDateConverter() { this.defaultValue = null; this.useDefault = false; }
public SqlDateConverter(Object defaultValue) {
this.defaultValue = defaultValue; this.useDefault = true; }
private Object defaultValue = null;
private boolean useDefault = true;
public Object convert(Class type, Object value) {
if (value == null || “”.equals(value)) { if (useDefault) { return (defaultValue); } else { throw new ConversionException(“No value specified”); } }
if (value instanceof Date) { return (value); }
try { return (Date.valueOf(value.toString())); } catch (Exception e) { log.error(“convert error ocured.”, e); if (useDefault) { return (defaultValue); } else { throw new ConversionException(e); } } }}
对SqlTimestampConverter也类似处理,然后在BaseAction中添加如下代码static { ConvertUtils.register(new SqlDateConverter(null), java.sql.Date.class); ConvertUtils.register(new SqlTimestampConverter(null), java.sql.Timestamp.class);}
在解决这个问题时,发现一个第3放的Bean Mapper工具dozer很不错的,它是基于BeanUtils开发的类拷贝和属性转换开源包。
3、发现下面代码中居然报Bean error not defined in any scope。
<logic:messagesPresent> <html:messages> <bean:write/></html:messages> </logic:messagesPresent>
经过仔细派查,发现问题在于在Action中保存错误消息:errors.add(Globals.ERROR_KEY, new ActionMessage( “error.saveStudent”, student.getName(), ex.getMessage()));时,忘了在资源文件中定义error.saveStudent,从而造成该错误消息并未真正生成,也就当然不存在Bean了了:) 寒啊…..
4、Eclipse的PropertyEditor每次都把中文的资源文件变成乱码。处理办法:1)在window–>preference–>General–>Content Types中设置java propertiy files为GB2312编码。2)用ant来做native2ascii转换:<?xml version=”1.0″ encoding=”GB2312″ ?>
<project basedir=”.”><property value=”.” /><property value=”${app.home}/src” /><property value=”${app.home}/WebRoot” /><property value=”${web.home}/WEB-INF/lib” /><property value=”${web.home}/WEB-INF/classes” /><property value=”java/resources” /><property value=”${src.home}/${resources.package}”/><property value=”${classes.home}/${resources.package}”/>
<path> <pathelement location=”${lib.home}” /> <pathelement path=”${lib.home}” /></path>
<!–主要完成资源文件的编码文件格式转换和拷贝到目标资源。–><target> <delete includeemptydirs=”true” quiet=”true”> <fileset dir=”${resources.dest}”> <include/> </fileset> </delete> <mkdir dir=”${resources.dest}”/> <native2ascii encoding=”GB2312″ src=”${resources.src}” dest=”${resources.dest}” includes=”**/*_zh_CN.properties” /> <copy todir=”${resources.dest}”> <fileset dir=”${resources.src}”> <include/> <exclude/> </fileset> </copy></target>
</project>
<2>大字段解决方案:做属性拷贝的时候类型为BigDecimal属性的值是null,所以会出现这样的错误。 因为如果你看BeanUtils的源代码就知道,对于BigDecimal类型的属性其对应的转换器类BigDecimalConverter在调用convert方法的时候会做如下判断:
Java code public Object convert(Class type, Object value) {[color=#FF6600] if (value == null) { if (useDefault) { return (defaultValue); } else { throw new ConversionException(“No value specified”); } }[/color]
if (value instanceof BigDecimal) { return (value); }
try { return (new BigDecimal(value.toString())); } catch (Exception e) { if (useDefault) { return (defaultValue); } else { throw new ConversionException(e); } }
}
红色部分就是产生这个错误的原因,首先被拷贝对象的该属性值为null,同时useDefault是false(这个在BigDecimalConverter类默认实例化的时候就定义了,如下代码:)
Java code public BigDecimalConverter() {
this.defaultValue = null; this.useDefault = false;
}
所以会产生你所遇到的错误。
对bBean这个对象中的BigDecimal类型属性进行赋值,然后进行属性拷贝,就可以避免你的错误。
走过一段路,风景毕竟不相同。这段惠风和畅,