Struts 2 - é possível usar set / construtor private?

10 respostas
A

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 ?

Obrigado

10 Respostas

nicoweda

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

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.

public class User implements Serializable 
{

	private static final long serialVersionUID = 1L;
	private Integer id;
	private String username;
	private String password;
	
	
	
	/**
	 * @param id
	 * @param username
	 * @param password
	 */
	public User(Integer id, String username, String password) throws Exception
	{
		super();
		this.setId(id);
		this.setUsername(username);
		this.setPassword(password);
	}


	/**
	 * @param id the id to set
	 */
	private void setId(Integer id) 
	{
		if (id < 0)
			throw new IllegalArgumentException("O atributo 'id' não pode ser menor que 0 (Zero) ( id : " + id + ") ");
		
		this.id = id;
	}


	/**
	 * @param username the username to set
	 */
	private void setUsername(String username) throws Exception
	{
		if (username == null)
			throw new NullPointerException("O atributo 'username' é nulo ( Class User : Method setUsername() )");
		
		if (username.trim().isEmpty())
			throw new IllegalArgumentException("O atributo 'username' está vazio ( Class User : Method setUsername() )");
		
		if (username.trim().length() > 20)	
			throw new IllegalArgumentException("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
	 */
	private void setPassword(String password) throws Exception
	{
		if (password == null)
			throw new NullPointerException("O atributo 'password' é nulo ( Class User : Method setPassword() )");
			
		if (password.isEmpty())
			throw new IllegalArgumentException("O atributo 'password' está vazio ( Class User : Method setPassword() )");			
			
		if (password.trim().length() != 8)	
			throw new IllegalArgumentException("O atributo 'password' deve possuir 8 caracteres. password.length : "+ password.length() +" ( Class User : Method setPassword() ) ");
		
		this.password = password.trim();
	}


	/**
	 * @return the id
	 */
	public Integer getId() 
	{return id;}


	/**
	 * @return the username
	 */
	public String getUsername() 
	{return username;}


	/**
	 * @return the password
	 */
	public String getPassword() 
	{return password;}
}

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
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 .:
package net.roseindia;
import com.opensymphony.xwork2.ActionSupport;
import java.util.Date;


/**
 * <p> Validate a user login. </p>
 */
public  class Login  extends ActionSupport {


    @Override
    public String execute() throws Exception {
       System.out.println("Validating login");
		if(!getUsername().equals("WilliamSilva") || !getPassword().equals("fly2007")){
           addActionError("Nome ou Password inválido! por favor repita a operação...!");
            return ERROR;
		}else{
			return SUCCESS;
		}
	}


    // ---- Username property ----

    /**
     * <p>Field to store User username.</p>
     * <p/>
     */
    private String username = null;


    /**
     * <p>Provide User username.</p>
     *
     * @return Returns the User username.
     */
    public String getUsername() {
        return username;
    }

    /**
     * <p>Store new User username</p>
     *
     * @param value The username to set.
     */
    public void setUsername(String value) {
        username = value;
    }

    // ---- Username property ----

    /**
     * <p>Field to store User password.</p>
     * <p/>
     */
    private String password = null;


    /**
     * <p>Provide User password.</p>
     *
     * @return Returns the User password.
     */
    public String getPassword() {
        return password;
    }

    /**
     * <p>Store new User password</p>
     *
     * @param value The password to set.
     */
    public void setPassword(String value) {
        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

rodrigo_corinthians
Perfeito…!!!

A

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.

Criado 3 de novembro de 2007
Ultima resposta 6 de nov. de 2007
Respostas 10
Participantes 5