<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    java學(xué)習(xí)

    java學(xué)習(xí)

     

    Form 表單域與 Java 對(duì)象屬性的自動(dòng)裝配功能

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

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

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

      1. 通過(guò) request.getParameterMap() 獲取被提交的 Form 的所有表單域的名稱-值映射,其中名稱和值均為字符串類型。
      2. 利用 java.beans.PropertyDescriptor 對(duì)象獲取 Java Bean 的所有屬性的名稱及其類型。
      3. 把表單域的名稱與 Bean 的屬性的名稱逐個(gè)進(jìn)行匹配,當(dāng)找到相匹配的屬性時(shí)就調(diào)用 Bean 的 setter 方法把表單域的值設(shè)置給該 Bean 屬性。當(dāng)然,因?yàn)楸韱斡虻闹悼偸亲址愋停芸赡芘c Bean 屬性的類型不一致,所以在設(shè)置 Bean 屬性前要進(jìn)行必要的類型轉(zhuǎn)換。

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



    <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">-請(qǐng)選擇-</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個(gè)表單域,其名稱-值分別是:{"firstName" - "丑","lastName" - "怪獸","birthday" - "1978-11-03","gender" - "女","working-Age" - "5","its" - "1,2,5"},該表單需要提交給 checkbean.action 進(jìn)行處理(請(qǐng)注意:不要一看到 .aciton 就以為是 struts2,騎白馬的不一定都是唐僧!),下面來(lái)看看 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 進(jìn)行映射
            // key: 表單元素名稱, value: Form Bean 屬性名
            Map<String, String> keyMap = new HashMap<String, String>();
            keyMap.put("working-Age", "workingAge");
            keyMap.put("its", "interest");
            
            /* 自動(dòng)裝配方法一 */
            // 使用表單元素創(chuàng)建 Form Bean
            // 如果表單元素的名稱和 Form Bean 屬性名完全一致則不需使用 keyMap 進(jìn)行映射
            Persion p = createFormBean(Persion.class, keyMap);
            
            /* 自動(dòng)裝配方法二 */
            // 先創(chuàng)建 Form Bean 對(duì)象, 然后再填充它的屬性
            Persion p2 = new Persion();
            fillFormBeanProperties(p2, keyMap);
            
            // 可以獲取 Form Bean 的所有屬性值
            //Map<String, Object> result = BeanHelper.getProperties(p);
            
            // 把 p 設(shè)置為 request 屬性,并最終在結(jié)果頁(yè)面展示
            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 的代碼可以看出,它是通過(guò) createFormBean() 或 fillFormBeanProperties() 方法來(lái)自動(dòng)裝配 Persion 的,它們之間的區(qū)別是:前者會(huì)直接創(chuàng)建新的 Persion 對(duì)象,而后者填充原有 Persion 對(duì)象的屬性。請(qǐng)注意,如果表單域的名稱與 Persion 對(duì)應(yīng)的屬性名不一致則用 keyMap 進(jìn)行映射,如表單域 "working-Age" 是對(duì)應(yīng) Persion 的 workingAge 屬性的,但它們的名稱不一致,所以要進(jìn)行映射。另外,Persion 有一個(gè) photos 屬性,而我們的表單域卻沒(méi)有,自動(dòng)裝配時(shí)會(huì)忽略該屬性。最后看一下輸出的結(jié)果頁(yè)面及其代碼:



    <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>

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

    package com.bruce.mvc;

    import com.bruce.util.http.HttpHelper;

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

        /** 默認(rèn) {@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 映射與表單元素名稱不對(duì)應(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 映射與表單元素名稱不對(duì)應(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 映射與表單元素名稱不對(duì)應(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 映射與表單元素名稱不對(duì)應(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 類并沒(méi)有并沒(méi)有做多少事情,他們只是獲取請(qǐng)求參數(shù) Map,并傳遞給 BeanHelper 類的 createBean() 和 setProperties() 方法進(jìn)行裝配,實(shí)際負(fù)責(zé)裝配工作的是 BeanHelper 。這里解析一下為何要寫得那么迂回,其實(shí)這些代碼是從本座自己寫的 “Portal Web 開(kāi)發(fā)框架” 中摘錄出來(lái)的,總之一句話:是因?yàn)榭蚣艿男枰鴮懙媚敲从鼗氐模⒎潜咀幸舛鵀橹m槺阕鱿聫V告:“Portal Web 開(kāi)發(fā)框架是 一套功能完備的 Web 服務(wù)端開(kāi)發(fā)框架,內(nèi)置 MVC Web 基礎(chǔ)架構(gòu),支持可擴(kuò)展的數(shù)據(jù)訪問(wèn)接口(已內(nèi)置 Hibernate、MyBaits 和 JDBC 支持),集成攔截器、國(guó)際化、文件上傳下載和緩存等基礎(chǔ) Web 服務(wù),基于純 Jsp/Servlet API 實(shí)現(xiàn),非常容易學(xué)習(xí)和使用尤其適合那些希望使用純 Jsp/Servlet API 進(jìn)行開(kāi)發(fā)或?qū)?SSH 等主流框架的復(fù)雜性感到繁瑣與無(wú)奈的人士使用。該框架已通過(guò)多個(gè)商業(yè)項(xiàng)目考驗(yàn),并不是寫來(lái)玩的哦。如果各位有興趣,本座以后再找個(gè)機(jī)會(huì)開(kāi)個(gè)專貼詳細(xì)介紹下這個(gè)框架。

      不扯遠(yuǎn)了,回到我們的正題,我們?cè)賮?lái)看看 BeanHelper 的裝配工裝是如何實(shí)現(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) 屬性的實(shí)際類型:直接對(duì)屬性賦值<br>
         *                        &nbsp; &nbsp; 2) {@link String} 類型:先執(zhí)行自動(dòng)類型轉(zhuǎn)換再對(duì)屬賦值<br>
         *                        &nbsp; &nbsp; 3) {@link String}[] 類型:先執(zhí)行自動(dòng)類型轉(zhuǎn)換再對(duì)屬賦值<br>
         *  @param keyMap        : properties.key / Bean 屬性名映射,當(dāng) properties 的 key 與屬性名不對(duì)應(yīng)時(shí),
         *                        用 keyMap 把它們關(guān)聯(lián)起來(lái)
         *  @return                  生成的 Bean實(shí)例  
         */
        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 實(shí)例
                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 實(shí)例
         *  @param properties    : 屬性名 / 值映射<br>
         *                        其中名稱為 {@link String} 類型,與屬性名稱可能一直也可能不一致<br>
         *                        屬性值可能為以下 3 中類型:<br>
         *                        &nbsp; &nbsp; 1) 屬性的實(shí)際類型:直接對(duì)屬性賦值<br>
         *                        &nbsp; &nbsp; 2) {@link String} 類型:先執(zhí)行自動(dòng)類型轉(zhuǎn)換再對(duì)屬賦值<br>
         *                        &nbsp; &nbsp; 3) {@link String}[] 類型:先執(zhí)行自動(dòng)類型轉(zhuǎn)換再對(duì)屬賦值<br>
         *  @param keyMap        : properties.key / Bean 屬性名映射,當(dāng) properties 的 key 與屬性名不對(duì)應(yīng)時(shí),
         *                        用 keyMap 把它們關(guān)聯(lián)起來(lái)  
         */
        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 的每個(gè)屬性值
            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);    // 名稱對(duì)應(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 的實(shí)例 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)換為目標(biāo)類型的屬性值
                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
    {
        /** 簡(jiǎn)單數(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 是否為簡(jiǎn)單數(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    : 目標(biāo)類型的 {@link Class} 對(duì)象
         * @param v        : 要轉(zhuǎn)換的字符串
         * @param handler    : 類型轉(zhuǎn)換處理器
         * @return        : 轉(zhuǎn)換結(jié)果,如果轉(zhuǎn)換不成功返回 null
         * @throws         : 如果目標(biāo)類型不支持拋出 {@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種簡(jiǎn)單數(shù)據(jù)類型及其包裝類、String 和 Date 類型以及它們的數(shù)組類型的自動(dòng)裝配,最后強(qiáng)調(diào)一下:BeanHelper 和 GeneralHelper 其實(shí)是兩個(gè)用途非常廣泛的類,其作用不單是為了協(xié)助 Form 表單域自動(dòng)裝配 Bean 。下面列出一些使用例子,幫助大家進(jìn)一步了解 BeanHelper 的使用方法:
    View Code
     package test;
     
     import java.beans.IntrospectionException;
     import java.util.Date;
     import java.util.HashMap;
     import java.util.Map;
     import java.util.StringTokenizer;
     
     import com.bruce.util.BeanHelper;
     import com.bruce.util.GeneralHelper;
     
     @SuppressWarnings("unused")
     public class TestBeanHelper extends Object
     {
         public static void main(String[] args) throws Exception
         {
             test();
             testStr2Object();
             test_setProperty();
             test_setProperties_1();
             test_setProperties_2();
         }
     
         private static void test()
         {
             //System.out.println(GeneralHelper.str2Date("  1978-11-03  "));
     //System.out.println(GeneralHelper.str2Date("  1978-11-03  "));
     //GeneralHelper.str2Byte(null);
     //GeneralHelper.str2Char_0(null);
     //GeneralHelper.str2Boolean(null);
     //GeneralHelper.str2Boolean_False(null);
         }
     
         private static void testStr2Object() throws IntrospectionException
         {
             int i = GeneralHelper.str2Object(int.class, "123");
             Date dt = GeneralHelper.str2Object(Date.class, "1978-11-03");
             String[] arr = GeneralHelper.str2Object(String[].class, "12, 34, 56, 78", new GeneralHelper.TypeHandler<String[]>()
             {
                 @Override
                 public String[] handle(String v)
                 {
                     StringTokenizer st = new StringTokenizer(v, " ,;\t\r\n\f");
                     String[] result = new String[st.countTokens()];
                     
                     for(int i = 0; st.hasMoreTokens(); i++)
                         result[i] = st.nextToken();
                     
                     return result;
                 }
             });
             
             // !! error !!
     // String[] arr2 = GeneralHelper.str2Object(String[].class, "12, 34, 56, 78");
         }
     
         private static void test_setProperty()
         {
             C c = new C();
             BeanHelper.setProperty(c, "dt", "2010-10-10");
             BeanHelper.setProperty(c, "i", 456);
             BeanHelper.setProperty(c, "l", "999");
             int i = BeanHelper.getProperty(c, "i");
             double l = BeanHelper.getProperty(c, "l");
             boolean b = BeanHelper.getProperty(c, "b");
             Date dt = BeanHelper.getProperty(c, "dt");
             System.out.println(c);
         }
     
         private static void test_setProperties_1() throws Exception
         {
             Map<String, String[]> objs = new HashMap<String, String[]>();
             objs.put("si", new String[] {"888"});
             objs.put("fi", new String[] {"999"});
             objs.put("b", new String[] {"true"});
             objs.put("i", new String[] {"1"});
             objs.put("l", new String[] {"2.3"});
             objs.put("dt", new String[] {"2011-09-17"});
             objs.put("__str", new String[] {"我是怪獸"});
             objs.put("__ia", new String[] {"12", "34", "56"});
             objs.put("__sa", new String[] {"ab", "cd", "ef"});
             
             Map<String, String> keyMap = new HashMap<String, String>();
             keyMap.put("__str", "str");
             keyMap.put("__ia", "ia");
             keyMap.put("__sa", "sa");
             
             C c = BeanHelper.createBean(C.class, objs, keyMap);
             Map<String, Object> result = BeanHelper.getProperties(c);
             System.out.println(result);
         }
         
         private static void test_setProperties_2() throws Exception
         {
             java.sql.Date dt = new java.sql.Date(new java.util.Date().getTime());
             
             Map<String, Object> objs = new HashMap<String, Object>();
             objs.put("si", 888);
             objs.put("fi", 999);
             objs.put("b", "True");
             objs.put("i", 123);
             objs.put("l", "2.3");
             //objs.put("dt", new String[] {"2011-09-17"});
             objs.put("dt", dt);
             objs.put("str", "我是怪獸");
             objs.put("ia", new int[] {12, 34, 56});
             objs.put("sa", "ab, cd, ef");
             
             C c = new C();
             BeanHelper.setProperties(c, objs);
             Map<String, Object> result = BeanHelper.getProperties(c);
             System.out.println(result);
         }
         
         
     }
    View Code
     package test;
     
     import java.util.Date;
     
     
     class A
     {
         private boolean b;
     
         public boolean isB()
         {
             return b;
         }
     
         public void setB(boolean b)
         {
             this.b = b;
         }
     
     }
     
     public class C extends A
     {
         static int si;
         final int fi = 100;
         
         private int i;
         private Double l;
         private Date dt;
         private String str;
         private int[] ia;
         private String[] sa;
     
         public String[] getSa()
         {
             return sa;
         }
         public void setSa(String[] sa)
         {
             this.sa = sa;
         }
         public static int getSi()
         {
             return si;
         }
         public static void setSi(int si)
         {
             C.si = si;
         }
         public int getFi()
         {
             return fi;
         }
         public String getStr()
         {
             return str;
         }
         public void setStr(String str)
         {
             this.str = str;
         }
         public int[] getIa()
         {
             return ia;
         }
         public void setIa(int[] ia)
         {
             this.ia = ia;
         }
         public int getI()
         {
             return i;
         }
         public void setI(int i)
         {
             this.i = i;
         }
         public Double getL()
         {
             return l;
         }
         public void setL(Double l)
         {
             this.l = l;
         }
         public Date getDt()
         {
             return dt;
         }
         public void setDt(Date dt)
         {
             this.dt = dt;
         }    
     }

    posted on 2013-01-07 09:40 楊軍威 閱讀(4470) 評(píng)論(1)  編輯  收藏

    評(píng)論

    # re: Form 表單域與 Java 對(duì)象屬性的自動(dòng)裝配功能[未登錄](méi) 2016-03-15 16:11 alex

    沒(méi)排版,看著好累  回復(fù)  更多評(píng)論   


    只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


    網(wǎng)站導(dǎo)航:
     

    導(dǎo)航

    統(tǒng)計(jì)

    常用鏈接

    留言簿

    隨筆檔案

    搜索

    最新評(píng)論

    閱讀排行榜

    評(píng)論排行榜

    主站蜘蛛池模板: 成人爽a毛片免费| 三年片在线观看免费观看大全中国| 亚洲精品影院久久久久久| 日本亚洲欧洲免费天堂午夜看片女人员 | 亚洲人成网www| 久久亚洲精品无码aⅴ大香| 亚洲最大成人网色| 久久精品亚洲中文字幕无码麻豆| 久久久久亚洲Av无码专| 亚洲国产午夜精品理论片| 国产成人精品日本亚洲专区6| 精品丝袜国产自在线拍亚洲| 亚洲午夜成人精品无码色欲| 亚洲精品无码成人片久久不卡| 亚洲AV女人18毛片水真多| 黄色毛片免费网站| 中文毛片无遮挡高清免费| 国产一区二区免费| 精品国产sm捆绑最大网免费站| 一个人免费高清在线观看 | 羞羞视频在线观看免费| 中国内地毛片免费高清| 久久国产免费一区二区三区| 黄色网址免费大全| 好大好深好猛好爽视频免费| 亚洲第一视频在线观看免费| 亚洲精品国产美女久久久| 亚洲高清视频在线播放| 亚洲免费综合色在线视频| 成人免费视频一区二区| 无码精品人妻一区二区三区免费看 | 特级毛片全部免费播放a一级| 中文字幕在线视频免费| 曰批全过程免费视频网址| 好吊妞视频免费视频| 在线日韩日本国产亚洲| 亚洲高清资源在线观看| 国产精品亚洲av色欲三区| aa级毛片毛片免费观看久| 美丽的姑娘免费观看在线播放| 暖暖日本免费在线视频 |