Java Beans, BeanUtils и логический класс-оболочка - PullRequest
13 голосов
/ 11 марта 2011

Я использую BeanUtils для манипулирования объектами Java, созданными через JAXB, и столкнулся с интересной проблемой.Иногда 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 следующим образом:1008 *

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> только для представления свойства, если тип возвращаемого значения - примитив boolean, а не тип оболочки Boolean.У кого-нибудь есть предложения о том, как получить доступ к таким свойствам через BeanUtils?Есть ли какое-то решение, которое я могу использовать?

Ответы [ 3 ]

10 голосов
/ 11 марта 2011

Наконец-то я нашел законное подтверждение:

8.3.2 Логические свойства

Кроме того, для логических свойств мы разрешаем методу-получателю соответствовать шаблону:

public boolean is<PropertyName>();

Из спецификация JavaBeans .Вы уверены, что не сталкивались с ошибкой JAXB-131 ?

6 голосов
/ 25 апреля 2014

Временное решение для обработки логического случая 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 ());

0 голосов
/ 05 июня 2018

вы можете просто создать второй геттер с помощью SET - sufix в качестве обходного пути:)

...