PropertyModel
会做你想做的事。当PropertyModel
查询 a 的值时,它会在两个地方查找:
如果给定属性存在“getter”方法,则PropertyModel
调用 getter 以检索属性的值。具体来说,PropertyModel
查找名为 的方法get<Property>
,其中<Property>
是传递给PropertyModel
构造函数的属性表达式,如果存在则使用反射调用该方法。
如果不存在“getter”方法,则PropertyModel
直接返回属性字段的值。具体来说,PropertyModel
使用反射查找与传递给PropertyModel
构造函数的属性表达式匹配的字段。如果找到匹配的字段,则PropertyModel
返回该字段的值。请注意,PropertyModel
除了公共字段之外,还将检查私有和受保护字段是否匹配。
在您的情况下,PropertyModel
构造函数中使用的属性表达式是"password"
,因此将首先在名为 的对象PropertyModel
上查找方法。如果不存在这样的方法,则将返回私有字段的值。user
getPassword
PropertyModel
password
由于在您的情况下PropertyModel
返回私有字段的值而不是调用“getter”,因此您很可能在User
类中输入了错误的 getter 名称。例如,如果您不小心输入getPasssword
了(使用 3 个 s),PropertyModel
则不会找到它,并将回退到返回私有字段。
编辑
如果您不喜欢PropertyModel
的默认行为,您可以创建一个子类,PropertyModel
以防止 Wicket 尝试读取/写入私有字段。这样,您可以强制通过 getter 和 setter 进行所有属性访问。
我写了一个示例BeanPropertyModel
类来演示这一点:
import org.apache.wicket.WicketRuntimeException;
import org.apache.wicket.model.PropertyModel;
/**
* A custom implementation of {@link org.apache.wicket.model.PropertyModel}
* that can only be bound to properties that have a public getter or setter method.
*
* @author mspross
*
*/
public class BeanPropertyModel extends PropertyModel {
public BeanPropertyModel(Object modelObject, String expression) {
super(modelObject, expression);
}
@Override
public Object getObject() {
if(getPropertyGetter() == null)
fail("Missing getter");
return super.getObject();
}
@Override
public void setObject(Object modelObject) {
if(getPropertySetter() == null)
fail("Missing setter");
super.setObject(modelObject);
}
private void fail(String message) {
throw new WicketRuntimeException(
String.format("%s. Property expression: '%s', class: '%s'.",
message,
getPropertyExpression(),
getTarget().getClass().getCanonicalName()));
}
}