|
beanutils用了魔术般的反射技术,实现了很多夸张有用的功能,都是c/c++时代不敢想的。无论谁的项目,始终一天都会用得上它。我算是后知后觉了,第一回看到它的时候居然错过。 1.属性的动态getter、setter 在这框架满天飞的年代,不能事事都保证执行getter,setter函数了,有时候属性是要根据名字动态取得的,就像这样: beanutils.getproperty(mybean,"code"); 而common beanutils的更强功能在于可以直接访问内嵌对象的属性,只要使用点号分隔。 beanutils.getproperty(orderbean, "address.city"); 相比之下其他类库的beanutils通常都很简单,不能访问内嵌的对象,所以有时要用commons beanutils来替换它们。
beanutils还支持list和map类型的属性,如下面的语法即可取得order的顾客列表中第一个顾客的名字 beanutils.getproperty(orderbean, "customers[1].name"); 其中beanutils会使用convertutils类把字符串转为bean属性的真正类型,方便从httpservletrequest等对象中提取bean,或者把bean输出到页面。 而propertyutils就会原色的保留bean原来的类型。 2.beancompartor 动态排序 还是通过反射,动态设定bean按照哪个属性来排序,而不再需要在实现bean的compare接口进行复杂的条件判断。 list peoples = ...; // person对象的列表 collections.sort(peoples, new beancomparator("age")); 如果要支持多个属性的复合排序,如"order by lastname,firstname" arraylist sortfields = new arraylist(); sortfields.add(new beancomparator("lastname")); sortfields.add(new beancomparator("firstname")); comparatorchain multisort = new comparatorchain(sortfields); collections.sort(rows,multisort); 其中comparatorchain属于jakata commons-collections包。 如果age属性不是普通类型,构造函数需要再传入一个comparator对象为age变量排序。 另外, beancompartor本身的compareblecomparator, 遇到属性为null就会抛出异常, 也不能设定升序还是降序。这个时候又要借助commons-collections包的comparatorutils. comparator mycmp = comparablecomparator.getinstance(); mycmp = comparatorutils.nulllowcomparator(mycmp); //允许null mycmp = comparatorutils.reversedcomparator(mycmp); //逆序 comparator cmp = new beancomparator(sortcolumn, mycmp); 3.converter 把request或resultset中的字符串绑定到对象的属性 经常要从request,resultset等对象取出值来赋入bean中,如果不用mvc框架的绑定功能的话,下面的代码谁都写腻了。 string a = request.getparameter("a"); bean.seta(a); string b = .... bean.setb(b); ......不妨写一个binder自动绑定所有属性: mybean bean = ...; 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的populate方法或者getproperty,setproperty方法其实都会调用convert进行转换。 但converter只支持一些基本的类型,甚至连java.util.date类型也不支持。而且它比较笨的一个地方是当遇到不认识的类型时,居然会抛出异常来。 对于date类型,我参考它的sqldate类型实现了一个converter,而且添加了一个设置日期格式的函数。 要把这个converter注册,需要如下语句: convertutilsbean convertutils = new convertutilsbean(); dateconverter dateconverter = new dateconverter(); convertutils.register(dateconverter,date.class);
//因为要注册converter,所以不能再使用beanutils的静态方法了,必须创建beanutilsbean实例 beanutilsbean beanutils = new beanutilsbean(convertutils,new propertyutilsbean()); beanutils.setproperty(bean, name, value); 4 其他功能 4.1 constructorutils,动态创建对象 public static object invokeconstructor(class klass, object arg) 4.2 methodutils,动态调用方法 methodutils.invokemethod(bean, methodname, parameter); 4.3 propertyutils,当属性为collection,map时的动态读取: collection: 提供index
beanutils.getindexedproperty(orderbean,"items",1); 或者 beanutils.getindexedproperty(orderbean,"items[1]"); map: 提供key value beanutils.getmappedproperty(orderbean, "items","111");//key-value goods_no=111 或者 beanutils.getmappedproperty(orderbean, "items(111)") 4.4 propertyutils,直接获取属性的class类型
public static class getpropertytype(object bean, string name)
|