Java Beans, BeanUtils, and the Boolean wrapper class
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 workaroun开发者_运维百科d I can use?
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?
Workaround to handle Boolean isFooBar() case with BeanUtils
- 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;
}
}
}
Register BooleanIntrospector:
BeanUtilsBean.getInstance().getPropertyUtils().addBeanIntrospector(new BooleanIntrospector());
you can just create second getter with SET - sufix as workaround :)
精彩评论