- 追加された行はこの色です。
- 削除された行はこの色です。
#author("2018-04-12T14:38:58+00:00","default:haikikyou","haikikyou")
#author("2018-04-13T14:26:18+00:00","default:haikikyou","haikikyou")
[[Java]]
#contents
* Commons BeanUtils [#qfbab3fe]
- JavaBean規約に沿ったオブジェクト操作を容易にしてくれる様々な機能を提供してくれるライブラリ
- Apache Commonsプロジェクトの1つ
* インストール [#h820eee5]
** maven [#ef1eb58a]
mavenでインストールする場合は、以下のような指定となる。
#geshi(xml,number){{{
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
<version>1.9.3</version>
</dependency>
}}}
&label(warn){参考};[[MvnRepository >https://mvnrepository.com/artifact/commons-beanutils/commons-beanutils]] - &size(11){&color(gray){on https://mvnrepository.com/artifact/commons-beanutils/commons-beanutils};};
** 個別にjarを設置する [#jee4532c]
jarファイルを個別にインストールする場合、1.9.3では以下のようになる。
- commons-beanutils-1.9.3.jar
- commons-logging-1.2.jar
- commons-collections-3.2.2.jar
commons-loggingやcommons-collectionsが必要となる。commons-collectionsは、4からgroupとartifactが変更されているので注意する。1.9.3では、commons-collectionsを利用する。
* DynaBean、DynaClass、DynaProperty [#w84b12ca]
* 例 [#fc4dbea5]
これらのクラスは、BeanのようなJavaオブジェクトを表現するためのベースクラス達である。~
それぞれ以下の役割を持つ。
- DynaBean
-- リストやマップのようなプロパティを操作可能とするクラスである。~
DynaBeanにプロパティを設定すると、DynaClassにプロパティ情報が伝えられる。~
POJOのようなオブジェクトは、WrapDynaBeanというクラスでラップされ扱われる。
- DynaClass
-- DynaBeanのプロパティ情報を保持するクラスである。
- DynaProperty
-- DynaBeanの個々のプロパティ表現である。
* LazyDynaList [#ie107681]
このクラスは、ArrayList<Object>を継承したクラスであり、主に以下の機能を有する。
+ サイズを自動拡張してくれ、指定のpositionに要素を挿入することができる。
+ 配列やCollectionをLazyDynaListに挿入する。指定の位置にCollectionの要素を挿入することができる。
** LazyDynaListの要素の型 [#k5baaf0c]
LazyDynaListに格納されるオブジェクトは、DynaBeanクラスとして管理される。~
追加されるオブジェクトの型によって異なる。
|~型|~対応する型|h
|Map|LazyDynaMap|
|POJO|WrapDynaBean|
|DynaBean|DynaBean|
要素タイプの指定がない場合は、LazyDynaBeantとLazyDynaClassが使われる。
*** Map型を扱う [#j1d9cf04]
#geshi(java){{{
/*
* 1. Mapの配列を扱う
*/
System.out.println("[1]");
// Mapの配列を作成
HashMap[] myMapArray = new HashMap[1];
myMapArray[0] = new HashMap<String, Object>();
myMapArray[0].put("name", "mapValue");
// Mapの配列を追加して初期化
LazyDynaList lazyList = new LazyDynaList(myMapArray);
// リサイズ時に失敗しないように要素のタイプを指定しておく。
// この指定がないと、すでに要素がある状態でelementTypeを設定しようとしてエラーとなる。(この時点では、まだelementTypeがない)
// DynaClassはLazyDynaMapであり、このDynaClassはMap型のオブジェクトを生成して返す。
lazyList.setElementType(HashMap.class);
//lazyList.setElementType(TreeMap.class);
// サイズ拡張で、新しい要素オブジェクトを得る、LazyDynaMap型である。
DynaBean newElement = (DynaBean) lazyList.get(lazyList.size());
newElement.set("name", "arrayValue");
DynaBean element = (DynaBean) lazyList.get(lazyList.size() - 1);
System.out.println(element.get("name"));
Map<String, String>[] maps = (Map<String, String>[]) lazyList.toArray();
Arrays.stream(maps).forEach(m -> {
m.forEach((k, v) -> System.out.println(k + ":" + v));
});
/*
* 2. Listを扱う
*/
System.out.println("[2]");
List<Map<String, String>> myList = new ArrayList<>();
lazyList = new LazyDynaList(myList);
// サイズ拡張, elementTypeはLazyDynaBeanである
newElement = (DynaBean) lazyList.get(lazyList.size());
newElement.set("name", "listValue");
element = (DynaBean) lazyList.get(lazyList.size() - 1);
// この時点でelementTypeはLazyDynaBeanとなっている。
System.out.println(element.get("name"));
// elementTypeのオブジェクトを追加する。
LazyDynaBean newBean = new LazyDynaBean();
newBean.set("name", "elementValue");
lazyList.add(newBean);
element = (DynaBean) lazyList.get(lazyList.size() - 1);
System.out.println(element.get("name"));
// LazyDynaBeanでない型の追加はエラーとなる。
HashMap<String, Object> map = new HashMap<String, Object>();
lazyList.add(map);
// Exception in thread "main" java.lang.IllegalArgumentException: Element Type class java.util.HashMap doesn't match other elements class org.apache.commons.beanutils.LazyDynaBean
/*
[1]
arrayValue
name:mapValue
name:arrayValue
[2]
listValue
elementValue
Exception in thread "main" java.lang.IllegalArgumentException: Element Type class java.util.HashMap doesn't match other elements class org.apache.commons.beanutils.LazyDynaBean
at org.apache.commons.beanutils.LazyDynaList.transform(LazyDynaList.java:689)
at org.apache.commons.beanutils.LazyDynaList.add(LazyDynaList.java:288)
at cb.LazyDynaListSample.main(LazyDynaListSample.java:122)
*/
}}}
この機能は、例えばHTMLフォームから要素の配列を受け取り、Listにセットするような状況で役に立つ。~
例えば以下のような使い方ができるだろう。
** HTMLフォーム配列を受け取る例 [#y63d732c]
#geshi(java,number){{{
package cb;
import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;
import java.util.HashMap;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.DynaBean;
import org.apache.commons.beanutils.LazyDynaList;
import org.apache.commons.beanutils.WrapDynaBean;
public class LazyDynaListTest {
public static class MyBean implements Serializable {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return String.format("name:%s, age:%d", name, age);
}
}
public static class MyForm {
LazyDynaList list = new LazyDynaList(MyBean.class);
public LazyDynaList getList() {
return list;
}
public void setList(LazyDynaList list) {
this.list = list;
}
public void bind(HashMap<String, Object> parameters)
throws IllegalAccessException, InvocationTargetException {
BeanUtils.populate(this, parameters);
}
}
public static void main(String[] args) throws Exception {
LazyDynaList list = new LazyDynaList();
MyForm form = new MyForm();
MyBean bean = new MyBean();
HashMap<String, Object> parameters = new HashMap<String, Object>() {
{
put("list[0].name", "hoge");
put("list[0].age", 100);
// beanにフィル
BeanUtils.populate(bean, new HashMap<String, Object>() {
{
put("name", "hoge");
put("age", 100);
put("list[1].name", "foo");
put("list[1].age", 200);
}
});
};
// OK, サイズは自動拡張
// [0]=LazyDynaBean, [0]=LazyDynaBean, [0]=WrapBean
list.set(2, bean);
form.bind(parameters);
// DynaBeanとして取得
Arrays.stream(list.toArray(new DynaBean[0]))
// POJOは、WrapDynaBeanとして格納されている。
Arrays.stream(form.getList().toArray(new WrapDynaBean[0]))
.forEach(v -> {
// instanceメンバにMyBeanのインスタンスがある。
MyBean bean = (MyBean)v.getInstance();
System.out.println(String.format("name: %s, age: %d",
bean.getName(), bean.getAge()));
// DynaBeanからアクセスする場合は、プロパティ名を指定すれば良い。
System.out.println(String.format("name: %s, age: %d",
v.get("name"), v.get("age")));
});
}
}
/*
name: null, age: null
name: null, age: null
name: hoge, age: 100
*/
}}}
&label(warn){参考}; Maven Repository
- [[commons-beanutils>https://mvnrepository.com/artifact/commons-beanutils/commons-beanutils]] - &size(11){&color(gray){on https://mvnrepository.com/artifact/commons-beanutils/commons-beanutils};};
- [[commons-logging>https://mvnrepository.com/artifact/commons-logging/commons-logging]] - &size(11){&color(gray){on https://mvnrepository.com/artifact/commons-logging/commons-logging};};
- [[commons-collections>https://mvnrepository.com/artifact/commons-collections/commons-collections]] - &size(11){&color(gray){on https://mvnrepository.com/artifact/commons-collections/commons-collections};};
* 参考リンク [#e0f0c93f]
- http://commons.apache.org/proper/commons-beanutils/