进来看了下孔浩老师的java视频,发现讲了挺多有用的知识,现在对BeanUtils的使用,做一个总结。
1、引入commons-beanutils和commons-logging包
2、创建实体对象,例如User
import java.util.Date;
public class User {
private int id;
private String username;
private int age;
private String password;
private Date birthday;
private Point point;
public Point getPoint() {
return point;
}
public void setPoint(Point point) {
this.point = point;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
}
User类中,包含一个Point类
public class Point {
private int x;
private int y;
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
}
3、BeanUtils可以完成简单的转换,例如int到String,但复杂的转换,或者说是用户自定义的转换,必须用户自己写转换器,例如本例中的birthday和point,写两个转换器
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import org.apache.commons.beanutils.Converter;
public class DateConverter implements Converter {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
/**
* 该方法中的两个参数,第一个参数表示要转换的类型,如果要拷贝一个字符串到日期中,此时这个类型
* 就是日期类型,第二个参数表示要转换的值
* 该方法的返回值就是转换之后的值
*/
@Override
public Object convert(Class clz, Object value) {
//1、判断要转换的类型是否符合要求
if(clz!=Date.class) {
return null;
}
try {
if(value instanceof String) {
return simpleDateFormat.parse((String)value);
}
} catch (ParseException e) {
e.printStackTrace();
}
return null;
}
}
import org.apache.commons.beanutils.Converter;
public class PointConvert implements Converter {
@Override
public Object convert(Class clz, Object value) {
if(clz!=Point.class) return null;
if(value instanceof String) {
String v = (String)value;
String[] vs = v.split(",");
Point p = new Point();
p.setX(Integer.parseInt(vs[0]));
p.setY(Integer.parseInt(vs[1]));
return p;
}
return null;
}
}
4、测试过程
调用前得先注册转换器,如:
ConvertUtils.register(new DateConverter(), Date.class);//注册转换器
注册转换器的原理就是,把DateConverter转换器放到CovertUtils中的WeakFastHashMap converters中,然后遇到转换Date类型,就到这个map中找,如果找到属性为java.util.Date的转换器,就用这个用户定义的方法,把String转换成Date,然后用反射,调用User的setBirthday方法,把转换后的值放进去。
具体测试代码如下:
import java.lang.reflect.InvocationTargetException;
import java.util.Date;
import itat.zttc.model.DateConverter;
import itat.zttc.model.Point;
import itat.zttc.model.PointConvert;
import itat.zttc.model.User;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.ConvertUtils;
import org.junit.Test;
public class TestBeanUtil {
@Test
public void test01() {
try {
User u = new User();
// String value = "张三";
User value = new User();
String key = "username";
/**
* 复制属性过程
* 1、先解析User对象中是否有username的属性,如果有继续,没有,直接return
* 2、判断username的类型,是String,还是int,还是其他类型
* 3、通过上面判断出的类型,调用相应的转换器,如果是,就会把传入的value转成String,如果是对象,调用toString方法,然后set进去
* 4、如果判断的类型不存在相应的转换器,报异常java.lang.IllegalArgumentException: argument type mismatch
*/
BeanUtils.copyProperty(u, key, value);
System.out.println(u.getUsername());
BeanUtils.copyProperty(u, "age", 1);
BeanUtils.copyProperty(u, "ddd", value);//User不存在ddd这个属性,也不会报错
//此时无法拷贝日期,因为BeanUtils根本不知道如何来转换日期1988/2/2
//这个时候就需要自己定义相应的转换器来完成转换
/*
* 定义转换器的步骤
* 1、创建一个类让其实现Converter接口
* 2、覆盖这个接口中的convert方法,在这个方法中实现转换
* 3、在拷贝属性之前注册转换器
*/
ConvertUtils.register(new DateConverter(), Date.class);//注册转换器
ConvertUtils.register(new PointConvert(), Point.class);
BeanUtils.copyProperty(u, "birthday","1977-12-22");
BeanUtils.copyProperty(u, "point","76,33");
System.out.println(u.getBirthday());
System.out.println(u.getPoint().getX()+","+u.getPoint().getY());
User u2 = new User();
BeanUtils.copyProperties(u2, u);
System.out.println(u2.getUsername()+u2.getAge());
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}