JavaWorld@TW the best professional Java site in Taiwan sun training logo
      註冊 | 登入 | 全文檢索 | 排行榜  

» JavaWorld@TW » Java 文章和新聞 » Java電子報  

按列印兼容模式列印這個話題 列印話題    把這個話題寄給朋友 寄給朋友   
reply to topicthreaded modego to previous topicgo to next topic
本主題所含的標籤
無標籤
作者 OpenSource-030412-第五期-Jakarta Commons BeanUtils
browser

戀香

版主

發文: 3570
積分: 1
於 2003-06-18 20:04 user profilesend a private message to usersend email to browserreply to postreply to postsearch all posts byselect and copy to clipboard. 
ie only, sorry for netscape users:-)add this post to my favorite list


在 bbs 上, popcorny 曾經講到 jakarta commons 下面有許多已經有許多開發好的好用元件 我沒記錯的話, 應該是討論到 Net Ftp, 但是你們連結到 Commons 的網頁時候, 一定會嚇 了一跳, 哇, 怎麼會有這麼多已經在開發的元件, 還有正在 SandBox ( 研發中 ) 的專案, 所 以如何善用之, 就變成我在連續幾週, 都會討論的課題 !!

目前 Commons 簡介
目前已經開發有 release 出來的版本有 BeanUtils, Betwixt, CLI, Collections, DBCP, Digester, Discovery, EL, FileUpload, HttpClient, Jelly, Jexl, JXPath, Lang, Latka, Logging, Modeler, Net, Pool, Validator 等等

每個版本都不太一樣, 隨時都有更新的可能, 至於還沒有 release 出來正式的版本, 有一些專案, 可能也正在使用了 !! 也是有可能因為其他專案做出來的一些元件, 可以抽出來共用的, 例如目前 struts 用的Resources ( Resource bundle component ) , 也被列入 SandBox 研發中, 準備 release 更符合所有專案的元件.

jakarta 為何要有 commons 這個 project 出現, 就是希望大家不用重複開發一樣的元件, 達到 reusable 的目的 !! 而且他們都有容易使用的特性, 也是各個 jakarta committer 大大們的精華傑作, 因此, 絕對不能錯過這一個 open source project !! 各位親愛的 java 同胞們 .................

BeanUtils 介紹
當我在選擇要先介紹哪一個元件, 實在猶豫了很久, 因為每一個實在都是精華, 久久無法做出決定, 所以呢, 只好按照是否 release 再按照字母的先後,做一個排序, 希望大家明白 ....

所謂 BeanUtils 為何要開發呢, 每個工程師或許在寫 JavaBean 的時候, 都會乖乖地去寫 getters 和 setters, 就是 getXXX() 及 setXXX() methods, 但是當你的 object 是動態產生的, 也許是用檔案, 也許是其他原因, 那你該如何去存取資料呢 !!

幾個例子你可能會用到 BeanUtils, 當然, 這是已經存在的專案了

BSF : Script Language 和 Java Object Model 之間
Velocity/JSP : 使用 template 建立相似的網頁
jakarta taglibs/ Struts / Cocoon : 建立自己特殊的 Tag Libraries for JSP 或 XSP
ant build.xml / tomcat server.xml : XML-based 的 設定檔案 ( configuration resources )
你大可以使用 java api 中的 java.lang.reflect 及 java.beans 來達到這些資料交換 ~~ 不過呢, 難度有點高 =.="" ,但是, BeanUtils 將會減低你開發的時間 !!

目前最新的版本為 1.6.1 (2003/2/18 released),
下載位置為 Binary & Source

BeanUtils API 介紹
BeanUtils 的 Java API 主要的 package 總共四項

org.apache.commons.beanutils
org.apache.commons.beanutils.converters
org.apache.commons.beanutils.locale
org.apache.commons.beanutils.locale.converters

其實除了第一項之外, 其他的都是後來版本才加上去的, converters 就是專門處理不同傳入的 object 該如何轉換, locale 呢, 就是為了國際化的處理, 所以重點我都會擺在第一項!!

而其中最常用到的 class 是 PropertyUtils 及 ConvertUtils 還有 DynaBeans( 有用 struts dynaform 的應該不陌生 )

BeanUtils.PropertyUtils 介紹
基本上, 我假設大家對 JavaBean 的開發都沒有問題, 就是 對 getters 及 setters 都了解是什麼. 先假設, Employee class

1
2
3
4
5
6
7
8
9
10
public class Employee {
        public Address getAddress(String type);
        public void setAddress(String type, Address address);
        public Employee getSubordinate(int index);
        public void setSubordinate(int index, Employee subordinate);
        public String getFirstName();
        public void setFirstName(String firstName);
        public String getLastName();
        public void setLastName(String lastName);
    }


在 PropertyUtils 中會區分為三種 method 狀態

Simple - 如果你是用到 primitive 語法, 如 int, String 或其他自行開發的 objects 等等, 只需要單一的物件就可以取得資料

PropertyUtils.getSimpleProperty(Object bean, String name)
PropertyUtils.setSimpleProperty(Object bean, String name, Object value)


1
2
3
4
5
6
    Employee employee = ...;
    String firstName = (String)PropertyUtils.getSimpleProperty(employee, "firstName");
    String lastName = (String)PropertyUtils.getSimpleProperty(employee, "lastName");
   .............
    PropertyUtils.setSimpleProperty(employee, "firstName", firstName);
    PropertyUtils.setSimpleProperty(employee, "lastName", lastName);

  
Indexed - 如果你是用到 Collection 或 List 實作出來的 objects , 只需要使用一個 index 數值就可以取得資料的型態

PropertyUtils.getIndexedProperty(Object bean, String name)
PropertyUtils.getIndexedProperty(Object bean, String name, int index)
PropertyUtils.setIndexedProperty(Object bean, String name, Object value)
PropertyUtils.setIndexedProperty(Object bean, String name, int index, Object value)


1
2
3
4
5
6
7
8
    Employee employee = ...;
    int index = ...;
    String name = "subordinate[" + index + "]";
    Employee subordinate = (Employee)PropertyUtils.getIndexedProperty(employee, name);
 
    Employee employee = ...;
    int index = ...;
    Employee subordinate = (Employee)PropertyUtils.getIndexedProperty(employee, "subordinate", index);

  
Mapped - 如果你是用到 Map 延伸出來的 objects , 只需要使用一個 key 值就可以取得資料

PropertyUtils.getMappedProperty(Object bean, String name)
PropertyUtils.getMappedProperty(Object bean, String name, String key)
PropertyUtils.setMappedProperty(Object bean, String name, Object value)
PropertyUtils.setMappedProperty(Object bean, String name, String key, Object value)


1
2
3
4
5
6
7
    Employee employee = ...;
    Address address = ...;
    PropertyUtils.setMappedProperty(employee, "address(home)", address);
 
    Employee employee = ...;
    Address address = ...;
    PropertyUtils.setMappedProperty(employee, "address", "home", address);

  
但是如果你是巢狀(nested)的資料結構, 你該如何取得你要的資料呢

PropertyUtils.getNestedProperty(Object bean, String name)
PropertyUtils.setNestedProperty(Object bean, String name, Object value)


你只需要簡單地使用 ".", 就可以得到你要的資料了

1
    String city = (String)PropertyUtils.getNestedProperty(employee, "address(home).city");


千萬要記住, BeanUtils 是要讓你隨心所欲使用, 所以呢 index , mapped 當然都可以這樣使用

1
2
    Employee employee = ...;
    String city = (String) PropertyUtils.getProperty(employee,"subordinate[3].address(home).city");


BeanUtils.DynaBean and BeanUtils.DynaClass 介紹
所有的 Dynamic JavaBean 都是實作 DynaBean 或 DynaClass 這兩個 interface, 也可能會用到 DynaProperty class 來存取 properties . 我們為何要用到 Dynamic JavaBean 呢, 例如, 你從資料庫撈出來的資料, 有時候可能是三個欄位, 有時候是四個欄位, 如果我們對於每個 Bean 都要去寫一個 class, 就會很累, 所以對於每一種 javabean 我們就設定他的屬性有哪些, 接著就可以使用 PropertyUtils 來將他的數值取出, 如此, 可以減少很多開發工時. 在 Struts 的課程中, 很多人問到我, 請問每一個 ActionForm 都必須寫成 java 檔嗎, 當然, 不需要的, 否則一個網頁一個 ActionForm ( 假設都不一樣 ), 那麼, 這麼浪費時間的工作, 為何還要使用 Struts 來作為 Framework 呢, 所以我們都是使用 org.apache.struts.action.DynaActionForm!!

MutableDynaClass ( since $1.5 ) 這是蠻新的一個 DynaClass, 是為了動態可以調整 properties !

BasicDynaBean and BasicDynaClass - 基本的 Dynamic 型態

BasicDynaClass(java.lang.String name, java.lang.Class dynaBeanClass, DynaProperty[] properties)
BasicDynaBean(DynaClass dynaClass)


1
2
3
4
5
6
7
8
9
10
11
12
13
    DynaProperty[] props = new DynaProperty[]{
        new DynaProperty("address", java.util.Map.class),
        new DynaProperty("subordinate", mypackage.Employee[].class),
        new DynaProperty("firstName", String.class),
        new DynaProperty("lastName",  String.class)
      };
    BasicDynaClass dynaClass = new BasicDynaClass("employee", null, props);
 
    DynaBean employee = dynaClass.newInstance();
    employee.set("address", new HashMap());
    employee.set("subordinate", new mypackage.Employee[0]);
    employee.set("firstName", "Fred");
    employee.set("lastName", "Flintstone");

  
ResultSetDynaClass (Wraps ResultSet in DynaBeans) - 使用 ResultSet 的 Dynamic JavaBean

ResultSetDynaClass(java.sql.ResultSet resultSet)
ResultSetDynaClass(java.sql.ResultSet resultSet, boolean lowerCase)


如果 lowerCase 設為 false , 回傳的資料欄位名將根據 JDBC 回傳的為準. default 為 true.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Connection conn = ...;
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("select account_id, name from customers");
Iterator rows = (new ResultSetDynaClass(rs)).iterator();
 
while (rows.hasNext()) {
     DynaBean row = (DynaBean) rows.next();
     System.out.println("Account number is " + 
                                 row.get("account_id") +
                                  " and name is " + row.get("name"));
}
 
rs.close();
stmt.close();

  
RowSetDynaClass (Disconnected ResultSet as DynaBeans) - 使用 RowSet 的 Dynamic JavaBean

RowSetDynaClass(java.sql.ResultSet resultSet)
RowSetDynaClass(java.sql.ResultSet resultSet, boolean lowerCase)


如果 lowerCase 設為 false , 回傳的資料欄位名將根據 JDBC 回傳的為準. default 為 true.

1
2
3
4
5
6
7
8
9
    Connection conn = ...;  // Acquire connection from pool
    Statement stmt = conn.createStatement();
    ResultSet rs = stmt.executeQuery("SELECT ...");
    RowSetDynaClass rsdc = new RowSetDynaClass(rs);
    rs.close();
    stmt.close();
    ...;                    // Return connection to pool
    List rows = rsdc.getRows();
    ...;                   // Process the rows as desired


  
WrapDynaBean and WrapDynaClass - 包裝過的 Dynamic JavaBean

如果你對於 DynaBean 的功能強大, 非常佩服的同時, 手邊的 JavaBean 又不能隨隨便便就不用 那你就把他包裝起來 ....

WrapDynaClass(java.lang.Class beanClass)
WrapDynaBean(java.lang.Object instance)
ConvertingWrapDynaBean(java.lang.Object instance)


1
2
3
    MyBean bean = ...;
    DynaBean wrapper = new WrapDynaBean(bean);
    String firstName = wrapper.get("firstName");

  
BeanUtils.ConvertUtils 介紹
在很多情況, 例如 struts framework 中, 就常常用到 request.getParameter 的參數, 需要轉換成 正確的資料型態, 所以 ConvertUtils 就是來處理這些動作.

ConvertUtils().convert(java.lang.Object value)
ConvertUtils().convert(java.lang.String[] values, java.lang.Class clazz)
ConvertUtils().convert(java.lang.String value, java.lang.Class clazz)


1
2
3
4
5
6
7
8
9
    HttpServletRequest request = ...;
    MyBean bean = ...;
    HashMap map = new HashMap();
    Enumeration names = request.getParameterNames();
    while (names.hasMoreElements()) {
      String name = (String) names.nextElement();
      map.put(name, request.getParameterValues(name));
    }
    BeanUtils.populate(bean, map);// it will use ConvertUtils for convertings


目前支援的型態有

sjava.lang.BigDecimal
java.lang.BigInteger
boolean and java.lang.Boolean
byte and java.lang.Byte
char and java.lang.Character
java.lang.Class
double and java.lang.Double
float and java.lang.Float
int and java.lang.Integer
long and java.lang.Long
short and java.lang.Short
java.lang.String
java.sql.Date
java.sql.Time
java.sql.Timestamp

也可以建立自己的 converter

1
2
3
4
   Converter myConverter =
    new org.apache.commons.beanutils.converter.IntegerConverter(); 
   ConvertUtils.register(myConverter, Integer.TYPE);    // Native type 
   ConvertUtils.register(myConverter, Integer.class);   // Wrapper class 

  
ps :部分內容屬於直接翻譯自 jakarta commons beanutils


vote up 0 vote down
browser edited on 2003-06-18 20:07
reply to postreply to post

» JavaWorld@TW »  Java 文章和新聞 » Java電子報

reply to topicthreaded modego to previous topicgo to next topic
  已讀文章
  新的文章
  被刪除的文章
Jump to the top of page

JavaWorld@TW


Powered by Powerful JuteForum® Version Jute 1.5.8
Copyright© 2002-2003 Rainman Zhu,Zua,Netboy,Scott. All Rights Reserved.