org.apache.commons.beanutils.ConversionException: No value specified

来源:互联网 发布:linux 卸载samba 编辑:程序博客网 时间:2024/05/20 02:22

org.apache.commons.beanutils.ConversionException: No value specified的解决办法 

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 id="error">
   <bean:write name="error"/>
  </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 name="app.home" value="." />
 <property name="src.home" value="${app.home}/src" />
 <property name="web.home" value="${app.home}/WebRoot" />
 <property name="lib.home" value="${web.home}/WEB-INF/lib" />
 <property name="classes.home" value="${web.home}/WEB-INF/classes" />
 <property name="resources.package" value="java/resources" />
 <property name="resources.src" value="${src.home}/${resources.package}"/>
 <property name="resources.dest" value="${classes.home}/${resources.package}"/>

 <path id="compile.classpath">
  <pathelement location="${lib.home}" />
  <pathelement path="${lib.home}" />
 </path>
 
 <!--主要完成资源文件的编码文件格式转换和拷贝到目标资源。-->
 <target name="resources">
  <delete includeemptydirs="true" quiet="true">
   <fileset dir="${resources.dest}">
    <include name="*.properties"/>
   </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 name="*.properties"/>
    <exclude name="*.zh_CN.properties"/>
   </fileset>
  </copy>
 </target>

</project>
3)安装了一个第三方插件:de.guhsoft.jinto_0.10.3.zip。这个工具非常方便,也省得了每次改完资源文件再运行ant的麻烦,好冬冬啊...

原创粉丝点击