`
anreddy
  • 浏览: 99867 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

运用反射机制实现form之间属性的拷贝

阅读更多

如果各位兄弟现在在struts做事情的时候,大家经常会遇到formBean对拷的情况。简单的就是说,如果两个不同的formBean有相同的属性,将其中一个formBean的相同属性的值赋值到另一个formBean相同的属性上.(当然如果这两个formbean相同更好了)[:E]
    
    
如果我这样说大家还不明白的话,org.apache.commons.beanutils下的BeanUtils.copyProperties(java.lang.Object dest, java.lang.Object orig) 大家一定用过了,这个方法的最不好的地方就是第一个formBean完全覆盖第二个formbean属性的值,比如bean1的一个属性是null的话,使用这个方法的话,自然这个null就把bean2的属性值给覆盖了,有时候这样的结果我们不能接受[cry],我们需要的是bean1就覆盖bean2属性是空的情况,即bean2的属性有值的时候bean1不覆盖bean2的属性,至于这样的好处?我自己也讲不太清楚,我想用hibenate的人会体会的更深一点[:E]


  
本人就写了一个类似的类,不过由于时间和能力的有限,目前这个类只能复制formBean
,也就说这个bean的所有属性必须是String类型,而且不能使String[],虽然功能有限,但是这个思想我觉得很好,大家不妨在我的基础上写出比apache更好的copyProperties()方法。我好长时间没有来了,最近一直加班,所以写完这个帖子可能不能有多少时间维护,希望大家原谅

  
以下是源码,本来还有试验的formBean,但是这样就会让这个帖子太长,本人的注释写的很详细,所以也不多罗嗦了,但是还是简单的说一下实现的思想:首先遍历formBean的属性,将这些属性放到一个容器里,然后遍历属性得到get和set方法,然后将属性的名称和这两个方法做一个影射.也就是说同过getMethodsMap这个方法,可以得到属性和get与set方法的影射集合(这里除去不存在get或者set方法的属性),然后遍历第2个formBean的影射集合与第一个formBean的影射集比较和赋值如果大家想扩展的话,还需要判断属性的类型,我基本有思路,但是我现在很忙,没有时间,希望大家能帮我完成这个心愿

package com.xjw.utils;
import java.lang.reflect.*;
import java.util.*;

/**
  本类就是用于formBean之间属性的对拷,主要的方法是copyFormBeanPropertys
*/
public class BeanUtil {
  /**
    得到fields的容器
    @param  Class objClass 当前对象的Class对象
    @return  ArrayList承装对象属性的容器
   */
  public static ArrayList getFildsArray(Class objClass) {
    ArrayList al = null;
    try {
      //得到所有的属性
      Field[] fields = objClass.getDeclaredFields();
      al = new ArrayList();
      for (int i = 0; i < fields.length; i++) {
        al.add(fields[i].getName());
      }
    } catch (Exception e) {
      al = null;
      System.out.println(e);
    }
    return al;
  }


  /**
     得到bean属性与方法的映射关系
     @param  Class objClass 当前对象的Class对象
     @return  HashMap承装属性与方法的映射关系的容器
   */
  public static HashMap getMethodsMap(Class objClass) {
    HashMap hm = null;
    try {
      //得到此对象所有的方法
      Method[] methods = objClass.getDeclaredMethods();
      hm = new HashMap(); //承装属性与方法的映射关系的容器
      String fieldName = ""; //属性名称首字母为大写
      String methodName = ""; //方法名称
      ArrayList al = getFildsArray(objClass); //得到本类的所有属性
      boolean isEndWithGet = false; //是否是get开头的
      boolean isFind = false; //判断方法名称是否包含此属性名称
      boolean isEndWithSet = false; //是否是set开头的
      if (al != null) { //属性不能不存在
        int alSize = al.size(); //多少个属性
        for (int i = 0; i < alSize; i++) {
          //得到首字母为大写的属性名称
          fieldName = upFirstChar((String) al.get(i));
          //对应属性名称的get和set方法
          Method[] myMothodArrag = new Method[2];
          //遍历所有方法找到和属性名称相同的set和get方法
          for (int j = 0; j < methods.length; j++) {
            methodName = (methods[j].getName());
            isEndWithGet = methodName.startsWith("get");
            isFind = methodName.endsWith(fieldName);
            isEndWithSet = methodName.startsWith("set");
            if (isFind & isEndWithGet) {
              myMothodArrag[0] = methods[j]; //如果是get方法,则放到自定义容器的第一位
            } else if (isFind & isEndWithSet) {
              myMothodArrag[1] = methods[j]; //如果是set方法,则放到自定义容器的第2位
            }
          }
          //遍历后只有属性,缺少方法的情况,不放到影射容器里
          if (myMothodArrag[0] != null & myMothodArrag[0] != null) {
            hm.put(fieldName, myMothodArrag);
          }

        }
      }

    } catch (Exception e) {
      System.out.println(e);
    }
    return hm;
  }


  /**
    change the fist letter to UpperCase
   */
  public static String upFirstChar(String str) {
    String first = (str.substring(0, 1)).toUpperCase();
    String other = str.substring(1);
    return first + other;
  }


  /**only copy the formbean property,that means bean's properties are String type
      将第一formbean的属性复制到第二个formbean属性(相同名称的属性)
     @param  Object form1 被复制的formbean
     @param  Object form2 要复制的formbean
     @param  boolean isCover  
     如果第一个formbean属性是null的话,你不需要用这个null来覆盖要复制的formbean,则此参数为false;
     @return  HashMap承装属性与方法的映射关系的容器
   */
  public static void copyFormBeanPropertys(Object form1, Object form2,
                                           boolean isCover) {
    try {
      Class form1Class = form1.getClass();
      Class form2Class = form2.getClass();
      HashMap hm1 = getMethodsMap(form1Class); //第一个bean属性与方法的映射关系的容器
      HashMap hm2 = getMethodsMap(form2Class); //第二个bean属性与方法的映射关系的容器
      Method[] myMothodArrag1 = new Method[2]; //form1承装get和set影射关系容器
      Method[] myMothodArrag2 = new Method[2]; //form2承装get和set影射关系容器
      Iterator it_2 = hm2.keySet().iterator(); //第二个容器的遍历器(就是要复制的formbean)
      String fieldsNameForm2 = null; //第二个form的属性名称
      String[] str = null; //参数列表
      Method getMethod = null; //对应get方法
      Method setMethod = null; //对应set方法
      Object obj = null; //反射方法的返回值
      boolean isContainsKey = false; //判断是存在
      if (hm1 == null | hm2 == null) {
        throw new Exception("遍历form方法和属性的影射关系出错!!!");
      } while (it_2.hasNext()) { //遍历第二个formbean属性
        fieldsNameForm2 = (String) it_2.next();
        //判断第一个formbean是否包含这个属性
        isContainsKey = hm1.containsKey(fieldsNameForm2);
        //得到承装第二个get和set影射关系容器
        myMothodArrag2 = (Method[]) hm2.get(fieldsNameForm2);
        if (isContainsKey) { //第一个formbean如果包含这个属性
          myMothodArrag1 = (Method[]) hm1.get(fieldsNameForm2); //得到承装get和set影射关系容器
          getMethod = myMothodArrag1[0]; //自定义容器的第一个是get方法
          obj = getMethod.invoke(form1, null); //动态调用form1的get方法,返回属性的值
          System.out.println(obj + "    ________________________");
          str = new String[1]; //向下转型(因为formbean所有的属性都是String)
          str[0] = (String) obj;
          if (isCover) {
            setMethod = myMothodArrag2[1]; //第二个bean的set方法
            setMethod.invoke(form2, str); //动态调用第二个formbean的set方法
          } else {
            if (obj != null) {
              setMethod = myMothodArrag2[1]; //第二个bean的set方法
              System.out.println(setMethod.getName());
              setMethod.invoke(form2, str); //动态调用第二个formbean的set方法
            }
          }
        }
      }

    } catch (Exception e) {
      System.out.println(e);
    }
  }

  public static void main(String[] args) {
    BeansTest form1 = new BeansTest();
    Bean2 form2 = new Bean2();
    copyFormBeanPropertys(form1, form2, false);

  }
}
http://www.javaresearch.org/article/23467.htm
分享到:
评论

相关推荐

    利用反射机制动态获取对象属性名称及数据类型

    我们创建一个名为`ReflectorClass`的辅助类,其中包含一个静态方法`getPropertyName`,这个方法接受一个对象实例作为参数,通过反射获取该对象的所有属性名及对应的类型,并返回一个字符串,每个属性名与类型之间用...

    【ASP.NET编程知识】ASP.NET中实现Form表单字段值自动填充到操作模型中.docx

    下面我们将探讨如何使用反射机制来实现Form表单字段值自动填充到操作模型中。 Form表单字段值自动填充的需求 在WebForm应用程序中,我们经常需要将Form表单字段值自动填充到操作模型中,以便于后续的业务逻辑处理...

    在C#中如何实现Form与Form之间的通信

    在C#中如何实现Form与Form之间的通信

    C#使用委托(delegate)实现在两个form之间传递数据的方法

    本文实例讲述了C#使用委托(delegate)实现在两个form之间传递数据的方法。分享给大家供大家参考。具体分析如下: 关于Delegate【代理、委托】是C#中一个非常重要的概念,向前可以推演到C++的指针,向后可以延续到匿名...

    winform利用窗体属性实现窗体之间传值.rar

    标题“winform利用窗体属性实现窗体之间传值”所指的知识点,主要是关于如何通过设置和访问窗体的公共属性来实现在不同窗体间的数据传递。这种技术尤其适用于简单的值传递场景,下面我们将详细探讨这一方法。 首先...

    winform 深拷贝的实现源码

    在Windows Forms(WinForm)应用程序开发中,对象的拷贝是一个常见的需求,特别是在...通过学习和分析这段代码,开发者可以掌握如何在自己的WinForm项目中实现对象的深拷贝,确保对象之间的数据独立性和程序的稳定性。

    java反射-在form提交的一些应用

    在“java反射-在form提交的一些应用”这个主题中,我们将探讨如何利用反射机制来处理HTML表单提交的数据,以及相关的源码分析和工具使用。 在Web应用程序中,表单提交通常是用户与服务器交互的重要方式。当用户填写...

    利用JAVA的反射机制动态加载struts中的form

    利用java的反射机制动态加载form,以使得这部分代码能够被重用,是很好的一个重用代码机制的体现

    js实现form表单自动回显功能

    js实现form表单自动回显功能

    c#中Form常用属性

    C# 中 Form 的常用属性 Form 是 C# 中的一个重要组件,它提供了大量的属性和方法来控制窗体的行为和外观。下面我们将详细介绍 Form 的常用属性。 1. Name 属性:用来获得或设置窗体的名称。这是一个字符串属性,...

    Form1调用Form2 ,From2回传值或调用Form1内的方法。

    在C#编程中,我们经常需要在不同的窗体(Form)之间传递数据或者触发特定的操作。这在开发GUI应用程序时尤为常见,例如一个窗体(Form1)打开另一个窗体(Form2),然后Form2执行某些操作并返回结果给Form1,或者...

    C# form1 ,form2 互相传值

    总之,通过创建Form实例、使用公共属性或方法传递值,以及利用事件机制,可以在C#的两个独立窗体之间进行有效的数据交换。这种通信方式在多窗体应用中非常实用,可以确保数据的准确性和实时性。

    两个Form之间传值Demo

    本文将深入探讨"两个Form之间传值Demo"这一主题,讲解如何在C#中实现在不同窗体之间传递数据。 首先,让我们理解窗体间的值传递主要有以下几种方法: 1. **构造函数传递**: 当打开一个新窗体时,可以通过传递...

    C# 不同Form之间值的传递

    在C#编程中,Form是Windows应用程序中用户界面的基本组件,常常需要在多个Form之间传递数据。本篇文章将深入探讨三种常见的在不同Form之间传递值的方法:公共变量、窗口调用以及构造函数。 1. 公共变量 公共变量是...

    C# 简单反射实现winform左侧树形导航,右侧切换内容

    本示例“C# 简单反射实现winform左侧树形导航,右侧切换内容”是将反射技术应用于Windows桌面应用程序开发,特别是Winform界面设计中,通过反射机制实现在窗口左侧展示树形结构,用户点击节点后,右侧区域根据选择的...

    HTML中Form表单的method属性使用介绍

    1 method是指定数据如何发送到服务器的一个属性 2 只可能是post和get post:官方解释是把数据通过post会话传送到服务器。实际就是提交数据。 get:将表单中数据的按照variable=value的形式,添加到action所指向的URL...

    仿ElementUI实现一个Form表单的实现代码

    在ElementUI中,表单验证通常结合`&lt;el-form&gt;`的`rules`属性和`&lt;el-form-item&gt;`的`prop`属性实现。规则可以在Vue实例中定义,并通过`rules`属性与对应的`&lt;el-form-item&gt;`绑定,实现对表单字段的校验逻辑。 ### 总结 ...

    C# form窗体控件属性

    C#窗体控件的属性和方法,帮助我们熟悉窗体的开发,有利于增快开发速度

    源码解析之rc-field-form解读与实现

    **源码解析之rc-field-form解读与实现** `rc-field-form`是React社区中一个流行的表单库,它提供了一种高效、灵活的方式来处理复杂的表单逻辑和数据管理。在本文中,我们将深入探讨`rc-field-form`的核心概念、工作...

Global site tag (gtag.js) - Google Analytics