All*_*nde 5 data-binding wicket
我是Wicket的新手,正在尝试以下配置:
class User {
private String password;
...
public void setPassword(String password) {
this.password = MD5.encode(password);
}
...
}
Run Code Online (Sandbox Code Playgroud)
尝试使用以下命令绑定到密码并发现PropertyModel的默认实现默认绑定到该字段,而不是属性(奇怪的名称呃?)
add(new PasswordTextField("password", new PropertyModel(user, "password"));
Run Code Online (Sandbox Code Playgroud)
他们为什么会以这种方式实施它?是否存在默认情况下使用getter和setter的PropertyModel替代方法?
谢谢?
Mik*_*oss 11
PropertyModel会做你想做的事.当a PropertyModel查询其值时,它会在两个位置查找:
如果给定属性存在"getter"方法,则PropertyModel调用getter来检索属性的值.具体来说,PropertyModel查找名为的方法get<Property>,其中<Property>是传递给PropertyModel构造函数的属性表达式,如果存在,则使用反射调用该方法.
如果不存在"getter"方法,则PropertyModel直接返回属性字段的值.具体来说,PropertyModeluses反射找到一个与传递给PropertyModel构造函数的属性表达式匹配的字段.如果找到匹配的字段,则PropertyModel返回字段的值.请注意,PropertyModel除了匹配的公共字段外,还将检查私有字段和受保护字段.
在您的情况下,PropertyModel构造函数中使用的属性表达式是"password",因此PropertyModel将首先在被user调用的对象上查找方法getPassword.如果不存在这样的方法,PropertyModel则将返回私有password字段的值.
因为在你的情况下,PropertyModel返回私有字段的值而不是调用"getter",你很可能错误地输入了User类中getter的名称.例如,如果您意外键入getPasssword(使用3秒),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()));
}
}
Run Code Online (Sandbox Code Playgroud)