1. 程式人生 > >常用jar包之commons-beanutils使用

常用jar包之commons-beanutils使用

Jakarta Commons專案提供了相當豐富的API,我們之前瞭解到的Commons Lang只是眾多API的比較核心的一小部分而已。Commons下面還有相當數量的子專案,用於解決各種各樣不同方向的實際問題,BeanUtils就是其中的一個,用於處理JavaBeans。它利用Java的反射機制,從動態的生成對bean的getter和setter的呼叫程式碼,到模擬建立一個動態的bean,等等。這個包看似簡單,卻是很多開源專案的基石:如在著名的Struts和Spring Framework中,我們都能找到BeanUtils的影子。大家猜猜看,有哪位名人是BeanUtils的作者之一?沒錯,就是Struts的創始人Craig McClanahan。

BeanUtils最核心的好處在於:我們在編碼時,並不需要知道我們處理的JavaBeans具體是什麼型別,有哪些屬性,這些資訊是可以動態獲取的,甚至我們都可以不必去關心事實上是否存在這樣一個具體的JavaBean類。我們只需要知道有一個JavaBean的例項,我們需要從中取得某個屬性,設定某個屬性的值,或者僅僅是需要一個屬性表。要做到這些,依靠Sun提供的JavaBean規範似乎找不到一個很直接的方式,除非硬編碼,將getXxxx()和setXxxx()直接寫進我們的程式。但是這樣就大大增加了程式碼的複雜度、耦合性和維護成本。還好Commons BeanUtils對這個問題提供了一種優雅的解決方案。

我們有兩種途徑獲取Commons BeanUtils的binary:

1- 從Struts、Spring或者任何依賴BeanUtils的開源產品的發行包中找到相應的jar檔案;

Commons BeanUtils的原始碼下載地址:

Commons BeanUtils一共包括如下5個包:

org.apache.commons.beanutils – 核心包,定義一組Utils類和需要用到的介面規範

org.apache.commons.beanutils.converters – 轉換String到需要型別的類,實現Converter介面

org.apache.commons.beanutils.locale – beanutils的locale敏感版本

org.apache.commons.beanutils.locale.converters – converters的locale敏感版本

org.apache.commons.collections – beanutils使用到的Collection類

其中需要我們特別關注的是這個org.apache.commons.beanutils包,其他包都是起輔助作用的。接下來我們就來看看如何使用beanutils包

     1.PropertyUtils


  它支援三種類型的屬性值-Simple,Indexed,Mapped
  Simple屬性訪問方法
  PropertyUtils.getSimpleProperty(Object bean, String name)
  PropertyUtils.setSimpleProperty(Object bean, String name, Object value)


  實現程式碼:
   Employee employee = ...;
   String firstName = (String)
   PropertyUtils.getSimpleProperty(employee, "firstName");
   String lastName = (String)
   PropertyUtils.getSimpleProperty(employee, "lastName");
   ... manipulate the values ...
   PropertyUtils.setSimpleProperty(employee, "firstName", firstName);
   PropertyUtils.setSimpleProperty(employee, "lastName", lastName);


  Indexed屬性訪問方法
  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)


  實現程式碼:
  Employee employee = ...;
   int index = ...;
   String name = "subordinate[" + index + "]";
   Employee subordinate = (Employee)
   PropertyUtils.getIndexedProperty(employee, name);//根據value取得屬性
   Employee employee = ...;
   int index = ...;
   Employee subordinate = (Employee)
   PropertyUtils.getIndexedProperty(employee, "subordinate", index);//根據索引
  值取的屬性值


  Mapped屬性訪問方法
  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)
  實現程式碼:
  Employee employee = ...;
   Address address = ...;
   PropertyUtils.setMappedProperty(employee, "address(home)", address);//根據陣列
  //內的值來去的相應的屬性值
   Employee employee = ...;
   Address address = ...;
   PropertyUtils.setMappedProperty(employee, "address", "home", address);


  Nested屬性訪問方法//Nested的意思是引數中包含元件
  PropertyUtils.getNestedProperty(Object bean, String name)
  PropertyUtils.setNestedProperty(Object bean, String name, Object value)
  實現程式碼:
  String city = (String) PropertyUtils.getNestedProperty(employee,
  "address(home).city");


  2.BeanUtils.DynaBean and BeanUtils.DynaClass 介面介紹
  DynaBean必須有一個bean來實現這個介面,DynaClass必有一個bean的屬性集來實現


  BasicDynaBean and BasicDynaClass - 基本的 Dynamic 型別
  基本的API:
  BasicDynaClass(java.lang.String name, java.lang.Class dynaBeanClass, DynaProperty[] properties)
  BasicDynaBean(DynaClass dynaClass)
  我們定義一下基本的程式碼:
  //定義動態屬性集
  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
  API:
  ResultSetDynaClass(java.sql.ResultSet resultSet)
  ResultSetDynaClass(java.sql.ResultSet resultSet, boolean lowerCase)
  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()) {
  //利用動態bean進行輸出
   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
  API:
  RowSetDynaClass(java.sql.ResultSet resultSet)
  RowSetDynaClass(java.sql.ResultSet resultSet, boolean lowerCase)
   Connection conn = ...; // 從緩衝池取得連線
   Statement stmt = conn.createStatement();
   ResultSet rs = stmt.executeQuery("SELECT ...");
   RowSetDynaClass rsdc = new RowSetDynaClass(rs);
   rs.close();
   stmt.close();
   ...; //關閉連線返回緩衝池
   List rows = rsdc.getRows();
   ...; // 處理得到的行


  3.BeanUtils.ConvertUtils 介紹
  這個包主要用來轉換從request傳遞過來的函式
  主要函式:
  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)
  實現例子:
   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);//用ConvertUtils進行轉換
  目前支援的轉換型別:
  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