- PR -

BeanUtilsのdescribeメソッドについて

投稿者投稿内容
未記入
ベテラン
会議室デビュー日: 2005/02/24
投稿数: 55
投稿日時: 2005-12-12 10:22
BeanUtilsのdescribeメソッドで
全プロパティを取得する処理を行いたいのですが、
実行してみると配列のプロパティを取得することが出来ません。

下記メソッドを実行すると全プロパティを
出力するような処理をしたいのですが、
修正すべきところなど教えていただけないでしょうか?

コード:
	static private void log(Object bean) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
		Map map = BeanUtils.describe(bean);
		Set set = map.keySet();
		Iterator itr = set.iterator();
		for (Object k = itr.next(); itr.hasNext(); k = itr.next()) {
			Object v = map.get(k);
			if (v instanceof Object[]) { // ※ここが実行されない
				Object[] a = (Object[]) v;
				for (int i = 0, end = a.length; i < end; i++) {
					log(a[i]);
				}
			} else {
				System.out.println("name="+k);
				System.out.println("value="+v);
			}
		}
	}



ふーばー
大ベテラン
会議室デビュー日: 2003/06/05
投稿数: 163
投稿日時: 2005-12-12 11:35
引用:

未記入さんの書き込み (2005-12-12 10:22) より:
BeanUtilsのdescribeメソッドで
全プロパティを取得する処理を行いたいのですが、
実行してみると配列のプロパティを取得することが出来ません。



itr.next() の戻り値で配列のプロパティが一切返されないのか、
if 文による配列プロパティかどうかの判断がまちがっているのか、
どちらですか?

前者は10個プロパティがあれば、10回ループしているかで判断できる
はずです。後者は、そのプロパティの型は何になっていますか?
未記入
ベテラン
会議室デビュー日: 2005/02/24
投稿数: 55
投稿日時: 2005-12-12 13:20
引用:

ふーばーさんの書き込み (2005-12-12 11:35) より:

itr.next() の戻り値で配列のプロパティが一切返されないのか、
if 文による配列プロパティかどうかの判断がまちがっているのか、
どちらですか?




コードを埋め込んだところitr.next()の戻り値で
配列のプロパティが一切返されてないようです。
コードと実行結果は以下になります。
あとすべての配列はObject[]で判断できるという認識ですが、
あってますか?


Parentクラス
コード:

package work;
public class Parent {
private String tel;
private Child[] child; // ※このプロパティが出力されない
public Child[] getChild() {
return child;
}
public String getTel() {
return tel;
}
public void setChild(Child[] string) {
child = string;
}
public void setTel(String string) {
tel = string;
}
}



Childクラス
コード:

package work;
public class Child {
private String name;
private String address;
public String getAddress() {
return address;
}
public String getName() {
return name;
}
public void setAddress(String string) {
address = string;
}
public void setName(String string) {
name = string;
}
}



プロパティ出力クラス
コード:

package work;
import java.lang.reflect.InvocationTargetException;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import org.apache.commons.beanutils.BeanUtils;

public class BeanUtilsTest {
public static void main (String[] args) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
Parent p = new Parent();
Child[] c = new Child[2];
c[0] = new Child();
c[1] = new Child();

c[0].setAddress("aaa");
c[0].setName("bbb");
c[1].setAddress("aaa");
c[1].setName("bbb");
p.setChild(c);
p.setTel("11111");
log(p);
}
static private void log(Object bean) throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
Map map = BeanUtils.describe(bean);
Set set = map.keySet();
Iterator itr = set.iterator();
for (Object k = itr.next(); itr.hasNext(); k = itr.next()) {
System.out.println("pass"); // ※取得したプロパティをカウントするため出力
Object v = map.get(k);
if (v instanceof Object[]) { // ※ここが実行されない
Object[] a = (Object[]) v;
for (int i = 0, end = a.length; i < end; i++) {
log(a[i]);
}
} else {
System.out.println("[name="+k+"][value="+v+"]");
}
}
}
}



実行結果
コード:

pass
[name=child][value=work.Child@14da8f4]
pass
[name=class][value=class work.Parent]



[ メッセージ編集済み 編集者: 未記入 編集日時 2005-12-12 13:21 ]
Anthyhime
ぬし
会議室デビュー日: 2002/09/10
投稿数: 437
投稿日時: 2005-12-12 13:45
思いっきり文字列が帰ってきますね。

describeのJavaDocをみると。

This map contains the to String converted property values for all properties for which a read method is provided (i.e. where the getReadMethod() returns non-null).

どうも文字列で直接戻せる型でないとだめみたいですね。
未記入
ベテラン
会議室デビュー日: 2005/02/24
投稿数: 55
投稿日時: 2005-12-12 14:54
なんかソースを書いているうちに
ちょっと変になってました。
以下は
コード:
		for (Object k = itr.next(); itr.hasNext(); k = itr.next()) {


ノーマルに以下のようにしないとループが一回省略されますね。すみません。
コード:
		while (itr.hasNext()) {
			Object k = itr.next();



あと配列が文字列で帰ってくるのが困ってるんですが。。。
代替手段とかないでしょうか?
プロパティ個々のログを出力するのが希望です。
tobitobi
会議室デビュー日: 2002/08/21
投稿数: 6
投稿日時: 2005-12-12 15:31
配列の確認はObject[]ではなく、ClassクラスのisArrayで判断すると思います。
Anthyhime
ぬし
会議室デビュー日: 2002/09/10
投稿数: 437
投稿日時: 2005-12-13 12:35
describeは用途が違うのであきらめたほうがいいですね。
自分でPropertyInfoを解析してオブジェクトをダンプするコードを書くのがいいと思います。
引用:
配列の確認はObject[]ではなく、ClassクラスのisArrayで判断すると思います。


instanceof Object[]は配列を識別するのに問題ないコードです。
かつのり
ぬし
会議室デビュー日: 2004/03/18
投稿数: 2015
お住まい・勤務地: 札幌
投稿日時: 2005-12-13 12:45
Beanのプロパティのログ目的なら、
Commons LangのToStringBuilder#reflectionToString(Object)が、
おすすめですよ。

コード:

public String toString() {
return ToStringBuilder.reflectionToString(this);
}



toStringメソッドをオーバーライドして上記の記述だけで、
フィールドの内容の文字列化を行ってくれます。


[ メッセージ編集済み 編集者: かつのり 編集日時 2005-12-13 12:58 ]

スキルアップ/キャリアアップ(JOB@IT)