Wicket Property Fremdheit?
-
23-08-2019 - |
Frage
Ich bin neu in Wicket und versucht, die folgende Konfiguration:
class User {
private String password;
...
public void setPassword(String password) {
this.password = MD5.encode(password);
}
...
}
Nach dem Versuch, die folgenden zu verwenden, um das Passwort zu binden und herauszufinden, dass die Standardimplementierung von Propertystandardmäßig auf das Feld gebunden ist, nicht die Eigenschaft (komischer Name eh?)
add(new PasswordTextField("password", new PropertyModel(user, "password"));
Warum in der Welt würde sie es auf diese Weise umgesetzt? Und gibt es eine Alternative, die Property Getter und Setter standardmäßig verwendet?
Danke?
Lösung
PropertyModel
wird tun, was Sie schon wollen. Wenn ein PropertyModel
für ihren Wert abgefragt wird, ist es an zwei Stellen aussieht:
-
Wenn ein „Getter“ Verfahren für die gegebene Eigenschaft vorhanden ist, ruft der
PropertyModel
den Getter den Wert der Eigenschaft abzurufen. Insbesondere sieht diePropertyModel
für ein Verfahren namensget<Property>
, wo<Property>
die Eigenschaft Ausdruck desPropertyModel
Konstruktor übergeben ist, und ruft die Methode mithilfe von Reflektion, wenn es vorhanden ist. -
Wenn keine „Getter“ Methode existiert, gibt die
PropertyModel
den Wert der Eigenschaft Feld direkt. Insbesondere verwendet diePropertyModel
Reflexion ein Feld finden, die die Eigenschaft Ausdruck an den Konstruktor übergebenPropertyModel
übereinstimmt. Wenn ein passendes Feld gefunden wird, gibt diePropertyModel
das Wert des Feldes. Beachten Sie, dass diePropertyModel
prüft private und geschützte Felder zusätzlich zu den öffentlichen Bereichen für ein Spiel.
In Ihrem Fall die Eigenschaft Ausdruck im PropertyModel
Konstruktor verwendet wird, ist "password"
, so dass die PropertyModel
erste für ein Verfahren auf dem user
Objekt namens getPassword
aussehen wird. Wenn kein solches Verfahren existiert, wird die PropertyModel
den Wert des privaten password
Feldes zurückzukehren, statt.
in Ihrem Fall Da der PropertyModel
ist die private Feldwert zurückkehrt, anstatt den Aufruf der „Getter“, werden Sie wahrscheinlich vertippt den Namen des Getter in Ihrer User
Klasse. Zum Beispiel f versehentlich getippt Sie getPasssword
(mit 3 s ist), die PropertyModel
wird es nicht finden, und auf die Rückkehr auf den privaten Bereich Rückfall wird.
Bearbeiten
Wenn Sie nicht PropertyModel
Standardverhalten mögen, können Sie eine Unterklasse von PropertyModel
erstellen, die Wicket verhindern wird von dem Versuch, auf private Felder zu lesen / schreiben. Auf diese Weise können Sie alle Immobilien zwingen Zugriffe durch Getter und Setter auftreten.
Ich schrieb ein Beispiel BeanPropertyModel
Klasse dies zu demonstrieren:
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()));
}
}
Andere Tipps
große Antwort von mike sprießt! ein kleiner Zusatz aber:
ich würde nicht Eigentum Modell in diesem Fall verwendet werden. nur schreiben
new Model<String>(){ getObject(){...} setObject(){...}}
und implementieren die richtige bahavior, das genau das tut, was Sie wollen.