首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Wicket PropertyModel陌生感?

Wicket PropertyModel陌生感?
EN

Stack Overflow用户
提问于 2009-02-14 02:21:35
回答 2查看 6.2K关注 0票数 5

我是Wicket的新手,正在尝试以下配置:

代码语言:javascript
复制
class User {
   private String password;

   ...

   public void setPassword(String password) {
     this.password = MD5.encode(password);
   }
   ...
}

在尝试使用以下代码绑定到密码后,发现PropertyModel的默认实现默认绑定到字段,而不是属性(奇怪的名称,嗯?)

代码语言:javascript
复制
add(new PasswordTextField("password", new PropertyModel(user, "password"));

他们到底为什么要以这种方式实现呢?默认情况下是否有使用getter和setters的PropertyModel替代方法?

谢谢?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2009-02-14 05:33:39

PropertyModel已经可以做你想做的事情了。当查询PropertyModel的值时,它在两个地方查找:

  • 如果给定属性存在" 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试图读/写私有字段,这样,你就可以强制所有的属性访问都通过getters和setters进行。

我编写了一个示例BeanPropertyModel类来演示它:

代码语言:javascript
复制
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()));
    }
}
票数 11
EN

Stack Overflow用户

发布于 2009-02-18 14:07:48

mike spross回答得很好!不过,还有一个小小的补充:

在这种情况下,我不会使用属性模型。只需写

代码语言:javascript
复制
 new Model<String>(){ getObject(){...} setObject(){...}}

并实现正确的行为,它会做你想要做的事情。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/548354

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档