项长老

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

1、内省技术Introspector

基于反射的技术,便于操作JavaBean API

1、通过Introspector获得BeanInfo信息

getBeanInfo(...);

2、通过BeanInfo获得方法描述器、属性描述器

getMethodDescriptors()

getPropertyDescriptors()

3. 遍历每一个属性

for (PropertyDescriptor propertyDescriptor : descriptors) {
    // 用属性 去map寻找对应key
    String name = propertyDescriptor.getName();
    if (map.containsKey(name)) { // 属性在map中存在对应key
        String value = map.get(name);
        // 通过属性描述器 ,获得写入该属性方法
        Method setMethod = propertyDescriptor.getWriteMethod();
        // 利用反射设置value ---- value类型必须和属性类型匹配
        setMethod.invoke(obj, value);
    }
}

注:JavaBean属性不是用成员变量计算的,而是通过getter和setter方法计算。由于每一个对象继承Object,继承了getClass()方法,因此也算一个。

完整代码:

package cn.itcast.introspector;

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

import org.junit.Test;

import cn.itcast.javabean.Person;

// 使用Junit
public class IntrospectorTest {
    @Test
    public void demo2() throws Exception {
        // 将map的值保存 相应对象属性中
        Map<String, String> map = new HashMap<String, String>();
        map.put("name", "mary");
        map.put("city", "beijing");
        map.put("hobby", "music");
        // map.put("age", "20"); age的值 与 person中age属性类型不匹配,无法封装

        Person person = new Person();

        saveMapValue2Object(map, person);
        System.out.println(person.getName());
        System.out.println(person.getCity());
        System.out.println(person.getHobby());
        System.out.println(person.getAge());
    }

    // 将map中key 与 object 中属性进行匹配,将map对应value保存 obj属性值
    private void saveMapValue2Object(Map<String, String> map, Object obj)
            throws Exception {
        // 1.内省获得javabean信息
        BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass());
        // 2、通过beanInfo获得所有属性
        PropertyDescriptor[] descriptors = beanInfo.getPropertyDescriptors();
        // 3. 遍历每一个属性
        for (PropertyDescriptor propertyDescriptor : descriptors) {
            // 用属性 去map寻找对应key
            String name = propertyDescriptor.getName();
            if (map.containsKey(name)) { // 属性在map中存在对应key
                String value = map.get(name);
                // 通过属性描述器 ,获得写入该属性方法
                Method setMethod = propertyDescriptor.getWriteMethod();
                // 利用反射设置value ---- value类型必须和属性类型匹配
                setMethod.invoke(obj, value);
            }
        }
    }

    @Test
    public void demo1() throws Exception {
        // 通过 Introspector获得 BeanInfo信息
        BeanInfo beanInfo = Introspector.getBeanInfo(Person.class);
        // 获得所有javabean属性描述器 , 每一个属性描述代表javabean一个属性
        PropertyDescriptor[] propertyDescriptors = beanInfo
                .getPropertyDescriptors();
        // 计算javabean属性
        System.out.println(propertyDescriptors.length);
        for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
            System.out.println(propertyDescriptor.getName());
        }
    }
}
View Code

2、BeanUtil内省工具包

在Model1中,完成form参数 ---- JavaBean自动封装
<jsp:setProperty property="*" name="calculator" />

在Model2中
使用内省技术完成form数据 封装 javabean对象


BeanUtils 工具包

1、在调用populate方法前,注册转换器 

ConvertUtils.register(Converter converter, Class clazz)

2、编写BeanUtils的封装程序 

BeanUtils.populate(person, request.getParameterMap());

完整代码:

package cn.itcast.servlet;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.beanutils.Converter;

import cn.itcast.javabean.Person;

/**
 * 获得form数据 ,将form数据封装 Person对象中
 * 
 * @author seawind
 * 
 */
public class Demo4Servlet extends HttpServlet {

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        request.setCharacterEncoding("utf-8");// 处理乱码

        // 将form参数 自动封装 Person对象
        Person person = new Person();

        // 将String类型 转换 java.util.Date类型 --- 自定义转换器
        // 在封装数据之前 ,注册转换器
        ConvertUtils.register(new MyDateConverter(), Date.class);

        try {
            BeanUtils.populate(person, request.getParameterMap());
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }

        System.out.println(person.getName());
        System.out.println(person.getCity());
        System.out.println(person.getHobby());
        System.out.println(person.getAge());
        System.out.println(person.getBirthday());
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        doGet(request, response);
    }

}

// 自定义转换器 实现 Converter接口
class MyDateConverter implements Converter {

    @Override
    // 需要 将value数据转换 c的类型
    // value 是 String类型,将String转换Date类型
    public Object convert(Class c, Object value) {
        String s = (String) value; // 代表用户输入生日
        DateFormat dateFormat = new SimpleDateFormat("yyyy年MM月dd日");
        try {
            Object result = dateFormat.parse(s); // 将String解析为 Date
            return result;
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

}
View Code

 

posted on 2016-02-22 13:30  项长老  阅读(377)  评论(0编辑  收藏  举报