那么何为内省呢?
内省:以反射的方式去访问javabean对象。
Jdk中的api : PropertyDescriptor类操作Bean的属性。
以下为一个javabean的User对象。
public class User { private String name; private int age; public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override //为了方便打印,添加一个toString方法 public String toString() { return "User [age=" + age + ", name=" + name + "]"; } }
现在来看一个传统的方式来访问。
public class Demo1 { public static void main(String[] args) { User user=new User(); user.setName("zhangsan"); user.setAge(19); System.out.println(user); } }
内省的方式来访问。
public class Demo1 { public static void main(String[] args) throws Exception { User user=new User(); //创建属性描述器 PropertyDescriptor descriptor=new PropertyDescriptor("name",User.class); //获得写方法 Method writeMethod=descriptor.getWriteMethod(); //调用写方法 writeMethod.invoke(user, "lisi"); System.out.println(user); } }
那么现在问题来了!如果你有多个javabean需要赋值。
你是否会选择去一个一个的赋值呢!
如果使用内省的话就可以实现通用。
看如下代码:
import java.beans.IntrospectionException; import java.beans.PropertyDescriptor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import cn.itcast.day08.domain.User; public class Demo2 { /** * @param args * @throws IntrospectionException * @throws InvocationTargetException * @throws IllegalAccessException * @throws IllegalArgumentException */ public static void main(String[] args) throws Exception { // 内省 User user = new User(); setProperty(user, "name", "wangwu"); setProperty(user, "age", 11); System.out.println(user); } // 实现一个通用的方法 为任意的一个javabean的任意属性赋任意值 public static void setProperty(Object bean, String fieldName, Object value) throws Exception { // 创建属性描述器 PropertyDescriptor descriptor = new PropertyDescriptor(fieldName, bean.getClass()); // 获得 写方法 Method writeMethod = descriptor.getWriteMethod(); // 调用 写方法 writeMethod.invoke(bean, value); } }
现在你应该知道内省是用来干什么的了吧!
看下面一个例子。
import java.lang.reflect.InvocationTargetException; import java.sql.Date; import java.util.Enumeration; import javax.servlet.http.HttpServletRequest; import org.apache.commons.beanutils.BeanUtils; import org.apache.commons.beanutils.ConvertUtils; import org.apache.commons.beanutils.converters.DateConverter; public class WebUtils { private WebUtils(){} //定义一个通用工具方法,将请求参数封装到javabean public static Object request2bean(HttpServletRequest request,Class beanClass){ try{ Object bean=beanClass.newInstance(); // 获得所有请求参数名 Enumeration names = request.getParameterNames(); //注册日期转换器 DateConverter converter=new DateConverter(); converter.setPattern("yyyy-MM-dd"); ConvertUtils.register(converter, Date.class); //遍历 while(names.hasMoreElements()){ // 获得一个参数名 String name = (String)names.nextElement(); // 获得参数名对应的参数值 String value = request.getParameter(name); //将参数名作为属性名 将参数值作为属性值,通过beanutils工具实现属性的封装 BeanUtils.setProperty(bean, name, value); } return bean; }catch (Exception e) { throw new RuntimeException(e); }//异常要抓下来,不能抛给servlet,把编译时异常包装称运行时异常 } }
这样做就可以去实现,用一个工具类去接受任何view层的表单数据,而不用一个一个的接收。