Apache Beanutils的使用

Beanutils的常见用法

由于我们在使用Java 原生api处理反射或内省操作时会比较麻烦,所以也就催生出了该api的产生。该api具备简化代码,提高代码可读性等优点。下面着重介绍该api中常用方法的使用

笔者建立的是maven项目,所以将gav展示如下:

<dependency>
    <groupId>commons-beanutils</groupId>
    <artifactId>commons-beanutils</artifactId>
    <version>1.8.3</version>
</dependency>
<dependency>
    <groupId>commons-logging</groupId>
    <artifactId>commons-logging</artifactId>
    <version>1.1.2</version>
</dependency>
由于BeanUtils源码中有引用log日志类,所以commons-logging jar包不能少
  • BeanUtils

cloneBean(Object bean):基于可用的属性getter和setter克隆一个bean,即使bean类本身并没有实现可克隆的。通俗一点就是克隆一个对象

describe(Object bean):获取对象中属性的键值对,即获取每一个字段以及字段的值

copyProperties(Object dest, Object orig):拷贝对象中的属性值至另一个对象,要求字段名要一样

populate(Object bean, Map properties):根据指定的名称/值对填充指定bean的java bean属性。

关于setProperty与getProperty方法由于最终调用的是PropertyUtils中的方法,所以在说到PropertyUtils时再介绍

  • ConvertUtils

convert方法:将某值转换成给定的数据类型

目前基本转换方式支持的类型如下:
java.lang.BigDecimal (no default value)
java.lang.BigInteger (no default value)
boolean and java.lang.Boolean (default to false)
byte and java.lang.Byte (default to zero)
char and java.lang.Character (default to a space)
java.lang.Class (no default value)
double and java.lang.Double (default to zero)
float and java.lang.Float (default to zero)
int and java.lang.Integer (default to zero)
long and java.lang.Long (default to zero)
short and java.lang.Short (default to zero)
java.lang.String (default to null)
java.io.File (no default value)
java.net.URL (no default value)
java.sql.Date (no default value)
java.sql.Time (no default value)
java.sql.Timestamp (no default value)

register(Converter converter, Class clazz):若要转换的类型不是上述类型,使用上面方法会抛出异常。因此需要手动注册转换器

  • PropertyUtils

getProperty(Object bean, String name):获取Bean中某字段的值
setProperty(Object bean, String name, Object value):设置Bean中某字段的值

getSimpleProperty(Object bean, String name):获取Bean中某字段的值 当字段数据类型是Java语言的原生类型(如:int型),简单的类(如:java.lang.String),或 者一个复杂类的对象,这个类可能来自Java语言或者来自应用程序再或者来自应用程序中的一个类库时 使用
setSimpleProperty(Object bean,String name, Object value):设置Bean中字段的值 当字段数据类型是Java语言的原生类型(如:int型),简单的类(如:java.lang.String),或 者一个复杂类的对象,这个类可能来自Java语言或者来自应用程序再或者来自应用程序中的一个类库时 使用

getIndexedProperty(Object bean,String name, int index)
getIndexedProperty(Object bean, String name):获取Bean中某字段的值 当字段类型是List时使用
setIndexedProperty(Object bean, String name,int index, Object value)
setIndexedProperty(Object bean, String name,Object value):设置属性的值 当字段类型是List时使用

getMappedProperty(Object bean, String name)
getMappedProperty(Object bean,String name, String key):获取Bean中某字段的值 当字段类型是Map时使用
setMappedProperty(Object bean, String name,Object value)
setMappedProperty(Object bean, String name,String key, Object value):设置属性的值 当字段类型是Map时使用

getNestedProperty(Object bean, String name):获取Bean中某字段的值,常用于字段类型是自定义对象时 使用
setNestedProperty(Object bean,String name, Object value):设置Bean中某字段的值,常用于字段类型是自定义对象时 使用

简述几种设置值、获取值方法的使用 
假设有一对象User:
public class User{
private String name;
private List<String> hobbies;
private Map<String,Object> map;
private Course course;(内有普通字段name)
...
}
若获取name属性的值:则getSimpleProperty(user(User实例),"name")
设置name属性的值,getSimpleProperty(user,"name","value") 

若获取hobbies中某个值,如第一个吧
getIndexProperty(user,"hobbies[0]")或者
getIndexProperty(user,"hobbies",0) 
设置某个索引的值:
setIndexProperty(user,"hobbies[0]","value")或者
setIndexProperty(user,"hobbies",0,"value") 

获取map中某个key对应的value值:
getMappedProperty(user,"map(key)")或者
getMappedProperty(user,"map","key") 
设置map中某个key对应的value值:
setMappedProperty(user,"map(key)","value")或者
setMappedProperty(user,"map","key","value")

获取course中name属性的值
getNestedProperty(user,"course.name")
设置course中name属性的值
setNestedProperty(user,"course.name","value") 

在使用时,看准字段的数据类型,当是list集合时,要使用[];当是map时,要使用();
当是嵌套对象时,要使用.(点) 

若不想这么麻烦,可直接使用getProperty或者setProperty,但是规则还要根据字段的数据类型来定;若设置hobbies中第二个位置的值 
setProperty(user,"hobbies[1]","value") 
以此类推
  • ConstructorUtils

Object invokeConstructor(Class klass,Object[] args,Class[] parameterTypes):通过构造函数 构造对象 agrs是构造函数中值的集合,parameterTypes是构造函数中值类型的集合;如果无法找到匹配的构造函数 则抛出异常

  • DynaBean、DynaClass

可以在不定义一个Java类的前提下,动态决定这个类中包含哪些属性,并动态访问它们的属性值

有一篇博客写的不错 解释的很清楚 我就不在这班门弄斧了
动态Bean

  • MethodUtils

MethodUtils中的常用invoke方法与ConstrutorUtils使用差不多,需要传递方法名、参数或者参数类型;使用方式很类似 这里就不再赘述

注意:每个Utils类都和一个Bean类对应,如BeanUtils与BeanUtilsBean等等,具体方法的实现在对应的Bean中

  • 代码演示:
public class User implements Serializable {
    private static final long serialVersionUID = 1L;
    private String name;
    private String age;
    private String address;
    private String[] hobbies;
    private Date birthday;
    private Map people;
    private course course;

    public course getCourse() {
        return course;
    }

    public void setCourse(course course) {
        this.course = course;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAge() {
        return age;
    }

    public void setAge(String age) {
        this.age = age;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public String[] getHobbies() {
        return hobbies;
    }

    public void setHobbies(String[] hobbies) {
        this.hobbies = hobbies;
    }

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }

    public Map getPeople() {
        return people;
    }

    public void setPeople(Map people) {
        this.people = people;
    }

    public User() {

    }

    public User(String name, String age, String address, String[] hobbies) {
        super();
        this.name = name;
        this.age = age;
        this.address = address;
        this.hobbies = hobbies;
    }

    public User(String name) {
        super();
        this.name = name;
    }

}

    User user = new User("wojiushiwo", "23", "上海", new String[] { "play", "sing" });

    // BeanUtils.setProperty(user, "name", "我就是我");

    // 克隆的 不是一个对象了
    Object cloneBean = BeanUtils.cloneBean(user);
    System.out.println(user);
    System.out.println(cloneBean);

演示结果:
com.wojiushiwo.CommonBeanUtilsDemo.User@4d405ef7
com.wojiushiwo.CommonBeanUtilsDemo.User@6193b845

    User user = new User("wojiushiwo", "23", "上海", new String[] { "play", "sing" });


    Map map = BeanUtils.describe(user);
     Set entrySet = map.entrySet();
    for (Object object : entrySet) {
        System.out.println(object);
    }  

演示结果:
birthday=null
address=上海
hobbies=play
name=wojiushiwo
course=null
class=class com.wojiushiwo.CommonBeanUtilsDemo.User
people=null
age=23
数据为null的是 没有设置值

//测试拷贝
public class CopyTestDemo implements Serializable {
    private static final long serialVersionUID = 1L;

    private String name;
    private String age;
    private boolean win;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAge() {
        return age;
    }

    public void setAge(String age) {
        this.age = age;
    }

    public boolean isWin() {
        return win;
    }

    public void setWin(boolean win) {
        this.win = win;
    }

    @Override
    public String toString() {
        return "name:" + name + ";age:" + age+";win:"+win;
    }
} 

// 对象中属性数据的拷贝
    CopyTestDemo demo = new CopyTestDemo();
    BeanUtils.copyProperties(demo, user);
    System.out.println(demo);

演示结果:
name:wojiushiwo;age:23;win:false(boolean 未设置值 默认false)

User entity = new User();
Map properties = new HashMap();
properties.put("name", "测试populate");
BeanUtils.populate(entity, properties);
System.out.println(entity.getName());

演示结果(字段太多,只设置一个):
测试populate

//简单数据类型之间的转换
Object convert = ConvertUtils.convert("23", int.class);
System.out.println(convert instanceof Integer);
//结果是true 
当待转换类型不是上面提到的,则需要注册转换器,如将字符串日期转换为java.util.Date,否则抛出异常ConversionException 

ConvertUtils.register(new Converter() {
        //type 要转换成的类型;value 待转换的数据
        public Object convert(Class type, Object value) {
            if (type != Date.class) {
                return null;
            }
            if (value == null || "".equals(value.toString().trim())) {
                return null;
            }
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            Date date = null;
            try {
                date = sdf.parse((String) value);
            } catch (ParseException e) {
                e.printStackTrace();
            }
            return date;
        }
    }, Date.class);  
    //注册完转换器之后 ConvertUtils类中默认就只有这一个转换器类,不知道这么理解对不对,还请大神指教!!!
     Object convert = ConvertUtils.convert("2017-10-09", Date.class);
     System.out.println(convert);

输出结果:
Mon Oct 09 00:00:00 CST 2017

//创建实例对象 
Obejct[] data={"wojiushiwo"};
Class[] types={String.class};
User user=(User)ConstructorUtils.invokeConstructor(User.class,
         data,types);
System.out.println(u.getName());

演示结果:
wojiushiwo

以上!若有错误,请指出 谢谢!

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值