Portillo extrañeza PropertyModel?
-
23-08-2019 - |
Pregunta
Soy nuevo en el portillo y estaba tratando la siguiente configuración:
class User {
private String password;
...
public void setPassword(String password) {
this.password = MD5.encode(password);
}
...
}
Después de tratar de usar lo siguiente para unirse a la contraseña y descubrir que la implementación predeterminada de PropertyModel es por defecto a dependiente del campo, no la propiedad (nombre raro eh?)
add(new PasswordTextField("password", new PropertyModel(user, "password"));
¿Por qué en el mundo se han implementado de esta manera? Y es que hay una alternativa que utiliza PropertyModel getter y setters por defecto?
Gracias?
Solución
PropertyModel
va a hacer lo que ya desea. Cuando un PropertyModel
se consulta por su valor, se ve en dos lugares:
-
Si existe un método "getter" para la propiedad dada, la
PropertyModel
llama al comprador para recuperar el valor de la propiedad. En concreto, elPropertyModel
busca unaget<Property>
llamado método, donde<Property>
es la expresión de propiedad pasado al constructorPropertyModel
, y llama al método utilizando la reflexión, si existe. -
Si no existe ningún método "getter", el
PropertyModel
devuelve el valor del campo de la propiedad directamente. En concreto, elPropertyModel
utiliza la reflexión encontrar un campo que coincide con la expresión propiedad pasó al constructorPropertyModel
. Si se encuentra un campo de juego, elPropertyModel
devuelve el valor del campo. Tenga en cuenta que laPropertyModel
comprobará campos privados y protegidos, además de campos públicos para un partido.
En su caso, la expresión bienes utilizados en el constructor PropertyModel
es "password"
, por lo que el PropertyModel
buscará primero un método en el objeto user
llamada getPassword
. Si no existe tal método, el PropertyModel
devolverá el valor del campo password
privada en su lugar.
Dado que en su caso la PropertyModel
está devolviendo el valor del campo privado en lugar de llamar a la "captador", lo más probable es escrito mal el nombre del comprador en su clase User
. Por ejemplo, f equivocación pulsa getPasssword
(con 3 de s), la PropertyModel
no lo encontrará, y se replegará para devolver el ámbito privado.
Editar
Si no te gusta el comportamiento predeterminado del PropertyModel
, puede crear una subclase de PropertyModel
que evitará Wicket de tratar de leer / escribir en campos privados. De esta manera, se puede obligar a todos los bienes accede a ocurrir a través de captadores y definidores.
escribí una clase de ejemplo BeanPropertyModel
para demostrar esto:
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()));
}
}
Otros consejos
gran respuesta de Mike Spross! una pequeña adición embargo:
No usaría modelo de propiedad en este caso. acaba de escribir
new Model<String>(){ getObject(){...} setObject(){...}}
e implementar el bahavior correcta, lo que hace exactamente lo que quiere.