سؤال

أنا جديد على النصيب وكان يحاول التكوين التالي:

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 الصحيح، الذي يفعل بالضبط ما تريد.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top