问题 Java Bean,BeanUtils和布尔包装类


我正在使用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> 如果返回类型是基元,则表示属性的方法 boolean,而不是包装类型 Boolean。有没有人建议如何通过BeanUtils访问这些属性?我可以使用某种解决方法吗?


12398
2018-03-10 22:10


起源

在哪里 BeanUtils 班级来自哪里?我查了一下 org.apache.commons.beanutils.BeanUtils (1.8.3),它工作正常。请注意,通常 is 前缀用于 boolean,而为 Boolean: get。 - Tomasz Nurkiewicz
我正在使用相同的BeanUtils。你能够做到 getProperty() 与 is 返回的方法 Boolean 包装类? - Charles Hellstrom
您对<name>的假设是正确的。 isXXX仅适用于类型布尔返回类型。对于布尔返回类型,getXXX是正确的方法名称。 - DwB
你是对的, getProperty() 不起作用 Boolean is。实际上,IntelliJ会生成getter get 对于 Boolean 和 is 对于 boolean  - 我想Eclipse也是如此。 - Tomasz Nurkiewicz


答案:


最后我找到了法律确认:

8.3.2布尔属性

另外,对于布尔属性,我们允许getter方法匹配模式:

public boolean is<PropertyName>();

JavaBeans规范。你确定你没有遇到过 JAXB-131 错误?


9
2018-03-11 17:21



是的,看起来我遇到了那个bug。我将JAXB版本升级到2.1.13并添加了“-enableIntrospection”标志。这改变了所有 Boolean 包装纸 is 方法 get秒。谢谢! - Charles Hellstrom


使用BeanUtils处理Boolean isFooBar()的解决方法

  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(new BooleanIntrospector());


5
2018-04-24 22:35





你可以用SET创建第二个getter - sufix作为解决方法:)


0
2018-06-04 21:03