Pergunta

Eu sou novo para Wicket e estava tentando a seguinte configuração:

class User {
   private String password;

   ...

   public void setPassword(String password) {
     this.password = MD5.encode(password);
   }
   ...
}

Depois de tentar usar o seguinte para vincular à senha e descobrir que a implementação padrão de PropertyModel é por padrão para ligado para o campo, não a propriedade (nome estranho eh?)

add(new PasswordTextField("password", new PropertyModel(user, "password"));

Por que no mundo que eles têm implementado desta maneira? E há uma alternativa PropertyModel que usos getter e setters por padrão?

Obrigado?

Foi útil?

Solução

PropertyModel vai fazer o que você já quer. Quando um PropertyModel é consultado para o seu valor, ele parece estar em dois lugares:

  • Se existe um método "getter" para a propriedade dada, o PropertyModel chama o getter para recuperar o valor da propriedade. Especificamente, os olhares PropertyModel para um get<Property> método chamado, onde <Property> é a expressão de propriedade passado para o construtor PropertyModel, e chama o método usando a reflexão se ela existir.

  • Se nenhum método "getter" existe, o PropertyModel retorna o valor do campo de propriedade diretamente. Especificamente, o uso PropertyModel reflexão encontrar um campo que corresponde à expressão de propriedade passado para o construtor PropertyModel. Se um campo correspondente for encontrado, o PropertyModel retorna o valor do campo. Note que o PropertyModel irá verificar campos particulares e protegidas, além de campos públicos para uma partida.

No seu caso, a expressão de propriedade usada no construtor PropertyModel é "password", de modo que o PropertyModel procurará primeiro por um método no objeto user chamado getPassword. Se nenhum método existe, o PropertyModel irá retornar o valor do campo password privada em vez.

Uma vez que no seu caso o PropertyModel está retornando o valor do campo privada em vez de chamar o "getter", você provavelmente digitado incorretamente o nome do getter em sua classe User. Por exemplo, f você digitou acidentalmente getPasssword (com 3 s de), o PropertyModel não vai encontrá-lo, e irá fallback para devolver o campo privado.


Editar

Se você não gosta o comportamento padrão do PropertyModel, você pode criar uma subclasse de PropertyModel que vai impedir Wicket de tentar ler / escrever para campos particulares. Dessa forma, você pode forçar todos os acessos de propriedade para ocorrer através de getters e setters.

Eu escrevi uma classe exemplo BeanPropertyModel para demonstrar isto:

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()));
    }
}

Outras dicas

grande resposta por Mike Spross! um pequeno acréscimo no entanto:

Eu não usaria modelo de propriedade neste caso. Basta escrever

 new Model<String>(){ getObject(){...} setObject(){...}}

e implementar o bahavior correta, que faz exatamente o que você quer.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top