我是Wicket的新手,正在尝试以下配置:
class User {
private String password;
...
public void setPassword(String password) {
this.password = MD5.encode(password);
}
...
}在尝试使用以下代码绑定到密码后,发现PropertyModel的默认实现默认绑定到字段,而不是属性(奇怪的名称,嗯?)
add(new PasswordTextField("password", new PropertyModel(user, "password"));他们到底为什么要以这种方式实现呢?默认情况下是否有使用getter和setters的PropertyModel替代方法?
谢谢?
发布于 2009-02-14 05:33:39
PropertyModel已经可以做你想做的事情了。当查询PropertyModel的值时,它在两个地方查找:
PropertyModel将调用该getter来检索属性的值。具体地说,PropertyModel查找名为get<Property>的方法,其中<Property>是传递给PropertyModel构造函数的属性表达式,如果该方法存在,则使用反射调用该方法。PropertyModel直接返回属性字段的值。具体地说,PropertyModel使用反射查找与传递给PropertyModel构造函数的属性表达式匹配的字段。如果找到匹配的字段,PropertyModel将返回该字段的值。请注意,除了公共字段外,PropertyModel还将检查私有字段和受保护字段是否匹配。在本例中,PropertyModel构造函数中使用的属性表达式是"password",因此PropertyModel将首先在user对象上查找一个名为getPassword的方法。如果不存在这样的方法,PropertyModel将返回私有password字段的值。
由于在您的示例中,PropertyModel返回的是私有字段的值,而不是调用" getter ",因此很可能是在User类中输入了错误的getter名称。例如,如果您不小心键入了getPasssword (带有3个s),PropertyModel将找不到它,并将退回到返回私有字段。
编辑
如果你不喜欢PropertyModel的默认行为,你可以创建一个PropertyModel的子类,防止Wicket试图读/写私有字段,这样,你就可以强制所有的属性访问都通过getters和setters进行。
我编写了一个示例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()));
}
}发布于 2009-02-18 14:07:48
mike spross回答得很好!不过,还有一个小小的补充:
在这种情况下,我不会使用属性模型。只需写
new Model<String>(){ getObject(){...} setObject(){...}}并实现正确的行为,它会做你想要做的事情。
https://stackoverflow.com/questions/548354
复制相似问题