前言
beanutils,顾名思义,是java bean的一个工具类,可以帮助我们方便的读取(get)和设置(set)bean属性值、动态定义和访问bean属性;
细心的话,会发现其实JDK已经提供了一个java.beans包,同样可以实现以上功能,只不过使用起来比较麻烦,所以诞生了apache commons beanutils;
看源码就知道,其实apache commons beanutils就是基于jdk的java.beans包实现的。
JavaBean
javabean一般有以下几个特性:
- 类必须是public访问权限,且需要有一个public的无参构造方法,之所以这样主要是方便利用Java的反射动态创建对象实例:
Class beanClass = Class.forName(className);
Object beanInstance = beanClass.newInstance();
- 由于javabean的构造方法是无参的,所以我们的bean的行为配置(即设置bean的属性值,方法对应行为,属性对应数据)不能在构造方法完成,取而代之的是通过一系列的set方法来设置属性值,通过setter方法,我们可以改变javabean呈现出来的行为和内部数据,这里的setter方法会按一定的约定来命名,如setHireDate、setName。。。
访问基本数据类型的Bean属性
- ApI
- PropertyUtils.getSimpleProperty(Object, String)
- PropertyUtils.setSimpleProperty(Object, String, Object)
- Demo
Employee employee = ...;
String firstName = (String)
PropertyUtils.getSimpleProperty(employee, "firstName");
String lastName = (String)
PropertyUtils.getSimpleProperty(employee, "lastName");
... manipulate the values ...
PropertyUtils.setSimpleProperty(employee, "firstName", firstName);
PropertyUtils.setSimpleProperty(employee, "lastName", lastName);
访问数组、list等索引类型属性
- API
- PropertyUtils.getIndexedProperty(Object, String)
- PropertyUtils.getIndexedProperty(Object, String, int)
- PropertyUtils.setIndexedProperty(Object, String, Object)
- PropertyUtils.setIndexedProperty(Object, String, int, Object)
- DEMO
Employee employee = ...;
int index = ...;
String name = "subordinate[" + index + "]";
Employee subordinate = (Employee)
PropertyUtils.getIndexedProperty(employee, name);
Employee employee = ...;
int index = ...;
Employee subordinate = (Employee)
PropertyUtils.getIndexedProperty(employee, "subordinate", index);
其他的如Map类型属性的操作
参考:官网
BeanUtils 类
简单介绍下两个方法的使用,populate和copyProperties,
- populate可以帮助我们把Map里的键值对值拷贝到bean的属性值中;
- copyProperties,顾名思义,帮我们拷贝一个bean的属性到另外一个bean中,注意是浅拷贝
HttpServletRequest request = ...;
MyBean bean = ...;
MyBean source = ...;
HashMap map = new HashMap();
Enumeration names = request.getParameterNames();
while (names.hasMoreElements()) {
String name = (String) names.nextElement();
map.put(name, request.getParameterValues(name));
}
BeanUtils.populate(bean, map);
BeanUtils.copyProperties(bean,source);
ConvertUtils 类
实际上,BeanUtils是依赖ConvertUtils来完成实际山的类型转换,但是有时候我们可能需要自定义转换器来完成特殊需求的类型转换;
自定义类型转换器步骤:
1、定义一个实现类实现Converter接口
2、调用ConvertUtils.register方法,注册该转换器
如下是一个实例,我们会在字符串转换的时候,加上一个前缀
public class CustomConverters
{
public static void main(String[] args) throws IllegalAccessException, InvocationTargetException
{
ConvertUtils.register(new StringConverter(), String.class);
Map<String, String> map = new HashMap<String, String>();
map.put("name", "001");
map.put("address", "hz");
map.put("id", "100");
map.put("state", "false");
User u = new User();
BeanUtils.populate(u, map);
System.out.println(u.toString());
}
}
class StringConverter implements Converter {
public <T> T convert(Class<T> type, Object value)
{
if(String.class.isInstance(value)){
return (T) ("***" + value);
}else{
return (T) value;
}
}
}
这里有一点需要注意,像BeanUtils, ConvertUtils 和 PropertyUtils工具类都是共享同一个转换器的,这样子虽然用起来很方便,但有时候显得不够灵活,实际上BeanUtils, ConvertUtils 和 PropertyUtils都有一个对应的可实例化的类,即BeanUtilsBean、ConvertUtilsBean、PropertyUtilsBean;
它们的功能与BeanUtils, ConvertUtils 和 PropertyUtils类似,区别是它们可以实例化,而且每个实例都可以拥有自己的类型转换器;