Java BeanUtils 未知 属性 带下划线 (_)

Java BeanUtils Unknown property with underscore (_)

我无法使用 BeanUtils.getProperty(bean, property) 从 class 中获取带下划线的 属性(例如:User_Name),它总是抛出错误:

"Unknown property 'User_Name' on class 'User'".

但是当我调试 bean 时,它有 User_Name 属性。

BeanUtils.getProperty(bean, propertyName);

用户 class 是

public class User {
    private String ID;
    private String User_Name;

    public void setID(String ID) {
        this.ID = ID;
    }

    public String getUser_Name() {
        return this.User_Name;
    }

    public void setUser_Name(String user_Name) {
        this.User_Name = user_Name;
    }
}

这是命名约定的问题。可以参考Where is the JavaBean property naming convention defined? for reference. From section 8.8 of JavaBeans API specification

... Thus when we extract a property or event name from the middle of an existing Java name, we normally convert the first character to lower case*case 1. However to support the occasional use of all upper-case names, we check if the first two characters*case 2 of the name are both upper case and if so leave it alone. So for example,

'FooBah" becomes 'fooBah'
'Z' becomes 'z'
'URL' becomes 'URL'

我们提供了一个实现这个转换规则的方法Introspector.decapitalize

因此对于给定的 class,属性 从 getUser_Name()setUser_Name() 推导出来 根据 *case1,是“user_Name”而不是“User_Name”。调用 getProperty(bean, "ID") 是根据 *case 2.

为了解决这个问题,请按照Java命名规则更新命名,属性和method应该从小写开始,使用驼峰式 而不是 snake_case 来分隔单词。请记住,遵循约定在编程中非常重要。下面以更新后的class为例。

import java.lang.reflect.InvocationTargetException;

import org.apache.commons.beanutils.BeanUtils;

public class User {
    private String ID;
    private String userName;

    public String getID() {
        return ID;
    }

    public void setID(String ID) {
        this.ID = ID;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public static void main(String[] args)
            throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
        User bean = new User();
        bean.setUserName("name");
        System.out.println(BeanUtils.getProperty(bean, "userName"));
    }
}