17

BeanUtils を使用して、JAXB 経由で作成された Java オブジェクトを操作していますが、興味深い問題に遭遇しました。時々、JAXB は次のような Java オブジェクトを作成します。

public class Bean {
    protected Boolean happy;

    public Boolean isHappy() {
        return happy;
    }

    public void setHappy(Boolean happy) {
        this.happy = happy;
    }
}

次のコードは問題なく動作します。

Bean bean = new Bean();
BeanUtils.setProperty(bean, "happy", true);

happyただし、次のようにプロパティを取得しようとしています。

Bean bean = new Bean();
BeanUtils.getProperty(bean, "happy");

この例外が発生します。

Exception in thread "main" java.lang.NoSuchMethodException: Property 'happy' has no getter method in class 'class Bean'

すべてをプリミティブに変更するとboolean、set 呼び出しと get 呼び出しの両方が機能するようになります。ただし、これらは生成されたクラスであるため、このオプションはありません。これは、戻り値の型がラッパー型ではなくプリミティブである場合にのみ、Java Bean ライブラリis<name>がプロパティを表すメソッドを考慮するためであると考えられます。BeanUtils を介してこれらのようなプロパティにアクセスする方法について、誰か提案がありますか? 使用できる回避策はありますか?booleanBoolean

4

3 に答える 3

10

最後に、法的確認を見つけました:

8.3.2 ブールプロパティ

さらに、ブール値のプロパティの場合、getter メソッドをパターンに一致させることができます。

public boolean is<PropertyName>();

JavaBeans 仕様から。JAXB-131バグに出くわしていませんか?

于 2011-03-11T17:21:26.183 に答える
8

Boolean isFooBar() ケースを BeanUtils で処理するための回避策

  1. 新しい BeanIntrospector を作成する

private static class BooleanIntrospector implements BeanIntrospector{
    @Override
    public void introspect(IntrospectionContext icontext) throws IntrospectionException {
        for (Method m : icontext.getTargetClass().getMethods()) {
            if (m.getName().startsWith("is") && Boolean.class.equals(m.getReturnType())) {
                String propertyName = getPropertyName(m);
                PropertyDescriptor pd = icontext.getPropertyDescriptor(propertyName);

                if (pd == null)
                    icontext.addPropertyDescriptor(new PropertyDescriptor(propertyName, m, getWriteMethod(icontext.getTargetClass(), propertyName)));
                else if (pd.getReadMethod() == null)
                    pd.setReadMethod(m);

            }
        }
    }

    private String getPropertyName(Method m){
        return WordUtils.uncapitalize(m.getName().substring(2, m.getName().length()));
    }

    private Method getWriteMethod(Class<?> clazz, String propertyName){
        try {
            return clazz.getMethod("get" + WordUtils.capitalize(propertyName));
        } catch (NoSuchMethodException e) {
            return null;
        }
    }
}

  1. BooleanIntrospector を登録します。

    BeanUtilsBean.getInstance().getPropertyUtils().addBeanIntrospector(新しい BooleanIntrospector());

于 2014-04-24T22:35:43.623 に答える