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);}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 * */封装请求参数的几种方案:
/*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(); } }新闻热点
疑难解答