Wicket PropertyModel が奇妙ですか?
-
23-08-2019 - |
質問
私は 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を実装します。