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()); } } }
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; } }