Struts 2 - é possível usar set / construtor private?
10 respostas
A
Alucard
Boa noite,
Estava realizando alguns testes com o struts 2 e me deparei com um problema.
Criei uma classe chamada ‘User’ com os atributos ‘username’ e ‘password’. Pensando no encapsulamento, criei os métodos set’s como private para cada atributo com validações dentro deles, e adicionei as mesmas dentro do construtor. Assim para instanciar a classe ‘User’, teria que obedecer os argumentos a serem passados e as validações dos métodos set’s. Mas quando fui utilizar a classe em uma action do Struts 2, vi que é necessário que a classe tenha um construtor vazio, e que os método set deve ser public.
Realmente é necessário a classe ter um construtor vazio e os métodos set’s do atributos da classe devem ser public ?
O Struts 2 utiliza os getters/setter pra fazer a injeção dos parametros.
To provide a loosely coupled system, Struts2 uses a technique
called dependency injection, or inversion of controlv.
Dependency injection can be implemented by constructor
injection, interface injection and setter injection. Struts2 uses
setter injection. This means that to have objects available to the
action, you need only to provide a setter. The preferred
dependency injection framework is the Spring Framework,
which is configured via a plugin. Another option is Plexus, or if
you prefer you can supply your own implementation.
Dá uma olhada nisso, peguei da documentação oficial do Struts 2.
Espero ter ajudado!
Abraços
A
Alucard
E ae Nico,
Então, isso que você disse é correto. Mas gostaria de saber se os métodos para setar os atributos e o construtor sem argumentos devem ser somente public.
publicclassUserimplementsSerializable{privatestaticfinallongserialVersionUID=1L;privateIntegerid;privateStringusername;privateStringpassword;/** * @param id * @param username * @param password */publicUser(Integerid,Stringusername,Stringpassword)throwsException{super();this.setId(id);this.setUsername(username);this.setPassword(password);}/** * @param id the id to set */privatevoidsetId(Integerid){if(id<0)thrownewIllegalArgumentException("O atributo 'id' não pode ser menor que 0 (Zero) ( id : "+id+") ");this.id=id;}/** * @param username the username to set */privatevoidsetUsername(Stringusername)throwsException{if(username==null)thrownewNullPointerException("O atributo 'username' é nulo ( Class User : Method setUsername() )");if(username.trim().isEmpty())thrownewIllegalArgumentException("O atributo 'username' está vazio ( Class User : Method setUsername() )");if(username.trim().length()>20)thrownewIllegalArgumentException("O atributo 'username' possui mais de 20 caracteres. username.length : "+username.length()+" ( Class User : Method setUsername() ) ");this.username=username.trim();}/** * @param password the password to set */privatevoidsetPassword(Stringpassword)throwsException{if(password==null)thrownewNullPointerException("O atributo 'password' é nulo ( Class User : Method setPassword() )");if(password.isEmpty())thrownewIllegalArgumentException("O atributo 'password' está vazio ( Class User : Method setPassword() )");if(password.trim().length()!=8)thrownewIllegalArgumentException("O atributo 'password' deve possuir 8 caracteres. password.length : "+password.length()+" ( Class User : Method setPassword() ) ");this.password=password.trim();}/** * @return the id */publicIntegergetId(){returnid;}/** * @return the username */publicStringgetUsername(){returnusername;}/** * @return the password */publicStringgetPassword(){returnpassword;}}
Estou tentando criar uma regra para que a classe somente possa ser instanciada se obedecer as regras que coloquei nos métodos set’s. E quando criar um objeto da classe ‘User’, ela não poderá ser modificada (deixando os métodos set’s como private). Dessa forma o objeto seria imutável. Pensando dessa maneira, eu não irei conseguir popular o objeto criado da classe ‘User’ por uma action do Struts 2. Será que teria uma outra maneira de contornar isso ?
Obrigado
W
WilliamSilva
Realmente é necessário a classe ter um construtor vazio e os métodos set's do atributos da classe devem ser public ?
Sim os acessos aos métodos dvem se public .:
packagenet.roseindia;importcom.opensymphony.xwork2.ActionSupport;importjava.util.Date;/** * <p> Validate a user login. </p> */publicclassLoginextendsActionSupport{@OverridepublicStringexecute()throwsException{System.out.println("Validating login");if(!getUsername().equals("WilliamSilva")||!getPassword().equals("fly2007")){addActionError("Nome ou Password inválido! por favor repita a operação...!");returnERROR;}else{returnSUCCESS;}}// ---- Username property ----/** * <p>Field to store User username.</p> * <p/> */privateStringusername=null;/** * <p>Provide User username.</p> * * @return Returns the User username. */publicStringgetUsername(){returnusername;}/** * <p>Store new User username</p> * * @param value The username to set. */publicvoidsetUsername(Stringvalue){username=value;}// ---- Username property ----/** * <p>Field to store User password.</p> * <p/> */privateStringpassword=null;/** * <p>Provide User password.</p> * * @return Returns the User password. */publicStringgetPassword(){returnpassword;}/** * <p>Store new User password</p> * * @param value The password to set. */publicvoidsetPassword(Stringvalue){password=value;}}
rodrigo_corinthians
Apenas acrescentando…
Alucard:
Realmente é necessário a classe ter um construtor vazio?
Sim, quando sobe a aplicação ou na requisição de um link o Struts 2 precisa instanciar a classe Action/Pojo por isso do construtor default porq automaticamente não teria como instanciar um construtor com parâmetros.
Alucard:
e os métodos set’s do atributos da classe devem ser public ?
Os get’s tanb porq é feito via reflection só tem acesso aos métodos public.
W
WilliamSilva
rodrigo_corinthians
Perfeito…!!!
A
Alucard
Bom dia a todos,
Muito obrigado pela explicação ! Só mais uma dúvida … como vocês fariam para que um objeto seja criado corretamente deixando um construtor sem argumentos e seus métodos set do tipo public ?
Por exemplo, eu quero que minha classe “User” sempre que seja instanciada, seja obrigatório o preechimento dos campos “id”, “username” e “password”. Bem, seu eu tiver um construtor sem argumentos, e tiver vários set’s como public, dá abertura para que meu objeto seja criado incompleto. Assim eu posso criar um objeto ‘User’ com o “username” e o “id” preenchido, mas o “password” vazio. Sei que posso fazer validações no Struts 2, mas se precisar utilizar a classe ‘User’ em um outro projeto que não utilize o Struts 2 ? Um projeto desktop por exemplo, ou um outro framework, ou talvez somente servlet, eu teria que criar outra validação.
Vocês teriam alguma idéia de como contornar isso ? Ou seria impossível ?
Muito obrigado a todos
nicoweda
cara, dar dá… tudo depende da sua necessidade!
Vc cria a sua classe com getter/setter privados ou sem getter/setter e um contrutor completo.
E através de um interceptor vc utiliza reflexão para injetar os parametros através do construtor… vai ser um pouco trabalhoso mas resolve o seu problema.
Abraços
xjcd
Amigo faz o seguinte, cria um metodo com retorno boleanod entro da sua classe chamado validate(), dele vc faz as suas validações, deixando os get/set públicos do jeito que tem de ser.
nicoweda
Eu sinceramente tb acho que vc deveria criar os getter/setters publicos e o construtor default… e depois estabelece um jeito padronizado pra validar as coisas… seja ele utillizando a validação do Struts 2 ou criando o metodo validate…
A ideia do construtor é contruir e não validar.
xjcd
Vc tem que chamar o validate no seu action antes de chamar o metodo salvar no seu DAO. Essa técnica é até uma padrão de projeto. CommandValidate. Lembre-se que em OO cadas coisa tem sua resposabilidade, e get/set so servem para settar e gettar nada mais, se vc quer fazer validação usa um método com essa resposabilidade específica.