سؤال
أنا جديد على النصيب وكان يحاول التكوين التالي:
class User {
private String password;
...
public void setPassword(String password) {
this.password = MD5.encode(password);
}
...
}
بعد محاولة استخدام ما يلي للربط بكلمة المرور ومعرفة أن التطبيق الافتراضي للبريد الإلكتروني هو الافتراضي لتحمل الحقل، وليس الخاصية (اسم غريب إيه؟)
add(new PasswordTextField("password", new PropertyModel(user, "password"));
لماذا في العالم قد نفذوا ذلك بهذه الطريقة؟ وهل هناك بديل PropertyModel يستخدم Getter والسينتين افتراضيا؟
شكرا لك؟
المحلول
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"، فمن المرجح أن يثقيب اسم Getter في User
صف دراسي. على سبيل المثال، F لقد كتبت بطريق الخطأ getPasssword
(مع 3 S)، PropertyModel
لن تجد ذلك، وسوف يسقط لإعادة المجال الخاص.
تعديل
إذا كنت لا تحب PropertyModel
السلوك الافتراضي، يمكنك إنشاء فئة فرعية من PropertyModel
من شأنها أن تمنع النصيبات من محاولة القراءة / الكتابة إلى الحقول الخاصة. بهذه الطريقة، يمكنك إجبار جميع وصول الممتلكات تحدث من خلال 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()));
}
}
نصائح أخرى
إجابة رائعة من مايك Spross! إضافة صغيرة واحدة على الرغم من:
لن استخدم طراز الممتلكات في هذه الحالة. اكتب فقط
new Model<String>(){ getObject(){...} setObject(){...}}
وتنفيذ Bahavior الصحيح، الذي يفعل بالضبط ما تريد.