NOVOTS KMS 词汇表 Glossary    联系我们 Contact Us
查询 Search  
   
按类别浏览 Browse by Category
NOVOTS KMS .: 工作心得 .: Java内省的实践

Java内省的实践

在工作中我们经常会在mvc框架中遇见只有一个request传递参数给我们,然后我们就会调用request自带的方法getParameter去获取一个String类型的参数,然后根据bean的成员变量类型将String转换成对应数据类型,再调用setXxx方法将参数导入bean里面,一般看见的代码表现形式大都是:

================================================================

String fieldname = (String) request.getParameter("fieldname");

String rate = (String) request.getParameter("rate");

String fixname = (String) request.getParameter("fixname");

String fixNameValue = (String) request.getParameter("fixNameValue");

String cityNo = (String)request.getParameter("cityNo");

String baseName = (String)request.getParameter("baseName");

String down = (String)request.getParameter("down");

================================================================

可以看见这段代码阅读体验极差,不利于开发人员快速上手,需要花大量时间去熟悉类似代码,造成了时间的浪费 在这里我们可以使用java自带的内省API去实现这种繁琐的数据处理方式,如下:

================================================================

User class1 = RequestUtils.getClass(request, User.class);

public static <T> T getClass(HttpServletRequest request,Class<T> clazz) throws ClassNotFoundException, InstantiationException, IllegalAccessException, IntrospectionException, IllegalArgumentException, InvocationTargetException, NoSuchFieldException, SecurityException, ParseException {

 if(request==null || clazz==null ){

 return null;

 }

     T t = clazz.newInstance();

     Class<?> cl = Class.forName(clazz.getName());

         BeanInfo beaninfo = Introspector.getBeanInfo(cl, Object.class);

         PropertyDescriptor[] pro = beaninfo.getPropertyDescriptors();

         for (PropertyDescriptor propertyDescriptor : pro) {

              Method writeme = propertyDescriptor.getWriteMethod();

             if(!StringUtils.isEmpty(request.getParameter(propertyDescriptor.getName()))  ){

              String fieldType = cl.getDeclaredField(propertyDescriptor.getName()).getType().getName();

               if("java.lang.Integer".equals(fieldType)) {

               writeme.invoke(t,Integer.valueOf(request.getParameter(propertyDescriptor.getName()))  );

                     }else if("java.lang.String".equals(fieldType)) {

               writeme.invoke(t,request.getParameter(propertyDescriptor.getName()));

                     }else if("java.lang.Long".equals(fieldType)) {

                      String s = request.getParameter(propertyDescriptor.getName());

                      writeme.invoke(t,Long.valueOf(s));

                     }else if("java.lang.Double".equals(fieldType)) {

                      String s = request.getParameter(propertyDescriptor.getName());

                      writeme.invoke(t,Double.valueOf(s));

                     }else if("java.util.Date".equals(fieldType)) {

                      String s = request.getParameter(propertyDescriptor.getName());

                      SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

                      writeme.invoke(t,sdf.parse(s));

                     }else {

//                      不支持复杂类型

                     }

             }

            }

    return t;

 }

================================================================

上面我们将request和User的class对象传入getClass方法中,进入getClass方法,先进行参数的判断,然后进入代码逻辑; 根据class对象我们调用newInstance方法实现实例化,更好地利用泛型实现强转操作,尽量避免程序员手动去强转; 之后通过Class.forName方法去获取一个class对象 这时候我们就可以调用java提供的内省API(beaninfo.getPropertyDescriptors)取cl(bean)所有的变量了,包括private修饰的成员变量,这时候成员变量被包装到PropertyDescriptor对象里面,通过for循环我们从PropertyDescriptor中获取到Method对象根据成员变量名去request里面获取到String类型的参数,之后调用invoke方法等同调用setXxx方法传入参数,在这里根据成员变量类型做出判断,会对数据进行转换存入t对象中最后将t返回,我们就完成了一个反射的流程。 反射的功劳,如果没有反射很难想象如果完成同样的功能会有多么难!但是反射也有缺点,比如性能比较低、安全性比较复杂等,这里就不在讨论这些东西,后面有时间我会详细讲下new的各种姿势以及优缺点


这篇文章对你多有用?

用户评语

添加评语
当前还没有评语.


.: .: .: .: .:
[ 登陆 ]
北京护航科技有限公司 2006

Novots Technologies Limited