java 内省!


那么何为内省呢?

内省:以反射的方式去访问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层的表单数据,而不用一个一个的接收。

原文地址:https://www.cnblogs.com/yangzhi/p/3576592.html