现象
org.apache.commons.beanutils.ConversionException: No value specified for 'java.sql.Timestamp'
org.apache.commons.beanutils.ConversionException: No value specified for 'java.sql.Date'
org.apache.commons.beanutils.ConversionException: No value specified for 'Date'
当调用 org.apache.commons.beanutils.BeanUtils.copyProperties(Object dest,Object orig) 方法时,当对象中有日期类属性且值为空时,会抛错 ConversionExcetpion : no value specified for XXX。
测试代码
依赖
<!-- https://mvnrepository.com/artifact/commons-beanutils/commons-beanutils -->
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
<version>1.8.2</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
</dependency>
DTO
package cn.pengld.beanutiltest;
import lombok.Data;
import java.io.Serializable;
import java.sql.Timestamp;
import java.util.Date;
/**
* @ClassName Account
* @Description
* @Author pengld
* @Date 2021/6/2 22:40
* @Version 1.0
*/
@Data
public class Account implements Serializable {
Integer id;
String nickname;
Date birth;
java.sql.Date birth2;
Timestamp birth3;
@Override
public String toString() {
return "Account{" +
"id=" + id +
", nickname='" + nickname + '\'' +
", birth=" + birth +
", birth2=" + birth2 +
", birth3=" + birth3 +
'}';
}
}
Test
package cn.pengld.beanutiltest;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.ConvertUtils;
/**
* @ClassName BeanUtilEx
* @Description
* @Author pengld
* @Date 2021/6/2 22:11
* @Version 1.0
*/
public class BeanUtilEx {
public static void main(String[] args) {
Account account = new Account();
account.setId(1);
account.setNickname("liming");
Account account2 = new Account();
try {
// ConvertUtils.register(new org.apache.commons.beanutils.converters.SqlDateConverter(null), java.sql.Date.class);
// ConvertUtils.register(new org.apache.commons.beanutils.converters.SqlDateConverter(null), java.util.Date.class);
// ConvertUtils.register(new org.apache.commons.beanutils.converters.SqlTimestampConverter(null), java.sql.Timestamp.class);
BeanUtils.copyProperties(account2, account);
System.out.println(account);
System.out.println(account2);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
}
解决方案
为ConvertUtils注册日期来的converter,设置defaultValue为null,即当类属性为空时设置为 NULL
ConvertUtils.register(new org.apache.commons.beanutils.converters.SqlDateConverter(null), java.sql.Date.class);
ConvertUtils.register(new org.apache.commons.beanutils.converters.SqlDateConverter(null), java.util.Date.class);
ConvertUtils.register(new org.apache.commons.beanutils.converters.SqlTimestampConverter(null), java.sql.Timestamp.class);
阿里编码规约检查
避免使用Apache BeanUtils进行属性的copy
IDE 安装阿里编码规约扫描插件,开启扫描,显示: