Java Bean、BeanUtils 和布尔包装类

发布于 2024-10-21 12:08:50 字数 937 浏览 7 评论 0原文

我正在使用 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 方法来表示属性。代码>布尔值。有人对如何通过 BeanUtils 访问此类属性有建议吗?我可以使用某种解决方法吗?

I'm using BeanUtils to manipulate Java objects created via JAXB, and I've run into an interesting issue. Sometimes, JAXB will create a Java object like this:

public class Bean {
    protected Boolean happy;

    public Boolean isHappy() {
        return happy;
    }

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

The following code works just fine:

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

However, attempting to get the happy property like so:

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

Results in this exception:

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

Changing everything to a primitive boolean allows both the set and get call to work. I don't have this option, however, since these are generated classes. I assume this happens because the Java Bean libraries only consider an is<name> method to represent a property if the return type is a primitive boolean, and not the wrapper type Boolean. Does anyone have a suggestion as to how to access properties like these through BeanUtils? Is there some kind of workaround I can use?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

半枫 2024-10-28 12:08:50

最后我找到了法律确认:

8.3.2 布尔属性

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

公共布尔值是();

来自 JavaBeans 规范。您确定没有遇到 JAXB-131 bug 吗?

Finally I've found legal confirmation:

8.3.2 Boolean properties

In addition, for boolean properties, we allow a getter method to match the pattern:

public boolean is<PropertyName>();

From JavaBeans specification. Are you sure you haven't came across JAXB-131 bug?

悟红尘 2024-10-28 12:08:50

使用 BeanUtils 处理布尔 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());

Workaround to handle Boolean isFooBar() case with BeanUtils

  1. Create new 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. Register BooleanIntrospector:

    BeanUtilsBean.getInstance().getPropertyUtils().addBeanIntrospector(new BooleanIntrospector());

2024-10-28 12:08:50

您可以使用 SET - 后缀创建第二个 getter 作为解决方法:)

you can just create second getter with SET - sufix as workaround :)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文