【JavaEE】Java内省Introspector、PropertyDescriptor与JavaBean

1.Java内省概念

Sun公司开发了一套API,专门用于操作Java对象的属性。【Introspector】
在开发框架时,需要使用Java对象的属性来封装程序的数据,使用反射技术完成此类操作过于麻烦,我们使用内省。
内省(Introspector) 是Java 语言对 JavaBean 类属性、事件的一种缺省处理方法。

JavaBean是一种特殊的类,主要用于传递数据信息,这种类中的方法主要用于访问私有的字段,且方法名符合某种命名规则。
如果在两个模块之间传递信息,可以将信息封装进JavaBean中,这种对象称为”值对象”(Value Object),或”VO”。
方法比较少。这些信息储存在类的私有变量中,通过set()、get()获得。
在Student中有属性name, age, birthday。我们可以通过getName, setName来访问name属性,这就是默认的规则。
Java JDK中提供了一套 API 用来访问某个属性的 getter/setter 方法,这就是内省。
PropertyDescriptor类:
PropertyDescriptor类表示JavaBean类通过存储器导出一个属性。主要方法:
1. getReadMethod(),获得用于读取属性值的方法;
2. getWriteMethod(),获得用于写入属性值的方法;
3. setReadMethod(Method readMethod),设置用于读取属性值的方法;
4. setWriteMethod(Method writeMethod),设置用于写入属性值的方法。

通过PropertyDescriptor与Introspector的比较可以看出,都是需要获得PropertyDescriptor,只是方式不一样:
PropertyDescriptor通过创建对象直接获得,Introspector需要遍历,
所以使用PropertyDescriptor类更加方便。

Introspector类,将JavaBean中的属性封装起来进行操作。
1.在程序中把一个类当做JavaBean来看,调用Introspector.getBeanInfo()方法,
得到的BeanInfo对象封装了这个类的属性信息。
2.通过BeanInfo来获取属性的属性描述器PropertyDescriptor 。

3.通过PropertyDescriptor获取某个属性对应的getter/setter方法,
然后通过反射机制来调用这些方法。

BeanInfo bi = Introspector.getBeanInfo(Student.class); 
PropertyDescriptor [] pds = bi.getPropertyDescriptors();

BeanUtils工具包
内省操作非常的繁琐,所以所以Apache开发了一套简单、易用的API来操作Bean的属性,BeanUtils工具包。
beanutils内省框架(依赖commons-logging):apache
准备包:commons-beanutils.jar, commons-logging.jar
BeanUtils工具包:
下载:commons-beanutils.jar http://commons.apache.org/beanutils/ 
commons-logging.jar http://commons.apache.org/logging/

1.获得属性的值,例如,BeanUtils.getProperty(stu,”stuName”),返回字符串
2.设置属性的值,例如,BeanUtils.setProperty(stu,”age”,38),参数是字符串或基本类型自动包装。
设置属性的值是字符串,获得的值也是字符串,不是基本类型。   
3.BeanUtils的特点:
①对基本数据类型的属性的操作:String<—–>基本类型 在WEB开发、使用中,录入和显示时,值会被转换成字符串,但底层运算用的是基本类型,这些类型转到动作由BeanUtils自动完成。
②非基本类型的属性的操作:String<—-> 其他类型
例如:

    public void test5 () throws Exception{
        Student s = new Student ();
        //给BeanUtils注册转换器,
        ConvertUtils.register(new Converter (){
            //type是目标类型, value是当前传入的值
        public Object convert(Class type,  Object value) {
        DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
                  //字符串转换为Date
                  String v= (String) value;
                  try{
                    Date d = df.parse(v);
                    return d;
                  }catch (ParseException e){
                    throw new RuntimeException (e);
                  }
                 }
                }, Date.class);
        BeanUtils.setProperty(s, "birthday", "1990-08-25");
        System.out.println(s.getBirthday());        
    }
    /**
     * 给BeanUtils注册转换器,参数:converter 要注册的转换器
     * clazz 此转换器执行的转换的目标类
     */ 
public static void register(Converter converter, Class clazz);  
public interface Converter {
      /*
       *将特定输入转换成特定的输出类型
       *参数:type   目标转换类型,value  待转换的输入值  
       *返回值: 转换的结果
       */  
    public Object convert(Class type, Object value);
}   

2. Java内省实例

JavaBean

package cn.edu;
import java.util.Date;
public class Student {
    private String stuName; 
    private int age;
    private Date birthday;
    public String getStuName() {
        return stuName;
    }
    public void setStuName(String stuName) {
        this.stuName = stuName;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public Date getBirthday() {
        return birthday;
    }
    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }
    @Override
    public String toString() {
        return "Student [stuName=" + stuName + ", age=" + age + ", birthday="
                + birthday + "]";
    }
}
package cn.edu;
import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.beanutils.Converter;
import org.apache.commons.beanutils.locale.converters.DateLocaleConverter;

public class BeanInfoUtil {
    public static void main(String[] args) throws  Exception {
        Student stu = new Student();
        BeanInfoUtil.setProperty(stu, "stuName","Tom");
        BeanInfoUtil.getProperty(stu, "stuName");
        setPropertyByIntrospector(stu, "stuName","Ben");
        getPropertyByIntrospector(stu, "stuName");
        /*
         * 3.BeanUtils工具包操作JavaBean
         * */
        BeanUtils.setProperty(stu, "stuName", "Green");
        BeanUtils.setProperty(stu, "age", 18);
        System.out.println("get stuName:"+BeanUtils.getProperty(stu, "stuName"));
        System.out.println("get age:"+BeanUtils.getProperty(stu, "age"));    

        convertUtilsGetBirthday(stu, "1990-08-25");
        convertUtilsGetBirthday2(stu, "1993-08-25");        
    }   
    /** 
     *  1.直接通过 PropertyDescriptor类的操作Bean属性
     * */   
    public static void setProperty(Student stu, String stuName, String value) throws Exception, IllegalArgumentException, InvocationTargetException{
         //1.获取stuName属性
         PropertyDescriptor propDesc=new PropertyDescriptor(stuName,Student.class);
         //2.得到setStuName()方法
         Method methodSetStuName=propDesc.getWriteMethod();
         //3.调用setStuName()方法
         methodSetStuName.invoke(stu, value);  
         System.out.println("set name:"+stu.getStuName());              
    }
    public static void getProperty(Student stu, String stuName) throws Exception{   
        PropertyDescriptor proDescriptor =new PropertyDescriptor(stuName,Student.class);
        Method methodGetStuName=proDescriptor.getReadMethod();
        Object objStuName=methodGetStuName.invoke(stu);
        System.out.println("get name:"+objStuName.toString());              
    }   
    /**
     *  2.通过Introspector类获取BeanInfo对象,再通过BeanInfo获取PropertyDescriptor,操作Bean属性 
     * */   
     public static void setPropertyByIntrospector(Student stu,String stuName, String value)throws Exception{
            //1.获取BeanInfo对象
            BeanInfo beanInfo=Introspector.getBeanInfo(Student.class);
            //2.通过BeanInfo对象获取PropertyDescriptor
            PropertyDescriptor[] proDescrtptors=beanInfo.getPropertyDescriptors();
            //3.遍历
            if(proDescrtptors !=null && proDescrtptors.length > 0){
                for(PropertyDescriptor propDesc : proDescrtptors){
                    if(propDesc.getName().equals(stuName)){              
                        Method methodSetUserName=propDesc.getWriteMethod();
                        methodSetUserName.invoke(stu, value);
                        System.out.println("set stuName:"+stu.getStuName());
                        break;
                    }
                }
            }
        }       
        public static void getPropertyByIntrospector(Student stu,String stuName)throws Exception{       
            BeanInfo beanInfo=Introspector.getBeanInfo(Student.class);
            PropertyDescriptor[] proDescrtptors=beanInfo.getPropertyDescriptors();        
            if(proDescrtptors !=null && proDescrtptors.length > 0){
                for(PropertyDescriptor propDesc : proDescrtptors){              
                    if(propDesc.getName().equals(stuName)){                 
                        Method methodStuUserName=propDesc.getReadMethod();
                        Object objStuName=methodStuUserName.invoke(stu);
                        System.out.println("get StuName:"+objStuName.toString());
                        break;
                    }
                }
            }
        }    
        /**
         *   给BeanUtils注册时间日期转换器 
         * */    
        public static void convertUtilsGetBirthday(Student stu, String date) throws Exception{          
            //给BeanUtils注册转换器, type是目标类型, value是当前传入的值
            ConvertUtils.register(new Converter (){
              public Object convert(Class type, Object value) {
                  DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
                  //字符串转换为Date
                  String v= (String) value;
                  try{
                    Date d = df.parse(v);
                    return d;
                  }catch (ParseException e){
                    throw new RuntimeException (e);
                  }
                 }
                }, Date.class);
            BeanUtils.setProperty(stu, "birthday", date);
            System.out.println(stu.getBirthday());          
        }   
        /**
         *   给BeanUtils注册时间日期转换器 
         * */
        public static void convertUtilsGetBirthday2(Student stu, String date) throws Exception{

            ConvertUtils.register(new DateLocaleConverter(), Date.class);   
            BeanUtils.setProperty(stu, "birthday", date);
            System.out.println(stu.getBirthday());              
        }       

}
/*
    set name:Tom
    get name:Tom
    set stuName:Ben
    get StuName:Ben
    get stuName:Green
    get age:18
    Sat Aug 25 00:00:00 CDT 1990
    Wed Aug 25 00:00:00 CST 1993
 * */

3.Java封装客户端请求参数至JavaBean

JavaBean
public class User {
    private String username;
    private String password[];
    private String gender;
    public String getUsername() {//读属性,属性名称username
        return username;
    }
    public void setUsername(String username) {//写属性,属性名username
        this.username = username;
    }

    public String[] getPassword() {
        return password;
    }
    public void setPassword(String[] password) {
        this.password = password;
    }
    public String getGender() {
        return gender;
    }
    public void setGender(String gender) {
        this.gender = gender;
    }
    @Override
    public String toString() {
        return "User [username=" + username + ", password="
                + Arrays.toString(password) + ", gender=" + gender + "]";
    }

}

封装请求参数的几种方案:

    /*1.使用Java内省,将请求参数的值封装到JavaBean中。
      约定优于编码:表单的输入域的name取值和JavaBean中的属性(getter和setter方法)保持一致
    */
    private void test1(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {  
        Enumeration<String> e = request.getParameterNames();//参数名
        User user = new User();
        while(e.hasMoreElements()){
            String paramName = e.nextElement();//即是JavaBean中的属性名称
            String paramValue = request.getParameter(paramName);
            //JavaBean的内省
            try {
                PropertyDescriptor pd = new PropertyDescriptor(paramName, User.class);
                Method m = pd.getWriteMethod();//setter方法
                m.invoke(user, paramValue);
            } catch (Exception e1) {
                e1.printStackTrace();
            }
        }
    }       
    /*2.getParameterMap获取参数*/
    private void test6(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        //key:请求参数名 value:请求参数值数组
        Map<String,String[]> map = request.getParameterMap();
        for(Map.Entry<String, String[]> me:map.entrySet()){
            System.out.println(me.getKey()+"="+Arrays.asList(me.getValue()));
        }
    }   

    /*
     3.getParameterMap获取参数结合Java 内省,封装到JavaBean中
    */
    private void test2(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        //key:请求参数名 value:请求参数值数组
        Map<String,String[]> map = request.getParameterMap();
        User user = new User();
        for(Map.Entry<String, String[]> me:map.entrySet()){
            String paramName = me.getKey();//参数名称
            String paramValues[] = me.getValue();//参数值
            try {
                PropertyDescriptor pd = new PropertyDescriptor(paramName, User.class);
                Method m = pd.getWriteMethod();//setter方法
                if(paramValues.length > 1){
                    m.invoke(user, (Object)paramValues);
                }else{
                    m.invoke(user, paramValues);
                }
            } catch (Exception e1) {
                e1.printStackTrace();
            }
        }
    }   
    /*3.借助第三方工具包:借助BeanUtil框架*/
    private void test8(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        User user = new User();
        try {
            BeanUtils.populate(user, request.getParameterMap());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值