利用beanutils 操纵bean

从网上搜了这方面的知识,整理如下

在一般的写bean组件的时候,都必须要写setter和getter方法,当然假如我们事先已经知道bean的相关属性和方法,写bean是比较简单的,但是组件太多的时候,重复编写经常是枯燥乏味令人厌烦的BeanUtils就可以帮助我们来解决这个问题

如果你有两个具有很多相同属性的JavaBean,一个很常见的情况就是Struts里的PO对象(持久对象)和对应的ActionForm,例如Teacher和TeacherForm。我们一般会在Action里从ActionForm构造一个PO对象,传统的方式是使用类似下面的语句对属性逐个赋值:

//得到TeacherForm
TeacherForm teacherForm=(TeacherForm)form;
//构造Teacher对象
Teacher teacher=new Teacher();
//赋值
teacher.setName(teacherForm.getName());
teacher.setAge(teacherForm.getAge());
teacher.setGender(teacherForm.getGender());
teacher.setMajor(teacherForm.getMajor());
teacher.setDepartment(teacherForm.getDepartment());

//持久化Teacher对象到数据库
HibernateDAO=;
HibernateDAO.save(teacher);
而使用BeanUtils后,代码就大大改观了,如下所示:
//得到TeacherForm
TeacherForm teacherForm=(TeacherForm)form;
//构造Teacher对象
Teacher teacher=new Teacher();
//赋值
BeanUtils.copyProperties(teacher,teacherForm);
//持久化Teacher对象到数据库
HibernateDAO=;
HibernateDAO.save(teacher);

如果Teacher和TeacherForm间存在名称不相同的属性,则BeanUtils不对这些属性进行处理,需要程序员手动处理。例如Teacher包含modifyDate(该属性记录最后修改日期,不需要用户在界面中输入)属性而TeacherForm无此属性,那么在上面代码的copyProperties()后还要加上一句:

teacher.setModifyDate(new Date());



怎么样,很方便吧!除BeanUtils外还有一个名为PropertyUtils的工具类,它也提供copyProperties()方法,作用与BeanUtils的同名方法十分相似,主要的区别在于后者提供类型转换功能,即发现两个JavaBean的同名属性为不同类型时,在支持的数据类型范围内进行转换,而前者不支持这个功能,但是速度会更快一些

BeanUtils可以直接get和set一个属性的值。它将property分成3种类型:

Simple——简单类型,如Stirng、Int……(对于Simple类型,第二个参数直接是属性名即可,详见代码)

        Indexed——索引类型,如 数组、arrayList……(对于Indexed,则为“属性名[索引值]”,注意这里对于ArrayList和数组都可以用一样的方式进行操作,详见代码)

 Maped——这个不用说也该知道,就是指Map,比如HashMap……(对于Map类型,则需要以“属性名(key值)”的形式,详见代码)

 访问不同类型的数据可以直接调用函数getProperty和setProperty。它们都只有2个参数,第一个是JavaBean对象,第二个是要操作的属性名。

 

4.Converter 把Request或ResultSet中的字符串绑定到对象的属性 
  
 经常要从request,resultSet等对象取出值来赋入bean中,如果不用MVC框架的绑定功能的话,下面的代码谁都写腻了。
String a = request.getParameter("a");   bean.setA(a);  

String b = request.getParameter("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方法(Struts用于将一个map的值填充到一个bean中)或者getProperty,setProperty方法其实都会调用convert进行转换,但Converter只支持一些基本的类型,甚至连java.util.Date类型也不支持。而且它比较笨的一个地方是当遇到不认识的类型时,居然会抛出异常来。 对于Date类型,我参考它的sqldate类型实现了一个Converter,而且添加了一个设置日期格式的函数。
要把这个Converter注册,需要如下语句:

//因为要注册converter,所以不能再使用BeanUtils的静态方法了,必须创建BeanUtilsBean实例:

	BeanUtilsBean beanUtils =
        new BeanUtilsBean( convertUtils, new PropertyUtilsBean() ) ;
        beanUtils.setProperty( bean, name, value ) ;


BeanUtils在Struts中的应用:

下面的代码是我们经常在Struts中为了获得浏览器带来的参数的方法:

DynaActionForm daf = (DynaActionForm)form ;
        User user = new User() ;
        user.setId( daf.getString( "id" ) ) ;
        user.setPassword( daf.getString( "password" ) ) ;
        user.setUsername( daf.getString( "password" ) ) ;

是不是觉得每次写这些都是在重复造轮子呢?

在看看用BeanUtils写的:

J

BeanUtils.copyProperties( user, daf ) ;

 

就是这么简单


public class Test {
    private String name; 
    private HashMap address = new HashMap(); 
    private String[] otherInfo; 
    private ArrayList product; 
    private ArrayList employee; 
    private HashMap telephone;

//省略get/set

}



public class MainClass {

    public static void main( String[] args ) throws Exception{
        Test test = new Test();
        test.setName( "zhangyi" );
        // BeanUtils.getProperty( bean, name )
        // 动态取得
        System.out.println(BeanUtils.getProperty( test, "name" ));
        HashMap map = new HashMap();
        map.put( "1", "13880808080" );
        map.put( "2", "13550505050" );
        // BeanUtils.setProperty( bean, name, value )
        BeanUtils.setProperty( test, "telephone", map );
        // 动态取得
        System.out.println(BeanUtils.getProperty( test, "telephone(1)" ));
        /**

         * 直接进行Bean之间的clone 复制后的2个Bean的同一个属性可能拥有同一个对象的ref,

         * 这个在使用时要小心,特别是对于属性为类的情况。

         */
        Test test2 = new Test();
        BeanUtils.copyProperties( test2, test );
        System.out.println(BeanUtils.getProperty( test2, "name" ));
    }
}


其余的功能大家继续挖掘吧,可以参考官方API的说明J

ConvertUtilsBean convertUtils = new ConvertUtilsBean();
DateConverter dateConverter = new DateConverter();
convertUtils.register(dateConverter,Date.class);

BeanUtils支持的转换类型如下:

  • java.lang.BigDecimal
  • java.lang.BigInteger
  • boolean and java.lang.Boolean
  • byte and java.lang.Byte
  • char and java.lang.Character
  • java.lang.Class
  • double and java.lang.Double
  • float and java.lang.Float
  • int and java.lang.Integer
  • long and java.lang.Long
  • short and java.lang.Short
  • java.lang.String
  • java.sql.Date
  • java.sql.Time
  • java.sql.Timestamp

这里要注意一点,java.util.Date是不被支持的,而它的子类java.sql.Date是被支持的。因此如果对象包含时间类型的属性,且希望被转换的时候,一定要使用java.sql.Date类型。否则在转换时会提示argument mistype异常。


@Test
	public void test2() throws IllegalAccessException, InvocationTargetException
	{
		Person p=new Person();
		String name="ljf";
		String password="1234";
		String age="22";
		String birthday="1990-11-11";
		
		//注册日期转换器 以下是自己实现的转换器,api中也有实现好的转换器
		ConvertUtils.register(new Converter(){//Converter是接口,创建必须实现此接口
			public Object convert(Class type,Object value){
				if(value==null)
					return null;
				if(!(value instanceof String))
					throw new ConversionException("本帅只支持String 类型的转换");
				String str=(String) value;
				if(str.trim().equals(""))
					return null;
				SimpleDateFormat df=new SimpleDateFormat("yyyy-MM-dd");
				try {
					return df.parse(str);
				} catch (ParseException e) {
					throw new RuntimeException(e);
				}
			}
		}, Date.class);
		//以下是api中实现好的转换器
		ConvertUtils.register(new DateConverter(), Date.class);
		
		BeanUtils.setProperty(p, "name", name);
		BeanUtils.setProperty(p, "password", password);
		BeanUtils.setProperty(p, "age", age);
		BeanUtils.setProperty(p,"birthday", birthday);

		System.out.println(p.getName());
		System.out.println(p.getPassword());
		//可以自动处理类型转换,只支持8种基本类型,想转换其它类型用类型转换器
		System.out.println(p.getAge());
		System.out.println(p.getBirthday());
	}
	
	//另外还有常用的BeanUtils.copyProperties(dest, orig)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值