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

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

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

    apache.commons.beanutils.BeanUtils的使用

    引言

    該class提供了一系列的靜態(tài)方法操作業(yè)已存在的符合JavaBean規(guī)范定義的Java Class.這里強(qiáng)調(diào)的JavaBean規(guī)范,簡(jiǎn)單來說就是一個(gè)Java Class通過一系列g(shù)etter和setter的方法向外界展示其內(nèi)在的成員變量(屬性).通過BeanUtils的靜態(tài)方法,我們可以:

    • 復(fù)制一個(gè)JavaBean的實(shí)例--BeanUtils.cloneBean();
    • 在一個(gè)JavaBean的兩個(gè)實(shí)例之間復(fù)制屬性--BeanUtils.copyProperties(),BeanUtils.copyProperty();
    • 為一個(gè)JavaBean的實(shí)例設(shè)置成員變量(屬性)值--BeanUtils.populate(),BeanUtils.setProperty();
    • 從 一個(gè)一個(gè)JavaBean的實(shí)例中讀取成員變量(屬性)的值 --BeanUtils.getArrayProperty(),BeanUtils.getIndexedProperty(),BeanUtils.getMappedProperty(),BeanUtils.getNestedProperty(),BeanUtils.getSimpleProperty(),BeanUtils.getProperty(),BeanUtils.describe();

    總的來看BeanUtils類提供了兩大類的功能:讀,寫成員變量.

    準(zhǔn)備工作

    下面逐一分析使用方法.首先我們建立兩個(gè)JavaBean,名位SampleObject和SampleObjectA,具體如下:

    package beanutil;

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

    /**
    * @author samepoint
    *
    * SampleObject contains some types of member varaibles:String,int,Array,Map,Object(self defined),just for test usaged of apache.commons.beanutils.BeanUtils
    */
    public class SampleObject {
    String name = null;
    String display = null;
    int num = -1;
    char[] words = {'a','b','c','d'};
    boolean tag = false;
    Map map = new HashMap();
    SampleObjectA sample = null;

    /**
    * default constructor. initialized members of map and sample.
    */
    public SampleObject() {
    this.map.put("home","localhost");
    this.map.put("port","80");
    }

    //the following is getters and setters
    /**
    * @return Returns the display.
    */
    public String getDisplay() {
    return display;
    }
    /**
    * @param display The display to set.
    */
    public void setDisplay(String display) {
    this.display = display;
    }
    /**
    * @return Returns the name.
    */
    public String getName() {
    return name;
    }
    /**
    * @param name The name to set.
    */
    public void setName(String name) {
    this.name = name;
    }
    /**
    * @return Returns the num.
    */
    public int getNum() {
    return num;
    }
    /**
    * @param num The num to set.
    */
    public void setNum(int num) {
    this.num = num;
    }
    /**
    * @return Returns the words.
    */
    public char[] getWords() {
    return words;
    }
    /**
    * @param words The words to set.
    */
    public void setWords(char[] words) {
    this.words = words;
    }
    /**
    * @return Returns the tag.
    */
    public boolean isTag() {
    return tag;
    }
    /**
    * @param tag The tag to set.
    */
    public void setTag(boolean tag) {
    this.tag = tag;
    }
    /**
    * @return Returns the map.
    */
    public Map getMap() {
    return map;
    }
    /**
    * @param map The map to set.
    */
    public void setMap(Map map) {
    this.map = map;
    }
    /**
    * @return Returns the sample.
    */
    public SampleObject getSample() {
    return sample;
    }
    /**
    * @param sample The sample to set.
    */
    public void setSample(SampleObject sample) {
    this.sample = sample;
    }
    }

    package beanutil;

    /**
    * @author samepoint
    *
    * Used to copy properties from SampleOjbect.
    * Used to nested property.
    */
    public class SampleObjectA {
    String name = null;
    String display = null;
    Double num = null;

    /**
    * @return Returns the num.
    */
    public Double getNum() {
    return num;
    }
    /**
    * @param num The num to set.
    */
    public void setNum(Double num) {
    this.num = num;
    }
    /**
    * @return Returns the display.
    */
    public String getDisplay() {
    return display;
    }
    /**
    * @param display The display to set.
    */
    public void setDisplay(String display) {
    this.display = display;
    }
    /**
    * @return Returns the name.
    */
    public String getName() {
    return name;
    }
    /**
    * @param name The name to set.
    */
    public void setName(String name) {
    this.name = name;
    }
    }

    所有測(cè)試使用的bean,如果未有說明,均使用SampleObject.

    所有測(cè)試使用的bean,如果未有說明,均使用SampleObject.
    BeanUtils.cloneBean(java.lang.object bean)

    為 bean創(chuàng)建一個(gè)clone對(duì)象,方法返回類型為Object.注意bean即使沒有實(shí)現(xiàn)java.lang.Cloneable接口,此方法依然有效. 此方法的實(shí)現(xiàn)機(jī)制建立在bean提供的一系列的getters和setters的基礎(chǔ)之上.此方法的正常使用代碼非常簡(jiǎn)單,故略掉.


    下 面討論下如果bean沒有提供getters和setters,會(huì)出現(xiàn)什么情況,很明顯如果將其中的一對(duì)getter和setter注釋掉,如 getDisplay()和setDisplay(),那么結(jié)果是根本不會(huì)針對(duì)display這個(gè)成員變量進(jìn)行復(fù)制;另外,如果將 setDisplay()的訪問限定符號(hào)設(shè)置為private的話,結(jié)果也是一樣的,成員變量-display在clone的過程中不會(huì)被復(fù)制.注意上面 討論的兩種情況,在運(yùn)行時(shí)不會(huì)拋出任何的exception.對(duì)于不拋出exception的問題,我也感到非常迷惑,因?yàn)榇朔椒ǖ膉avadoc上明明 指出當(dāng)不能訪問bean上的Accessor或不存在accessor時(shí),應(yīng)該拋出java.lang.IllegalAccessException或 java.lang.NotSuchMethodException.為了再次確認(rèn),我將SampleObject中的所有g(shù)etter和setter都 注釋掉了,結(jié)果依然一樣,看來要看下源碼了.

    BeanUtils.copyProperties(java.lang.Object dest, java.lang.Object orig)

    一 個(gè)bean class有兩個(gè)實(shí)例:orig和dest,將orig中的成員變量的值復(fù)制給dest,即將已經(jīng)存在的dest變?yōu)閛rig的副本.與 BeanUtils.cloneBean(java.lang.object bean)的區(qū)別就在于是不是需要?jiǎng)?chuàng)建新的實(shí)例了.同樣正常使用代碼非常簡(jiǎn)單,這里也略掉.
    如果bean class中沒有提供或是不完全提供getters和setters,結(jié)果如同在BeanUtils.cloneBean(java.lang.object bean)部分中的討論結(jié)果一樣.
    另 外,我曾經(jīng)這樣想,如果有兩個(gè)bean class,他們之間沒有任何關(guān)系,只是在成員變量的命名上有重疊(以SampleObject為例,如果我們有另外的bean class--AnotherSampleObject,也包含了成員變量display,name和num),他們之間是否可以利用 BeanUtils.copyProperties(java.lang.Object dest, java.lang.Object orig)進(jìn)行復(fù)制呢?(這個(gè)想法來自于<Struts in action>中formBean章節(jié)中關(guān)于formBean與valueObject的討論)答案是可以的,該方法會(huì)復(fù)制名稱完全一樣的成員變 量,即使成員變量的類型不同也會(huì)自動(dòng)進(jìn)行轉(zhuǎn)換的(我在AnotherSampleObject中將num的類型定義為Double,而 SampleObject中的num為int),感覺真的是很神奇.回頭再去看看javadoc,發(fā)現(xiàn)這個(gè)方法原本就是如此設(shè)計(jì)的,原文如下:
    Copy property values from the origin bean to the destination bean for all cases where the property names are the same.
    其中for all cases where the property names are the same正是很好的明證,以后可以放心大膽的使用了.
    ps:又對(duì)javadoc的重要性進(jìn)行重新認(rèn)識(shí),同時(shí)認(rèn)識(shí)到自己的英文是那么的爛.

    BeanUtils.copyProperty(java.lang.Object bean,java.lang.String name,java.lang.Object value)

    這個(gè)方法簡(jiǎn)單的說就是將bean中的成員變量name賦值為value.使用方法如下:
    SampleObject sample = new SampleObject();
    BeanUtils.copyProperty(sample,"num",new Integer(10));

    如果成員變量為數(shù)組,如何為數(shù)據(jù)內(nèi)的成員賦值呢?apache的java doc上說的很明白,就是要提供一個(gè)包含索引參數(shù)的setter,所以要將以下代碼加到SampleObject的源代碼中.
    /**
    * set word with against
    * @param index
    * @param word
    */
    public void setWords(int index,char word){
    this.words[index] = word;
    }

    如果我們要為SampleObject中的words[2]賦值為S,那么代碼如下:
    BeanUtils.copyProperty(a,"words[2]","S");

    如果成員變量為Map,如何為Map內(nèi)指定key賦值呢?同上面講的數(shù)組的方式一樣,就是要提供一個(gè)包含key參數(shù)的setter,在SampleObject中添加如下代碼:
    /**
    * set map with key
    * @param key
    * @param value
    */
    public void setMap(Object key,Object value){
    this.map.put(key,value);
    }

    如果我們要將SampleObject.map中home對(duì)應(yīng)值改為remote,那么代碼如下:
    BeanUtils.copyProperty(a,"map(home)","remote");

    最后說下如何為嵌套屬性的賦值,(所謂嵌套屬性就是beanA中一個(gè)成員變量是另外一個(gè)beanB,那么beanB中的屬性就叫做beanA的嵌套屬性了.),用法如下:
    BeanUtils.copyProperty(a,"sample.display","second one");

    BeanUtils.setProperty(java.lang.Object bean,java.lang.String name,java.lang.Object value)

    這 個(gè)方法讓我郁悶了一會(huì),因?yàn)樗峁┑墓δ芘c上面說的BeanUtils.copyProperty(java.lang.Object bean,java.lang.String name,java.lang.Object value)完全一致,apache的hero們沒理由為同一功能提供兩種展示方法啊,后來我看了 apache.commons.beanutils.BeanUtilsBean中的javadoc,才明白了一點(diǎn)點(diǎn).如果我們只是為bean的屬性賦值 的話,使用copyProperty()就可以了;而setProperty()方法是實(shí)現(xiàn)BeanUtils.populate()(后面會(huì)說到)機(jī)制 的基礎(chǔ),也就是說如果我們需要自定義實(shí)現(xiàn)populate()方法,那么我們可以override setProperty()方法.
    所以,做為一般的日常使用,setProperty()方法是不推薦使用的.

    BeanUtils.populate(java.lang.Object bean, java.util.Map properties)

    使 用一個(gè)map為bean賦值,該map中的key的名稱與bean中的成員變量名稱相對(duì)應(yīng).注意:只有在key和成員變量名稱完全對(duì)應(yīng)的時(shí) 候,populate機(jī)制才發(fā)生作用;但是在數(shù)量上沒有任何要求,如map中的key如果是成員變量名稱的子集,那么成員變量中有的而map中不包含的項(xiàng) 將會(huì)保留默認(rèn)值;同樣,如果成員變量是map中key的子集,那么多余的key不會(huì)對(duì)populate的結(jié)果產(chǎn)生任何影響.恩,結(jié)果就是populate 只針對(duì)map中key名稱集合與bean中成員變量名稱集合的交集產(chǎn)生作用.(很饒口啊)
    正常用法很簡(jiǎn)單,這里略掉.
    同樣,這個(gè)方法也支持對(duì)數(shù)組中單個(gè)元素,map中單個(gè)元素和嵌套屬性的賦值,具體做法和copyProperty()方法類似,具體如下:
    values.put("words[1]","U");
    values.put("map(home)","remote");
    values.put("sample.display",new Double(5.0));

    注意:apache的javadoc中,明確指明這個(gè)方法是為解析http請(qǐng)求參數(shù)特別定義和使用的,在正常的使用中不推薦使用.他們推薦使用BeanUtils.copyProperties()方法.(struts中的FormBean應(yīng)該是用這個(gè)方法裝配的)

    BeanUtils.getArrayProperty(java.lang.Object bean,java.lang.String name)

    獲取bean中數(shù)組成員變量(屬性)的值.
    沒什么好說的,用法很簡(jiǎn)單,略.
    還 是要說一句,如果我們指定的name不是數(shù)組類型的成員變量,結(jié)果會(huì)如何?會(huì)不會(huì)拋出類型錯(cuò)誤的exception呢?回答是不會(huì),仍然會(huì)返回一個(gè) String的數(shù)組,數(shù)組的第一項(xiàng)就是name對(duì)應(yīng)的值(如果不是String類型的話,JVM會(huì)自動(dòng)的調(diào)用toString()方法的).

    BeanUtils.getIndexedProperty(java.lang.Object bean,java.lang.String name)
    BeanUtils.getIndexedProperty(java.lang.Object bean,java.lang.String name,int index)

    這兩個(gè)方法都是獲取數(shù)組成員變量(屬性)中的單一元素值的方法.比如,我想得到SampleObject中words[1]的值,用法如下:
    BeanUtils.getIndexedProperty(sampleOjbectInstance,"words[1]");
    BeanUtils.getIndexedProperty(sampleOjbectInstance,"words",1);

    BeanUtils.getMappedProperty(java.lang.Object bean,java.lang.String name)
    BeanUtils.getMappedProperty(java.lang.Object bean,java.lang.String name,java.lang.String key)

    這兩個(gè)方法是獲取map成員變量中單一元素值的方法,用法與getIndexedProperty()方法相似,如我想得到SampleObject中map中home對(duì)應(yīng)的值,用法如下:
    BeanUtils.getMappedProperty(sampleOjbectInstance,map(home));
    BeanUtils.getMappedProperty(sampleOjbectInstance,map,"home");

    BeanUtils.getNestedProperty(java.lang.Object bean,java.lang.String name)

    獲取嵌套屬性值的方法,如我想得到SampleOjbect中成員變量sample中的display的值,用法如下:
    BeanUtils.getNestedProperty(sampleOjbectInstance,"sample.display");

    BeanUtils.getSimpleProperty(java.lang.Object bean, java.lang.String name)
    BeanUtils.getProperty(java.lang.Object bean, java.lang.String name)

    獲 取屬性值的方法.api已經(jīng)很清楚了,我唯一的問題是這個(gè)simple是什么意思.javadoc只是說了getProperty()方法中的name參 數(shù)可以為普通屬性名稱,數(shù)組屬性名稱或嵌套屬性名稱的一種,而getSimpleProperty()方法中的name參數(shù)應(yīng)該為普通屬性名稱了.我的想 法是通過對(duì)方法簽名的不同,讓developers可以顯示區(qū)別對(duì)待普通屬性,數(shù)組屬性,map屬性和嵌套屬性.
    ps:具體有何區(qū)別,看來要仔細(xì)看看源代碼了.

    BeanUtils.describe(java.lang.Object bean)

    將一個(gè)bean以map的形式展示.(這個(gè)方法和populate()是我夢(mèng)想中的雙手劍)
    但是使用這個(gè)方法得到的結(jié)果有點(diǎn)令我失望,以SampleObject為例,代碼片段如下:
    SampleObject a = new SampleObject();
    a.setDisplay("first one");
    a.setName("A");
    a.setNum(5);
    a.setWords("goto".toCharArray());
    SampleObjectA b = new SampleObjectA();
    b.setDisplay("nested property");
    b.setNum(new Double(2.0));
    b.setName("sampleA");
    a.setSample(b);
    try {
    Map descMap = BeanUtils.describe(a);
    System.out.println(descMap);
    }
    ......

    運(yùn)行結(jié)果如下:
    {num=5, display=first one, class=class beanutil.SampleObject, words=g, tag=false, sample=beanutil.SampleObjectA@be2358, map={port=80, home=localhost}, name=A}

    • 首先可以看出,除了輸出SampleObject中定義的key-value外,還會(huì)包含class=class beanutil.SampleObject這一項(xiàng),我想這是為了通過獲得的map我們可以知道原來的bean的具體類型;
    • 其 次,作為數(shù)組成員變量(屬性)的words,在map中只包含了首個(gè)元素,而map類型的成員變量的輸出結(jié)果到是非常令人滿意.為什么明明長(zhǎng)度為4的 words數(shù)組現(xiàn)在輸出只有一個(gè)字符呢,我又進(jìn)行了debug,并監(jiān)控了words變量,發(fā)現(xiàn)在返回的descMap中,words對(duì)應(yīng)的值的類型為 String,長(zhǎng)度為1.
      ps:不知道是不是我使用錯(cuò)誤,真不知道為什么會(huì)這樣.
    • 最后,嵌套屬性不會(huì)逐一進(jìn)行輸出的,除非你override了toString()方法.
    與apache.commons.beanutils.BeanUtilsBean的關(guān)系

    apache.commons.beanutils.BeanUtils 中每個(gè)方法是通過apache.commons.beanutils.BeanUtilsBean實(shí)現(xiàn) 的,apache.commons.beanutils.BeanUtils中靜態(tài)方法功能是默認(rèn)方法,也就是最基本和最普通的,如果需要更復(fù)雜的功能實(shí) 現(xiàn)的話,則需要使用apache.commons.beanutils.BeanUtilsBean中的方 法.apache.commons.beanutils.BeanUtilsBean可以在不同的緩沖區(qū)內(nèi)存在不同的實(shí)例,從而可以提供不同的服務(wù),主要 是converter的不同.通過這個(gè)機(jī)制可以為不同的用戶提供本地化的支持(我想這個(gè)在internet application上經(jīng)常要用到吧).我想這也是為什么apache.commons.beanutils.BeanUtilsBean不是 interface而是class的原因.

    總結(jié)
    BeanUtils是利用java的反射和自醒機(jī)制來讀寫javabean的屬性的.

    posted on 2009-08-07 16:45 MichaelLee 閱讀(7100) 評(píng)論(0)  編輯  收藏 所屬分類: Hibernater

    <2009年8月>
    2627282930311
    2345678
    9101112131415
    16171819202122
    23242526272829
    303112345

    導(dǎo)航

    統(tǒng)計(jì)

    公告

    ====Michael Lee====
    =Java Sofware Engineer=
    =Work @ Beijing=
    ---再煩,也別忘微笑;再急,也要注意語氣;再苦,也別忘堅(jiān)持;再累,也要愛自己!---
    ---低調(diào)做人,你會(huì)一次比一次穩(wěn)健;高調(diào)做事,你會(huì)一次比一次優(yōu)秀---
    ---成功的時(shí)候不要忘記過去;失敗的時(shí)候不要忘記還有未來---

    常用鏈接

    留言簿(2)

    隨筆分類

    隨筆檔案

    文章分類

    文章檔案

    搜索

    最新評(píng)論

    閱讀排行榜

    評(píng)論排行榜

    主站蜘蛛池模板: 久久久久久亚洲精品影院| 黄色a三级三级三级免费看| 大地资源免费更新在线播放| 国产成人人综合亚洲欧美丁香花| 亚洲精品无码永久在线观看| 久久永久免费人妻精品| 亚洲一区免费在线观看| 内射无码专区久久亚洲| 亚洲黄色免费观看| 曰批免费视频播放在线看片二| 久久久久久a亚洲欧洲aⅴ| 我要看免费的毛片| 成人国产精品免费视频| 亚洲三级在线播放| 日韩亚洲变态另类中文| 成人特黄a级毛片免费视频| 免费无码又爽又刺激网站直播| 久久亚洲精品国产亚洲老地址 | 偷自拍亚洲视频在线观看| 久久综合日韩亚洲精品色| 免费无码一区二区三区蜜桃大| 国产免费一区二区三区不卡| 亚洲国产成人AV网站| 亚洲日本一区二区三区| 亚洲欧洲日产国码一级毛片| 黄页网站免费在线观看| 三级黄色片免费看| 日韩在线视精品在亚洲| 亚洲成a人片在线观看中文app| 亚洲无码在线播放| 免费a在线观看播放| 日本XXX黄区免费看| 毛片在线播放免费观看| 成人午夜免费视频| 亚洲精品无码日韩国产不卡av| 亚洲美女视频一区| 亚洲中文字幕无码中文字在线| 国产青草视频在线观看免费影院| 国产精品免费观看| 午夜爽爽爽男女免费观看影院| 国产精品极品美女自在线观看免费|