javaweb学习总结五(内省、beanUtils工具包)

一:内省的概念

1:内省是反射的一种特例,由于在反射中频繁的操作javabean,所以为了方便反射

javabean,sun公司开发出一套API提高效率。

2:javaBean,就是用来封装客户端请求数据,有字段、get、set方法的对象,javaBean对象的属性有getXXX方法

决定。

 

二:内省访问JavaBean

1:定义javaBean

 1 public class Person {
 2     private String name;
 3     private int age;
 4 
 5     public String getName() {
 6         return name;
 7     }
 8 
 9     public void setName(String name) {
10         this.name = name;
11     }
12 
13     public int getAge() {
14         return age;
15     }
16 
17     public void setAge(int age) {
18         this.age = age;
19     }
20 
21     public double getSalary() {
22         return 12000.0;
23     }
24 }

2:访问javaBean对象

a:获取所有的属性

1 @Test
2     // 获取所有的属性
3     public void test1() throws Exception {
4         BeanInfo bi = Introspector.getBeanInfo(Person.class);
5         PropertyDescriptor[] pds = bi.getPropertyDescriptors();
6         for (PropertyDescriptor pd : pds) {
7             System.out.println(pd.getName());
8         }
9     }

运行结果:

age
class
name
salary

其中age ,name是定义的成员变量,salary是getSlary()方法定义的,class是因为Person继承了Object类,

所以也继承了Object的方法getClass();

要想得到自己定义的类,可以使用getBeanInfof(Person.class,Object.class)方法,如下:

 1 @Test
 2     // 获取所有的属性
 3     public void test1() throws Exception {
 4         // BeanInfo bi = Introspector.getBeanInfo(Person.class);
 5         BeanInfo bi = Introspector.getBeanInfo(Person.class, Object.class);
 6         PropertyDescriptor[] pds = bi.getPropertyDescriptors();
 7         for (PropertyDescriptor pd : pds) {
 8             System.out.println(pd.getName());
 9         }
10     }

运行结果:

age
name
salary

 

b:操作属性

 1 @Test
 2     // 操作属性
 3     public void test2() throws Exception {
 4         Person p = new Person();
 5         PropertyDescriptor pd = new PropertyDescriptor("age", Person.class);
 6         // 获取getxxx()方法
 7         Method m = pd.getWriteMethod();
 8         m.invoke(p, 27);
 9         // 获取setxxx()方法
10         m = pd.getReadMethod();
11         System.out.println(m.invoke(p, null));
12     }

 

c:获取当前属性的类型

1 // 获取当前属性的类型
2     public void test3() throws Exception {
3         PropertyDescriptor pd = new PropertyDescriptor("age", Person.class);
4         System.out.println(pd.getPropertyType());
5     }

运行结果:

int

 

三:BeanUtils工具类的使用

beanUtils工具是apache基金会为了方便操作javaBean类,开发的一套API,在实际的开发中使用多于内省。

1:使用beanUtils设置属性的值

1 @Test
2     // 使用beanutils设置属性
3     public void test01() throws Exception {
4         Person p = new Person();
5         BeanUtils.setProperty(p, "age", 27); // 设置age为27
6         System.out.println(p.getAge());
7     }

2:beanUtils内部有类型自动转换的机制,String类型可以转换为8种基本数据类型,如下:

1 @Test
2     public void test02() throws Exception {
3         Person p = new Person();
4         String name = "Jack";
5         String age = "27";
6         BeanUtils.setProperty(p, "name", name);
7         BeanUtils.setProperty(p, "age", age); // 这里String类型转换为int类型
8         System.out.println(p.getName() + ":" + p.getAge());
9     }

本来Person类中age为int类型,但是String类型的age直接赋给了bean,但是转换仅限于8种基本数据类型。

3:如果是其他的类型,则转换会失败,如下Date类型,String转换是就会报错:

 1 @Test
 2     public void test03() throws Exception {
 3         Person p = new Person();
 4         String name = "Jack";
 5         String age = "27";
 6         String birthday = "2010-10-02";
 7         BeanUtils.setProperty(p, "name", name);
 8         BeanUtils.setProperty(p, "age", age); // 这里String类型转换为int类型
 9         BeanUtils.setProperty(p, "birthday", birthday); // 这里会报错,因为String类型自动转化仅限于8种基本类型
10         System.out.println(p.getName() + ":" + p.getAge() + ":"
11                 + p.getBirthday());
12     }

异常如下:

4:自定义String到Date的转化器

 1 @Test
 2     public void test04() throws Exception {
 3         Person p = new Person();
 4         String name = "Jack";
 5         String age = "27";
 6         String birthday = "2010-10-02";
 7         ConvertUtils.register(new Converter() {
 8 
 9             @Override
10             public Object convert(Class arg0, Object value) {
11                 if (value == null) {
12                     return null;
13                 }
14                 if (!(value instanceof String)) {
15                     throw new ConversionException("转换异常!");
16                 }
17                 String str = (String) value;
18                 if (str.trim().equals("")) {
19                     return null;
20                 }
21                 // 排除以上情况,开始转换
22                 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
23                 try {
24                     return sdf.parse(str);
25                 } catch (ParseException e) {
26                     throw new RuntimeException(e);
27                 }
28             }
29 
30         }, Date.class); // 将转换器里定义转换方法
31         BeanUtils.setProperty(p, "name", name);
32         BeanUtils.setProperty(p, "age", age); // 这里String类型转换为int类型
33         BeanUtils.setProperty(p, "birthday", birthday); // 这里会报错,因为String类型自动转化仅限于8种基本类型
34         System.out.println(p.getName() + ":" + p.getAge() + ":"
35                 + p.getBirthday());
36     }

转换成功!

5:使用BeanUtils定义的转化器

 1 @Test
 2     public void test05() throws Exception {
 3         Person p = new Person();
 4         String name = "Jack";
 5         String age = "27";
 6         String birthday = "2010-10-02";
 7         ConvertUtils.register(new DateLocaleConverter(), Date.class); // 将转换器里定义转换方法
 8         BeanUtils.setProperty(p, "name", name);
 9         BeanUtils.setProperty(p, "age", age); // 这里String类型转换为int类型
10         BeanUtils.setProperty(p, "birthday", birthday); // 这里会报错,因为String类型自动转化仅限于8种基本类型
11         System.out.println(p.getName() + ":" + p.getAge() + ":"
12                 + p.getBirthday());
13     }

但是这里有几个问题:

a:导包错误,导入java.util.Date,而不是java.sql.Date,否则报错,如下:

b:导入的commons-beanUtils.jar版本不对,建议commons-beanUtils-1.9.2.jar或者commons-beanUtils-1.9.2.jar都可以,

否则报错如下:

c:但是使用自定义的转换器有缺点,就是当日期字符串为空时,它不能判断,仍然后进行转换,异常如下:

但是自定义的转换器是没有这个问题的。

6:将map里存储的key-value封装到bean里面

 1 @Test
 2     public void test06() throws Exception {
 3         Person p = new Person();
 4         Map<String, Object> map = new HashMap<String, Object>();
 5         String name = "Jack";
 6         String age = "27";
 7         String birthday = "2010-10-02";
 8         ConvertUtils.register(new DateLocaleConverter(), Date.class);
 9         map.put("name", name);
10         map.put("age", age);
11         map.put("birthday", birthday);
12         BeanUtils.populate(p, map);
13         System.out.println(p.getName());
14         System.out.println(p.getAge());
15         System.out.println(p.getBirthday());
16     }

以上代码均已经验证!

posted @ 2016-07-28 22:40  程序员三藏  阅读(1488)  评论(1编辑  收藏  举报