黑马程序员java学习<基础加强>—JavaBean

一、概述:

1、IntroSpector:即内省,是对内部进行检查,了解更多的底层细节。

2、内省的作用:主要针对JavaBean进行操作。

 

二、JavaBean

1、简述:

1)JavaBean是一种特殊的Java类,主要用于传递数据信息,这种Java类中的方法主要用于访问私有的字段,且方法都符合某种特殊的命名规则。

2)它是一种特殊的Java类,其中的方法名称等,都符合特殊的规则。只要一个类中含有get和set打头的方法,就可以将其当做JavaBean使用。

3)字段和属性:

字段就是我们定义的一些成员变量,如private String name;等

而属性是具有某些功能,Bean属性,是含有get或set方法的那些属性的字段,即这个变量的get属性,set属性等。

2、作用:

如果要在两个模板之间传递多个信息,可将这些信息封装到一个JavaBean中,这种JavaBean的实例对象通常称之为值对象(Value Object,简称VO),这些信息在类中用私有字段来储存,如果读取或设置这些字段的值,则需要通过一些相应的方法来访问。

3、命名方式:

JavaBean的属性是根据其中的setter和getter方法来确定的,而不是依据其中的变量,如方法名为setId,则中文意思是设置Id,getId也是如此;去掉前缀,剩余部分就是属性名称,如果剩余部分的第二个字母小写,则把剩余部分改为小写。如:getAge/setAge-->age;gettime-->time;setTime-->time;getCPU-->CPU。

4、总之、一个类被当做JavaBean使用时,JavaBaan的属性是根据方法名推断出来的,它根本看不到Java类内部的成员变量。

5、JavaBean的好处:

一个符合JavaBean特点的类当做普通类一样可以使用,但是把它当做JavaBean类用肯定有好处的:

1)在JavaEE开发中,经常要使用JavaBean。很多环境就要求按JavaBean的方式进行操作,别人都这么用,那么就必须要求这么做。

2)JDK中提供了对JavaBean进行操作的API,这套API称为内省,若要自己通过getX的方式来访问私有x,可用内省这套API,操作JavaBean要比使用普通的方式更方便。

示例:

package cn.itcast.text1;  
  
import java.beans.BeanInfo;  
import java.beans.IntrospectionException;  
import java.beans.Introspector;  
import java.beans.PropertyDescriptor;  
import java.lang.reflect.InvocationTargetException;  
import java.lang.reflect.Method;                                                                                                                                                                                                      
   
public class IntroSpectorTest {                                                                                                       /* 
  
      public static void main(String[] args) throws Exception { 
      
        // TODO Auto-generated method stub 
        ReflectPoint pt1 = new ReflectPoint(3,5); 
        String propertyName = "x"; 
        //"x"-->"X"-->"getX"-->MethodGetX--> 
        //内省的方式: 
        //属性描述符:PropertyDescriptor 
       //get属性信息 
        PropertyDescriptor pd = 
                new PropertyDescriptor(propertyName,pt1.getClass()); 
       Method methodGetX = pd.getReadMethod(); 
        Object retVal = methodGetX.invoke(pt1); 
        System.out.println(retVal); 
        //set属性信息 
        Object value = 7; 
        PropertyDescriptor pd2 = 
                new PropertyDescriptor(propertyName,pt1.getClass()); 
        Method methodSetX = pd2.getWriteMethod(); 
       methodSetX.invoke(pt1,value); 
         
        System.out.println(pt1.getX()); 
     } 
     */  
    //上面的get或set代码分别通过选中要重构的代码,通过右击选重构获得get和set方法:  
    public static void main(String[] args) throws Exception {  
        // TODO Auto-generated method stub  
        ReflectPoint pt1 = new ReflectPoint(3,5);  
        String propertyName = "x";  
        //一般方式:"x"-->"X"-->"getX"-->MethodGetX-->  
       //内省方式:  
        //通过get和set方法获取属性值  
        Object retVal = getProperty(pt1, propertyName);  
       System.out.println(retVal);  
          
        Object value = 7;  
        setProperty(pt1, propertyName, value);  
        System.out.println(pt1.getX());  
    }  
      
        //设置属性值的方法             //此处的类型为Object,通用,下同  
    private static void setProperty(Object rf, String propertyName,  
            Object value) throws IntrospectionException,  
            IllegalAccessException, InvocationTargetException {  
       //创建属性描述符对象,将属性名称和加载文件等信息写入其中  
        PropertyDescriptor pd =  
               new PropertyDescriptor(propertyName,rf.getClass());  
        //通过反射的方法类Method,获取属性所对应的set方法  
        Method methodSetX = pd.getWriteMethod();  
        methodSetX.invoke(rf, value);  
    }  
    //获取属性值的方法  
    private static Object getProperty(Object rf, String propertyName)  
            throws IntrospectionException, IllegalAccessException,  
           InvocationTargetException {  
        //创建属性描述符对象,获取属性所对应的名称和加载文件等信息  
        PropertyDescriptor pd =  
                new PropertyDescriptor(propertyName,rf.getClass());  
        //通过反射的方法类Method,获取属性所对应的get方法  
        Method methodGetX = pd.getReadMethod();  
       Object retVal = methodGetX.invoke(rf);  
        return retVal;  
    }  
}


 

三、对JavaBean的复杂内省操作:

1、在IntroSpector类中有getBeanInfo(Class cls)的方法。

2、获取Class对象的Bean信息,返回的是BeanInfo类型。

3、BeanInfo类中有getPropertyDescriptors()的方法,可获取所有的BeanInfo的属性信息,返回一个PropertyDescriptor[]。

4、在通过遍历的形式,找出与自己想要的那个属性信息。

 

四、BeanUtils工具包:

1、BeanUtils等工具包都是由阿帕奇提供的,为了便于开发。

2、BeanUtils可以将8种基本数据类型进行自动的转换,因此对于非基本数据类型,就需要注册转换器Converter,这就需要ConverUtils包,

2、好处:

1)提供的set或get方法中,传入的是字符串,返回的还是字符串,因为在浏览器中,用户输入到文本框的都是以字符串的形式发送至服务器上的,所以操作的都是字符串。也就是说这个工具包的内部有自动将整数转换为字符串的操作。

2)支持属性的级联操作,即支持属性链。如可以设置:人的脑袋上的眼镜的眼珠的颜色。这种级联属性的属性连如果自己用反射,那就很困难了,通过这个工具包就可以轻松调用。

3、可以和Map集合进行相互转换:可将属性信息通过键值对的形式作为Map集合存储(通过staticjava.util.Map describe(java.lang.Object bean)的方法),也可以将Map集合转换为JavaBean中的属性信息(通过static voidpopulate(java.lang.Object bean, java.util.Map properties)的方法)。

4、示例:

1)设置和获取属性值:

import java.lang.reflect.InvocationTargetException;  
import java.text.ParseException;  
import java.text.SimpleDateFormat;  
import java.util.Date;  
import java.util.Map;  
import java.util.TreeMap;  
   
import org.apache.commons.beanutils.BeanUtils;  
import org.apache.commons.beanutils.ConversionException;  
import org.apache.commons.beanutils.ConvertUtils;  
import org.apache.commons.beanutils.Converter;  
import org.apache.commons.beanutils.PropertyUtils;  
import org.apache.commons.beanutils.locale.converters.DateLocaleConverter;  
import org.junit.Test;  
   
public class BeanUtilDemo {  
  
    /** 
     * BeanUtils使用 
     */  
  
    @Test   
    public void test1() throws Exception{  
        //创建对象,设置属性值  
        Person p = new Person();  
        BeanUtils.setProperty(p, "name", "zzz");  
       String name = BeanUtils.getProperty(p, "name");  
        System.out.println(name);  
    }  
      
    @Test   
    public void test2() throws Exception{  
        //创建对象,传入属性值  
        Person p = new Person();  
        String name = "wangwu";  
        String age = "23";  
        String hight = "173.5";  
        //设置属性值  
        BeanUtils.setProperty(p, "name", name);  
        BeanUtils.setProperty(p, "age", age);  
        BeanUtils.setProperty(p, "hight", hight);  
        //获取属性值  
        System.out.println(BeanUtils.getProperty(p, "name"));  
        System.out.println(BeanUtils.getProperty(p, "age"));  
        System.out.println(BeanUtils.getProperty(p, "hight"));  
    }  

 

2)未注册的属性值的获取和设置

//获取未注册的属性,即非八种基本数据类型的引用类型  
//private Date birthday  
@Test   
public void test3() throws Exception{  
    Person p = new Person();  
    String name = "wangwu";  
    String age = "23";  
    String hight = "173.5";  
    String birthday = "1990-09-09";  
    ConvertUtils.register(new Converter() {  
        //注册器Converter接口中方法的重写  
        @Override  
        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(value.equals(""))  
                return null;  
           SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");  
            try{  
                return sdf.parse(str);  
            }catch(ParseException e){  
                throw new RuntimeException(e);//异常链不能掉,这里必须写上e  
            }  
        }},  
        Date.class);  
      
    //测试  
    BeanUtils.setProperty(p, "name", name);  
    BeanUtils.setProperty(p, "age", age);  
    BeanUtils.setProperty(p, "hight", hight);  
    BeanUtils.setProperty(p, "birthday", birthday);  
    System.out.println(BeanUtils.getProperty(p, "name"));  
    System.out.println(BeanUtils.getProperty(p, "age"));  
    System.out.println(BeanUtils.getProperty(p, "hight"));  
    System.out.println(BeanUtils.getProperty(p, "birthday"));  
 }
   
//使用已经写好的注册器DateLocaleConverter  
  @Test    
public void test4() throws Exception{  
    Person p = new Person();  
    String name = "wangwu";  
    String age = "23";  
    String hight = "173.5";  
    String birthday = "1990-09-09";  
    //将日期注册到BeanUtils上  
   ConvertUtils.register(new DateLocaleConverter(), Date.class);//提供的注册器不健壮,因为传入空字符串,就会报错  
                                                                //所以,当没有提供注册器或需要加强注册器的时候,可以自己写  
    //测试  
    BeanUtils.setProperty(p, "name", name);  
    BeanUtils.setProperty(p, "age", age);  
    BeanUtils.setProperty(p, "hight", hight);  
    BeanUtils.setProperty(p, "birthday", birthday);  
    System.out.println(BeanUtils.getProperty(p, "name"));  
    System.out.println(BeanUtils.getProperty(p, "age"));  
    System.out.println(BeanUtils.getProperty(p, "hight"));  
    System.out.println(BeanUtils.getProperty(p, "birthday"));  
    Date date = p.getBirthday();  
    System.out.println(date.toLocaleString());  
}  



3)Map集合在BeanUtils中的应用:

//Map集合在BeanUtils中的应用  
@Test  
public void test5() throws Exception {  
    /* 
     * JDK 7.0新特性:  
     * Map map = {"name" : "zs", "age" : 22, "hight" : 176.5}; 
    */  
    //将数据存入集合  
    Map map = new TreeMap();  
    map.put("name", "zhangsan");  
    map.put("age", "20");  
    map.put("hight", "172.5");  
    map.put("birthday", "1999-10-02");  
      
    //注册器  
    ConvertUtils.register(new DateLocaleConverter(), Date.class);  
    //获取属性  
    Person p = new Person();  
    BeanUtils.populate(p, map);  
       
    System.out.println(BeanUtils.getProperty(p, "name"));  
    System.out.println(BeanUtils.getProperty(p, "age"));  
    System.out.println(BeanUtils.getProperty(p, "hight"));  
    System.out.println(BeanUtils.getProperty(p, "birthday"));  
      
}
  
//属性链  
@Test  
public void test6() throws Exception {  
    Person p = new Person();  
    BeanUtils.setProperty(p, "birthday.time", "111212");  
    System.out.println(BeanUtils.getProperty(p, "birthday.time"));  
}  


 

5、补充:

1)BeanUtils是以字符串的形式进行操作的

2)PropertyUtils是以传入值本身的类型进行操作的。

//PropertyUtils可直接解析为指定类型,而BeanUtils只能指定字符串的类型  
    @Test  
    public void test7() throws Exception {  
        Person p = new Person();  
        System.out.println("-----BeanUtiles-------");  
        BeanUtils.setProperty(p, "age", "22");//字符串形式  
        System.out.println(BeanUtils.getProperty(p, "age"));  
        System.out.println(BeanUtils.getProperty(p, "age").getClass().getName());  
          
        System.out.println("-----PropertyUtiles-------");  
        PropertyUtils.setProperty(p, "age", 22);//Integer形式  
        System.out.println(PropertyUtils.getProperty(p, "age"));  
        System.out.println(PropertyUtils.getProperty(p, "age").getClass().getName());  
    }  


 

请解释以下代码<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>注册第一步</title> </head> <body> <% // 设置请求编码方式,防止中文乱码问题 request.setCharacterEncoding("UTF-8"); %> <!-- 查找JavaBean对象,使用请求参数为对象属性赋值 --> <jsp:useBean id="user" class="com.test.chapter07.javabean.UserBean" scope="session" /> <jsp:setProperty property="*" name="user" /> <h2 align="center">用户注册信息确认</h2> <form action="registerSuccess.jsp" method="post"> <table border="1" width="50%" align="center"> <tr> <td>用户名:</td> <td><jsp:getProperty property="username" name="user" /></td> </tr> <tr> <td>密 码:</td> <td><jsp:getProperty property="password" name="user" /></td> </tr> <tr> <td>性别:</td> <td><jsp:getProperty property="sex" name="user" /></td> </tr> <tr> <td>年龄:</td> <td><jsp:getProperty property="age" name="user" /></td> </tr> <tr> <td>提示信息:</td> <td><jsp:getProperty property="tooltip" name="user" /></td> </tr> <tr> <td>提示答案:</td> <td><jsp:getProperty property="answer" name="user" /></td> </tr> <tr> <td>邮箱:</td> <td><jsp:getProperty property="email" name="user" /></td> </tr> <tr> <td>愿意接受信息:</td> <td><jsp:getProperty property="messageChoose" name="user" /></td> </tr> <tr> <td colspan="2" align="center"><input type="submit" value="确认提交"></td> </tr> </table> </form> </body> </html>
05-25
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值