~怪^_*獸~

          虛榮鎖身軀 心靈給酒醉 脆弱人類 懶問何為對
          (怪獸樂園Q群:75375912

          導(dǎo)航

          <2012年4月>
          25262728293031
          1234567
          891011121314
          15161718192021
          22232425262728
          293012345

          留言簿

          隨筆分類(158)

          文章分類

          隨筆檔案(53)

          閱讀排行榜

          評論排行榜

          常用鏈接

          統(tǒng)計

          最新評論

          深度剖析:Java POJO Bean 對象與 Web Form 表單的自動裝配

            時下很多 Web 框架 都實現(xiàn)了 Form 表單域與 Java 對象屬性的自動裝配功能,該功能確實非常有用,試想如果沒這功能則勢必到處沖積著 request.getParameter() 系列方法與類型轉(zhuǎn)換方法的調(diào)用。重復(fù)代碼量大,容易出錯,同時又不美觀,影響市容。

            現(xiàn)在的問題是,這些框架通過什么方法實現(xiàn)自動裝配的?如果不用這些框架我們自己如何去實現(xiàn)呢?尤其對于那些純 JSP/Servlet 應(yīng)用,要是擁有自動裝配功能該多好啊!本座深知各位之期盼,決定把自動裝配的原理和實現(xiàn)方法娓娓道來。

            實現(xiàn)原理其實比較簡單,主要由以下3個步驟構(gòu)成:

            1. 通過 request.getParameterMap() 獲取被提交的 Form 的所有表單域的名稱-值映射,其中名稱和值均為字符串類型。
            2. 利用 java.beans.PropertyDescriptor 對象獲取 Java Bean 的所有屬性的名稱及其類型。
            3. 把表單域的名稱與 Bean 的屬性的名稱逐個進行匹配,當(dāng)找到相匹配的屬性時就調(diào)用 Bean 的 setter 方法把表單域的值設(shè)置給該 Bean 屬性。當(dāng)然,因為表單域的值總是字符串類型,很可能與 Bean 屬性的類型不一致,所以在設(shè)置 Bean 屬性前要進行必要的類型轉(zhuǎn)換。

            上面所表述的3點原理不知大家是否完全理解,沒關(guān)系,下面我們通過一個具體的表單提交的例子來看一看實際的效果,首先看看待提交的表單頁面及其代碼:

          <form action="checkbean.action" method="post">
          First Name: <input type="text" name="firstName" value="丑">
          <br>
          Last Name: <input type="text" name="lastName" value="怪獸">
          <br>
          Birthday: <input type="text" name="birthday" value="1978-11-03">
          <br>
          Gender: 男 <input type="radio"" name="gender" value="false">
          &nbsp;<input type="radio"" name="gender" value="true" checked="checked">
          <br>
          Working age: <select name="working-Age">
          <option value="-1">-請選擇-</option>
          <option value="3">三年</option>
          <option value="5" selected="selected">五年</option>
          <option value="10">十年</option>
          <option value="20">二十年</option>
          </select>
          <br>
          Interest: 游泳 <input type="checkbox" name="its" value="1" checked="checked">
          &nbsp;打球 <input type="checkbox" name="its" value="2" checked="checked">
          &nbsp;下棋 <input type="checkbox" name="its" value="3">
          &nbsp;打麻將 <input type="checkbox" name="its" value="4">
          &nbsp;看書 <input type="checkbox" name="its" value="5" checked="checked">
          <br>
          <br>
          <input type="submit" value="確 定">&nbsp;&nbsp;<input type="reset" value="重 置">
          </form>

           

            從上圖可以看出,總共有6個表單域,其名稱-值分別是:{"firstName" - "丑","lastName" - "怪獸","birthday" - "1978-11-03","gender" - "女","working-Age" - "5","its" - "1,2,5"},該表單需要提交給 checkbean.action 進行處理(請注意:不要一看到 .aciton 就以為是 struts2,騎白馬的不一定都是唐僧!),下面來看看 CheckBean Action 的處理代碼和 Bean 的定義:

           

          import java.util.HashMap;
          import java.util.Map;

          import vo.Persion;

          import com.bruce.mvc.ActionSupport;

          public class CheckBean extends ActionSupport
          {
          @Override
          public String execute()
          {
          // 如果表單元素的名稱和 Form Bean 屬性名不一致則使用 keyMap 進行映射
          // key: 表單元素名稱, value: Form Bean 屬性名
          Map<String, String> keyMap = new HashMap<String, String>();
          keyMap.put("working-Age", "workingAge");
          keyMap.put("its", "interest");

          /* 自動裝配方法一 */
          // 使用表單元素創(chuàng)建 Form Bean
          // 如果表單元素的名稱和 Form Bean 屬性名完全一致則不需使用 keyMap 進行映射
          Persion p = createFormBean(Persion.class, keyMap);

          /* 自動裝配方法二 */
          // 先創(chuàng)建 Form Bean 對象, 然后再填充它的屬性
          Persion p2 = new Persion();
          fillFormBeanProperties(p2, keyMap);

          // 可以獲取 Form Bean 的所有屬性值
          //Map<String, Object> result = BeanHelper.getProperties(p);

          // 把 p 設(shè)置為 request 屬性,并最終在結(jié)果頁面展示
          setRequestAttribute("persion", p);

          return SUCCESS;
          }
          }
          import java.util.Date;
          import java.util.List;

          public class Persion
          {
          private String firstName;
          private String lastName;
          private Date birthday;
          private boolean gender;
          private int workingAge;
          private int[] interest;
          private List<String> photos;

          // getter 和 setter 方法
          // (略)。。。。。。
          }


             從 CheckBean 的代碼可以看出,它是通過 createFormBean() 或 fillFormBeanProperties() 方法來自動裝配 Persion 的,它們之間的區(qū)別是:前者會直接創(chuàng)建新的 Persion 對象,而后者填充原有 Persion 對象的屬性。請注意,如果表單域的名稱與 Persion 對應(yīng)的屬性名不一致則用 keyMap 進行映射,如表單域 "working-Age" 是對應(yīng) Persion 的 workingAge 屬性的,但它們的名稱不一致,所以要進行映射。另外,Persion 有一個 photos 屬性,而我們的表單域卻沒有,自動裝配時會忽略該屬性。最后看一下輸出的結(jié)果頁面及其代碼:

            <body>
          <br>
          <div align="right">
          <a href="index.action"><u:msg key="jsp-set_locale.back-to-index"/></a>
          </div>
          <br><br><br><br>
          <div align="center">
          <table border="1">
          <caption>Persion Attributs</caption>

          <tr><td>Name</td><td><c:out value="${persion.firstName} ${persion.lastName}"/>&nbsp;</td></tr>
          <tr><td>Brithday</td><td><c:out value="${persion.birthday}"/>&nbsp;</td></tr>
          <tr><td>Gender</td><td><c:out value="${persion.gender}"/>&nbsp;</td></tr>
          <tr><td>Working Age</td><td><c:out value="${persion.workingAge}"/>&nbsp;</td></tr>
          <tr><td>Interest</td><td><c:forEach var="its" items="${persion.interest}">
          <c:out value="${its}" /> &nbsp;
          </c:forEach>&nbsp;</td></tr>
          <tr><td>Photos</td><td><c:forEach var="p" items="${persion.photos}">
          <c:out value="${p}" /><br>
          </c:forEach>&nbsp;</td></tr>
          </table>
          </div>
          </body>

            

            通過上面的例子可以看到,通過自動裝配 Bean,我們獲得了非常大的便利。現(xiàn)在我們就從createFormBean() 和 fillFormBeanProperties() 開始,逐步揭開自動裝配的神秘面紗,先看看下面兩個類及其方法的定義:

           

          package com.bruce.mvc;

          import com.bruce.util.http.HttpHelper;

          /** {@link Action} 對象公共基類 */
          public class ActionSupport implements Action
          {
          private ServletContext servletContext;
          private HttpServletRequest request;
          private HttpServletResponse response;
          private HttpSession session;

          /** 默認 {@link Action} 入口方法(返回 {@link Action#SUCCESS}) */
          public String execute()
          {
          return SUCCESS;
          }

          /** 使用表單元素創(chuàng)建 Form Bean (表單元素的名稱和 Form Bean 屬性名完全一致) */
          public final <T> T createFormBean(Class<T> clazz)
          {
          return HttpHelper.createFormBean(request, clazz);
          }

          /** 使用表單元素創(chuàng)建 Form Bean (用 keyMap 映射與表單元素名稱不對應(yīng)的 Form Bean 屬性) */
          public final <T> T createFormBean(Class<T> clazz, Map<String, String> keyMap)
          {
          return HttpHelper.createFormBean(request, clazz, keyMap);
          }

          /** 使用表單元素填充 Form Bean (表單元素的名稱和 Form Bean 屬性名完全一致) */
          public final <T> void fillFormBeanProperties(T bean)
          {
          HttpHelper.fillFormBeanProperties(request, bean);
          }

          /** 使用表單元素填充 Form Bean (用 keyMap 映射與表單元素名稱不對應(yīng)的 Form Bean 屬性) */
          public final <T> void fillFormBeanProperties(T bean, Map<String, String> keyMap)
          {
          HttpHelper.fillFormBeanProperties(request, bean, keyMap);
          }

          // 其它方法
          // (略)。。。
          }
          package com.bruce.util.http;

          import com.bruce.util.BeanHelper;

          /** HTTP 幫助類 */
          public class HttpHelper
          {
          /** 使用表單元素創(chuàng)建 Form Bean (表單元素的名稱和 Form Bean 屬性名完全一致) */
          public final static <T> T createFormBean(HttpServletRequest request, Class<T> clazz)
          {
          return createFormBean(request, clazz, null);
          }

          /** 使用表單元素創(chuàng)建 Form Bean (用 keyMap 映射與表單元素名稱不對應(yīng)的 Form Bean 屬性) */
          public final static <T> T createFormBean(HttpServletRequest request, Class<T> clazz, Map<String, String> keyMap)
          {
          Map<String, String[]> properties = getParamMap(request);
          return BeanHelper.createBean(clazz, properties, keyMap);
          }

          /** 使用表單元素填充 Form Bean (表單元素的名稱和 Form Bean 屬性名完全一致) */
          public final static <T> void fillFormBeanProperties(HttpServletRequest request, T bean)
          {
          fillFormBeanProperties(request, bean, null);
          }

          /** 使用表單元素填充 Form Bean (用 keyMap 映射與表單元素名稱不對應(yīng)的 Form Bean 屬性) */
          public final static <T> void fillFormBeanProperties(HttpServletRequest request, T bean, Map<String, String> keyMap)
          {
          Map<String, String[]> properties = getParamMap(request);
          BeanHelper.setProperties(bean, properties, keyMap);
          }

          /** 獲取 {@link HttpServletRequest} 的所有參數(shù)名稱和值 */
          public final static Map<String, String[]> getParamMap(HttpServletRequest request)
          {
          return request.getParameterMap();
          }

          // 其它方法
          // (略)。。。
          }


            哈哈,大家看到了吧,我們迂回了那么久,但 ActionSupport 類和 HttpHelper 類并沒有并沒有做多少事情,他們只是獲取請求參數(shù) Map,并傳遞給 BeanHelper 類的 createBean() 和 setProperties() 方法進行裝配,實際負責(zé)裝配工作的是 BeanHelper 。這里解析一下為何要寫得那么迂回,其實這些代碼是從本座自己寫的 “Portal Web 開發(fā)框架” 中摘錄出來的,總之一句話:是因為框架的需要而寫得那么迂回的,并非本座有意而為之。順便做下廣告:“Portal Web 開發(fā)框架是一套功能完備的 Web 服務(wù)端開發(fā)框架,內(nèi)置 MVC Web 基礎(chǔ)架構(gòu),支持可擴展的數(shù)據(jù)訪問接口(已內(nèi)置 Hibernate、MyBaits 和 JDBC 支持),集成攔截器、國際化、文件上傳下載和緩存等基礎(chǔ) Web 服務(wù),基于純 Jsp/Servlet API 實現(xiàn),非常容易學(xué)習(xí)和使用尤其適合那些希望使用純 Jsp/Servlet API 進行開發(fā)或?qū)?SSH 等主流框架的復(fù)雜性感到繁瑣與無奈的人士使用。該框架已通過多個商業(yè)項目考驗,并不是寫來玩的哦。如果各位有興趣,本座以后再找個機會開個專貼詳細介紹下這個框架。

            不扯遠了,回到我們的正題,我們再來看看 BeanHelper 的裝配工裝是如何實現(xiàn)的:

           

          /** Java Bean 幫助類,執(zhí)行 Java Bean 屬性的 get / set 相關(guān)操作 */
          public class BeanHelper
          {
          /** 創(chuàng)建指定類型的 Java Bean,并設(shè)置相關(guān)屬性
          *
          *
          @param clazz : Bean 類型
          *
          @param properties : 屬性名 / 值映射<br>
          * 其中名稱為 {
          @link String} 類型,與屬性名稱可能一直也可能不一致<br>
          * 屬性值可能為以下 3 中類型:<br>
          * &nbsp; &nbsp; 1) 屬性的實際類型:直接對屬性賦值<br>
          * &nbsp; &nbsp; 2) {
          @link String} 類型:先執(zhí)行自動類型轉(zhuǎn)換再對屬賦值<br>
          * &nbsp; &nbsp; 3) {
          @link String}[] 類型:先執(zhí)行自動類型轉(zhuǎn)換再對屬賦值<br>
          *
          @param keyMap : properties.key / Bean 屬性名映射,當(dāng) properties 的 key 與屬性名不對應(yīng)時,
          * 用 keyMap 把它們關(guān)聯(lián)起來
          *
          @return 生成的 Bean實例
          */
          public static final <B, T> B createBean(Class<B> clazz, Map<String, T> properties, Map<String, String> keyMap)
          {
          B bean = null;

          try
          {
          // 創(chuàng)建 Bean 實例
          bean = clazz.newInstance();
          // 設(shè)置 Bean 屬性
          setProperties(bean, properties, keyMap);
          }
          catch(Exception e)
          {
          throw new RuntimeException(e);
          }

          return bean;
          }

          public static final <B, T> B createBean(Class<B> clazz, Map<String, T> properties)
          {
          return createBean(clazz, properties, null);
          }

          /** 設(shè)置 Java Bean 的屬性
          *
          *
          @param bean : Bean 實例
          *
          @param properties : 屬性名 / 值映射<br>
          * 其中名稱為 {
          @link String} 類型,與屬性名稱可能一直也可能不一致<br>
          * 屬性值可能為以下 3 中類型:<br>
          * &nbsp; &nbsp; 1) 屬性的實際類型:直接對屬性賦值<br>
          * &nbsp; &nbsp; 2) {
          @link String} 類型:先執(zhí)行自動類型轉(zhuǎn)換再對屬賦值<br>
          * &nbsp; &nbsp; 3) {
          @link String}[] 類型:先執(zhí)行自動類型轉(zhuǎn)換再對屬賦值<br>
          *
          @param keyMap : properties.key / Bean 屬性名映射,當(dāng) properties 的 key 與屬性名不對應(yīng)時,
          * 用 keyMap 把它們關(guān)聯(lián)起來
          */
          public static final <T> void setProperties(Object bean, Map<String, T> properties, Map<String, String> keyMap)
          {
          // 獲取所有 Bean 屬性
          Map<String, PropertyDescriptor> pps = getPropDescMap(bean.getClass());
          Set<Map.Entry<String, T>> set = properties.entrySet();

          // 根據(jù)屬性名稱設(shè)置 Bean 的每個屬性值
          for(Map.Entry<String, T> o : set)
          {
          String name = null; // 屬性名稱
          String key = o.getKey();

          if(keyMap != null)
          name = keyMap.get(key);
          if(name == null)
          name = key;

          T value = o.getValue();
          PropertyDescriptor pd = pps.get(name); // 名稱對應(yīng)的 PropertyDescriptor

          if(pd != null && value != null)
          // 設(shè)置指定屬性值
          setProperty(bean, pd, value);
          }
          }

          public static final <T> void setProperties(Object bean, Map<String, T> properties)
          {
          setProperties(bean, properties, null);
          }

          // 設(shè)置指定屬性值
          private static final <T> boolean setProperty(Object bean, PropertyDescriptor pd, T value)
          {
          // 獲取屬性的 setter 方法
          Method method = pd.getWriteMethod();
          // 只處理 public 的實例 setter 方法
          if(method != null && isPublicInstanceMethod(method))
          {
          method.setAccessible(true);

          Class<?> clazz = pd.getPropertyType();
          // 設(shè)置具體屬性值
          setProperty(bean, value, method, clazz);

          return true;
          }

          return false;
          }

          // 設(shè)置具體屬性值
          private static <T> void setProperty(Object bean, T value, Method method, Class<?> clazz)
          {
          Object param = null;
          Class<?> valueType = value.getClass();
          Class<?> valueComType = valueType.getComponentType();
          Class<?> clazzComType = clazz.getComponentType();

          // 檢查是否需要作類型轉(zhuǎn)換
          if(
          !clazz.isAssignableFrom(valueType) &&
          (
          (valueType.equals(String.class)) ||
          (valueType.isArray() && valueComType.equals(String.class))
          ) &&
          (
          (GeneralHelper.isSimpleType(clazz)) ||
          (clazz.isArray() && GeneralHelper.isSimpleType(clazzComType))
          )
          )
          // 轉(zhuǎn)換為目標類型的屬性值
          param = parseParameter(clazz, value);
          else
          param = value;

          // 調(diào)研 setter 方法設(shè)置屬性值
          invokeMethod(bean, method, param);
          }

          // 執(zhí)行類型轉(zhuǎn)換 (不解釋了,看官們自己參詳吧 ^_^)
          private static final <T> Object parseParameter(Class<?> clazz, T obj)
          {
          Object param = null;
          Class<?> valueType = obj.getClass();

          if(clazz.isArray())
          {
          String[] value = null;

          if(valueType.isArray())
          value = (String[])obj;
          else
          {
          String str = (String)obj;
          StringTokenizer st = new StringTokenizer(str, " ,;\t\n\r\f");
          value = new String[st.countTokens()];

          for(int i = 0; st.hasMoreTokens(); i++)
          value[i] = st.nextToken();
          }

          int length = value.length;
          Class<?> type = clazz.getComponentType();
          param = Array.newInstance(type, length);

          for(int i = 0; i < length; i++)
          {
          String v = value[i];
          Object p = GeneralHelper.str2Object(type, v);
          Array.set(param, i, p);
          }
          }
          else
          {
          String value = null;

          if(valueType.isArray())
          {
          String[] array = (String[])obj;
          if(array.length > 0)
          value = array[0];
          }
          else
          value = (String)obj;

          param = GeneralHelper.str2Object(clazz, value);
          }

          return param;
          }

          // 其他方法
          // (略)。。。
          }
          public class GeneralHelper
          {
          /** 簡單數(shù)據(jù)類型集合 */
          public static final Set<Class<?>> SMIPLE_CLASS_SET = new HashSet<Class<?>>(18);

          static
          {
          SMIPLE_CLASS_SET.add(int.class);
          SMIPLE_CLASS_SET.add(long.class);
          SMIPLE_CLASS_SET.add(float.class);
          SMIPLE_CLASS_SET.add(double.class);
          SMIPLE_CLASS_SET.add(byte.class);
          SMIPLE_CLASS_SET.add(char.class);
          SMIPLE_CLASS_SET.add(short.class);
          SMIPLE_CLASS_SET.add(boolean.class);
          SMIPLE_CLASS_SET.add(Integer.class);
          SMIPLE_CLASS_SET.add(Long.class);
          SMIPLE_CLASS_SET.add(Float.class);
          SMIPLE_CLASS_SET.add(Double.class);
          SMIPLE_CLASS_SET.add(Byte.class);
          SMIPLE_CLASS_SET.add(Character.class);
          SMIPLE_CLASS_SET.add(Short.class);
          SMIPLE_CLASS_SET.add(Boolean.class);
          SMIPLE_CLASS_SET.add(String.class);
          SMIPLE_CLASS_SET.add(Date.class);
          }

          /** 檢查 clazz 是否為簡單數(shù)據(jù)類型 */
          public final static boolean isSimpleType(Class<?> clazz)
          {
          return SMIPLE_CLASS_SET.contains(clazz);
          }

          /** String -> Any,如果 handler 為 null 則把字符串轉(zhuǎn)換為 8 種基礎(chǔ)數(shù)據(jù)類型、及其包裝類、 {@link Date} 或 {@link String},
          * 如果 handler 不為 null 則由 handler 執(zhí)行轉(zhuǎn)換
          *
          *
          @param type : 目標類型的 {@link Class} 對象
          *
          @param v : 要轉(zhuǎn)換的字符串
          *
          @param handler : 類型轉(zhuǎn)換處理器
          *
          @return : 轉(zhuǎn)換結(jié)果,如果轉(zhuǎn)換不成功返回 null
          *
          @throws : 如果目標類型不支持拋出 {@link IllegalArgumentException}
          *
          */
          @SuppressWarnings("unchecked")
          public static final <T> T str2Object(Class<T> type, String v, TypeHandler<T> handler)
          {
          Object param = null;

          if(handler != null)
          return handler.handle(v);

          if(type == String.class)
          param = safeTrimString(v);
          else if(type == int.class)
          param = str2Int_0(v);
          else if(type == long.class)
          param = str2Long_0(v);
          else if(type == byte.class)
          param = str2Byte_0(v);
          else if(type == char.class)
          param = str2Char_0(v);
          else if(type == float.class)
          param = str2Float_0(v);
          else if(type == double.class)
          param = str2Double_0(v);
          else if(type == short.class)
          param = str2Short_0(v);
          else if(type == boolean.class)
          param = str2Boolean_False(v);
          else if(type == Integer.class)
          param = str2Int(v);
          else if(type == Long.class)
          param = str2Long(v);
          else if(type == Byte.class)
          param = str2Byte(v);
          else if(type == Character.class)
          param = str2Char(v);
          else if(type == Float.class)
          param = str2Float(v);
          else if(type == Double.class)
          param = str2Double(v);
          else if(type == Short.class)
          param = str2Short(v);
          else if(type == Boolean.class)
          param = str2Boolean(v);
          else if(Date.class.isAssignableFrom(type))
          param = str2Date(v);
          else
          throw new IllegalArgumentException(String.format("object type '%s' not valid", type));

          return (T)param;
          }

          public static final <T> T str2Object(Class<T> type, String v)
          {
          return str2Object(type, v, null);
          }

          // 其他方法
          // (略)。。。
          }

           

            從上面的代碼可以看出,BeanHelper 支持8種簡單數(shù)據(jù)類型及其包裝類、String 和 Date 類型以及它們的數(shù)組類型的自動裝配,最后強調(diào)一下:BeanHelper 和 GeneralHelper 其實是兩個用途非常廣泛的類,其作用不單是為了協(xié)助 Form 表單域自動裝配 Bean 。下面列出一些使用例子,幫助大家進一步了解 BeanHelper 的使用方法:

           

          View Code
            1 package test;
          2
          3 import java.beans.IntrospectionException;
          4 import java.util.Date;
          5 import java.util.HashMap;
          6 import java.util.Map;
          7 import java.util.StringTokenizer;
          8
          9 import com.bruce.util.BeanHelper;
          10 import com.bruce.util.GeneralHelper;
          11
          12 @SuppressWarnings("unused")
          13 public class TestBeanHelper extends Object
          14 {
          15 public static void main(String[] args) throws Exception
          16 {
          17 test();
          18 testStr2Object();
          19 test_setProperty();
          20 test_setProperties_1();
          21 test_setProperties_2();
          22 }
          23
          24 private static void test()
          25 {
          26 //System.out.println(GeneralHelper.str2Date(" 1978-11-03 "));
          27 //System.out.println(GeneralHelper.str2Date(" 1978-11-03 "));
          28 //GeneralHelper.str2Byte(null);
          29 //GeneralHelper.str2Char_0(null);
          30 //GeneralHelper.str2Boolean(null);
          31 //GeneralHelper.str2Boolean_False(null);
          32 }
          33
          34 private static void testStr2Object() throws IntrospectionException
          35 {
          36 int i = GeneralHelper.str2Object(int.class, "123");
          37 Date dt = GeneralHelper.str2Object(Date.class, "1978-11-03");
          38 String[] arr = GeneralHelper.str2Object(String[].class, "12, 34, 56, 78", new GeneralHelper.TypeHandler<String[]>()
          39 {
          40 @Override
          41 public String[] handle(String v)
          42 {
          43 StringTokenizer st = new StringTokenizer(v, " ,;\t\r\n\f");
          44 String[] result = new String[st.countTokens()];
          45
          46 for(int i = 0; st.hasMoreTokens(); i++)
          47 result[i] = st.nextToken();
          48
          49 return result;
          50 }
          51 });
          52
          53 // !! error !!
          54 // String[] arr2 = GeneralHelper.str2Object(String[].class, "12, 34, 56, 78");
          55 }
          56
          57 private static void test_setProperty()
          58 {
          59 C c = new C();
          60 BeanHelper.setProperty(c, "dt", "2010-10-10");
          61 BeanHelper.setProperty(c, "i", 456);
          62 BeanHelper.setProperty(c, "l", "999");
          63 int i = BeanHelper.getProperty(c, "i");
          64 double l = BeanHelper.getProperty(c, "l");
          65 boolean b = BeanHelper.getProperty(c, "b");
          66 Date dt = BeanHelper.getProperty(c, "dt");
          67 System.out.println(c);
          68 }
          69
          70 private static void test_setProperties_1() throws Exception
          71 {
          72 Map<String, String[]> objs = new HashMap<String, String[]>();
          73 objs.put("si", new String[] {"888"});
          74 objs.put("fi", new String[] {"999"});
          75 objs.put("b", new String[] {"true"});
          76 objs.put("i", new String[] {"1"});
          77 objs.put("l", new String[] {"2.3"});
          78 objs.put("dt", new String[] {"2011-09-17"});
          79 objs.put("__str", new String[] {"我是怪獸"});
          80 objs.put("__ia", new String[] {"12", "34", "56"});
          81 objs.put("__sa", new String[] {"ab", "cd", "ef"});
          82
          83 Map<String, String> keyMap = new HashMap<String, String>();
          84 keyMap.put("__str", "str");
          85 keyMap.put("__ia", "ia");
          86 keyMap.put("__sa", "sa");
          87
          88 C c = BeanHelper.createBean(C.class, objs, keyMap);
          89 Map<String, Object> result = BeanHelper.getProperties(c);
          90 System.out.println(result);
          91 }
          92
          93 private static void test_setProperties_2() throws Exception
          94 {
          95 java.sql.Date dt = new java.sql.Date(new java.util.Date().getTime());
          96
          97 Map<String, Object> objs = new HashMap<String, Object>();
          98 objs.put("si", 888);
          99 objs.put("fi", 999);
          100 objs.put("b", "True");
          101 objs.put("i", 123);
          102 objs.put("l", "2.3");
          103 //objs.put("dt", new String[] {"2011-09-17"});
          104 objs.put("dt", dt);
          105 objs.put("str", "我是怪獸");
          106 objs.put("ia", new int[] {12, 34, 56});
          107 objs.put("sa", "ab, cd, ef");
          108
          109 C c = new C();
          110 BeanHelper.setProperties(c, objs);
          111 Map<String, Object> result = BeanHelper.getProperties(c);
          112 System.out.println(result);
          113 }
          114
          115
          116 }
          View Code
           1 package test;
          2
          3 import java.util.Date;
          4
          5
          6 class A
          7 {
          8 private boolean b;
          9
          10 public boolean isB()
          11 {
          12 return b;
          13 }
          14
          15 public void setB(boolean b)
          16 {
          17 this.b = b;
          18 }
          19
          20 }
          21
          22 public class C extends A
          23 {
          24 static int si;
          25 final int fi = 100;
          26
          27 private int i;
          28 private Double l;
          29 private Date dt;
          30 private String str;
          31 private int[] ia;
          32 private String[] sa;
          33
          34 public String[] getSa()
          35 {
          36 return sa;
          37 }
          38 public void setSa(String[] sa)
          39 {
          40 this.sa = sa;
          41 }
          42 public static int getSi()
          43 {
          44 return si;
          45 }
          46 public static void setSi(int si)
          47 {
          48 C.si = si;
          49 }
          50 public int getFi()
          51 {
          52 return fi;
          53 }
          54 public String getStr()
          55 {
          56 return str;
          57 }
          58 public void setStr(String str)
          59 {
          60 this.str = str;
          61 }
          62 public int[] getIa()
          63 {
          64 return ia;
          65 }
          66 public void setIa(int[] ia)
          67 {
          68 this.ia = ia;
          69 }
          70 public int getI()
          71 {
          72 return i;
          73 }
          74 public void setI(int i)
          75 {
          76 this.i = i;
          77 }
          78 public Double getL()
          79 {
          80 return l;
          81 }
          82 public void setL(Double l)
          83 {
          84 this.l = l;
          85 }
          86 public Date getDt()
          87 {
          88 return dt;
          89 }
          90 public void setDt(Date dt)
          91 {
          92 this.dt = dt;
          93 }
          94 }

           

            老規(guī)矩,想看完整代碼者請輕輕 Touch 一下:  Source Code ^_^ 



          原文出處:怪獸的博客  怪獸的微博  怪獸樂園Q群

          posted on 2012-04-13 02:10 ~怪^_*獸~ 閱讀(1982) 評論(0)  編輯  收藏 所屬分類: 編程技術(shù)互聯(lián)網(wǎng)絡(luò)軟件設(shè)計

          主站蜘蛛池模板: 天镇县| 苍溪县| 昌邑市| 报价| 松江区| 鹤峰县| 太仆寺旗| 融水| 佳木斯市| 灌阳县| 阳原县| 大庆市| 封开县| 广东省| 道真| 金塔县| 临泽县| 天全县| 新泰市| 广州市| 分宜县| 句容市| 和田县| 沙坪坝区| 米林县| 星子县| 聂荣县| 来安县| 新和县| 胶州市| 琼结县| 漳浦县| 仁寿县| 友谊县| 洛阳市| 洛川县| 陵川县| 余江县| 乐清市| 福建省| 即墨市|