質問

私は 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"));

一体なぜ彼らはこのように実装したのでしょうか?また、デフォルトでゲッターとセッターを使用する PropertyModel の代替手段はありますか?

ありがとう?

役に立ちましたか?

解決

PropertyModel あなたが望むことはすでにやります。とき PropertyModel 値がクエリされると、次の 2 つの場所が検索されます。

  • 指定されたプロパティに「ゲッター」メソッドが存在する場合、 PropertyModel getter を呼び出してプロパティの値を取得します。具体的には、 PropertyModel という名前のメソッドを探します get<Property>, 、 どこ <Property> に渡されるプロパティ式です。 PropertyModel コンストラクターを呼び出し、リフレクションが存在する場合はそれを使用してメソッドを呼び出します。

  • 「getter」メソッドが存在しない場合、 PropertyModel プロパティフィールドの値を直接返します。具体的には、 PropertyModel リフレクションを使用して、に渡されたプロパティ式に一致するフィールドを検索します。 PropertyModel コンストラクタ。一致するフィールドが見つかった場合、 PropertyModel フィールドの値を返します。注意してください。 PropertyModel は、一致するパブリック フィールドに加えて、プライベート フィールドと保護されたフィールドをチェックします。

あなたの場合、で使用されるプロパティ式は、 PropertyModel コンストラクターは "password", 、それで、 PropertyModel まず、 user オブジェクトと呼ばれる getPassword. 。そのようなメソッドが存在しない場合、 PropertyModel プライベートの値を返します password 代わりにフィールドを使用します。

あなたの場合、 PropertyModel 「ゲッター」を呼び出す代わりにプライベート フィールドの値を返しています。おそらく、ゲッターの名前をタイプミスした可能性があります。 User クラス。たとえば、誤って入力した場合、 getPasssword (3 つの s を含む)、 PropertyModel 見つからないため、フォールバックしてプライベート フィールドを返します。


編集

気に入らない場合は PropertyModelのデフォルトの動作では、次のサブクラスを作成できます。 PropertyModel これにより、Wicket がプライベート フィールドに対して読み取り/書き込みを試行できなくなります。このようにして、すべてのプロパティへのアクセスがゲッターとセッターを介して行われるように強制できます。

例を書きました 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()));
    }
}

他のヒント

マイクsprossによって素晴らしい答え! しかし一つの小さな加えます:

私は、この場合には、プロパティモデルを使用していないと思います。ただ書く

 new Model<String>(){ getObject(){...} setObject(){...}}

と正確に何をしたいんれ、正しいbahaviorを実装します。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top