WebWork2 - Cenário Simples - Várias Dúvidas

7 respostas
A

Ouvindo falar (e falar bem) sobre o WebWork e ainda mais com o artigo que o Smota publicou, resolvi estudá-lo, mas ainda assim estou apanhando para efetuar alguns comportamentos básicos no dia a dia de um sistema.
Vou descrever um cenário básico, no qual eu gostaria de implementá-lo no WW2.
Seria um Cadastro de Cidade
:arrow: Crio uma classe Bean, com os atribuos id,nome,uf, crio os métodos setters e getters e um construtor default.
:arrow: Crio um arquivo .JSP, na qual será a interface com o usuário, ele terá um form em HTML, no qual irá chamar uma Action para cadastro.
:arrow: dentro do xwork.xml eu crio a tag da action, e direiciono essa tag para meu Bean.
:arrow: o Sistema deve validar os dados digitados pelo usuário, sendo o ID e o nome da cidade obrigátorios. Isso quem será responsável é o validation do WW2.
:arrow: Caso houve validação, preencher os dados dentro da minha classe bean Cidade, e essa classe deverá ser jogada para o Hibernate gravar essas informações no banco de dados, usando o método Save da classe DAO.

É isso ae, o que eu pensei em fazer foi o seguinte.
Dentro do meu form, chamar por exemplo uma action chamada
cadastroCidade.action.
Essa tag está mapeada no arquivo xwork.xml assim;

<action class="br.com.teste.models.Cidade" name="cadastroCidade">
		<interceptor-ref name="defaultStack"/>
		<result name="success">sucesso.jsp</result>
		<result name="input">clientes.jsp</result>
	</action>

ou seja, está chamando o meu bean Cidade. O WW irá validar ele (se tiver o aruqivo de validation) e depois irá preencher os atributos, até ae sem problemas.

Agora seguem as dúvidas

:arrow: Meu Objetivo é, depois de ter o bean preenchido, eu irei jogar ele dentro do Hibernate através do DAO.save, eu irei ter que fazer isso dentro do método execute() (dentro do Bean), que é um método overriding da ActionSupport? Ou existe outro meio de eu recuperar esse Bean dentro de outro servlet?
Porque se eu for ter que implementar isso dentro do método execute de cada bean, imaginando um sistema com umas 50 entidades, eu terei 50 Bean representando as entidades, e terei que implementar dentro dos 50, certo?.
:arrow: Se eu jogar o código dentro do método execute (código para chamar o dao), eu não estarei misturando as coisas, ou seja, dentro de um modelo (MODEL do MVC) eu não estarei jogando regras de negócios também?
:arrow: Pensei em criar uma classe que extende a ActionSupport, dentro dessa clase colocar os métodos do DAO e depoi dentro do meu Bean extender essa classe, e dentro do método execute eu chamo apenas um método dessa classe, acredito que diminuirá o trabalho e reaproveitará código, será que isso é a melhor solução?
:arrow: Vamos supor que dentro do Form (no HTML), eu tenha um botao para gravar e outro pra deletar. Dentro do Execute eu vou ter que ver qual botao foi pressionado para ae sim selecionar qual operação efetuar? E isso não é misturar mais ainda regras de negócios dentro dos Modelos?

Dúvidas, Dúvidas e mais Dúvidas :roll: :roll:

Por enquanto é só…

Obrigado desde já

7 Respostas

smota

:shock: :shock: :shock: :shock: :shock:

ehehe vamos por partes.

Você baixou o projeto do tutorial e brincou com ele?!? Qualquer cadastro ou coisa parecida eh igualquinem o login (com mais campos provavelmente :wink: )

A primeira parte da sua msg está OK, o que vcoê quer fazer eh tudo que se espera quando tah usando o WW (ou qq framework MVC).

As dúvidas que ficaram meio confusas.

  1. MODEL do MVC é sua camada onde estarão as regras de negócio (vc pode abstrair isso ainda mais e não ser, mas por definição é sim, quer dize, o modelo é quem sabe trabalhar os dados e controla-los na definicao)
  2. DAO não tem nada a ver com regra de negocio. É usado nela geralmente.
  3. Vc vai salvar no execute() sim mas nao precisa se preocupar em popular os beans nem nada , eles já estarão populados.
  4. Quanto ao botões de SALVAR ou DELETAR vc tem 2 opcoes, a primeira eh cada botao postar pra uma action diferente (por Javascript mesmo) e a segunda eh ver qual botao foi pressionado … sim vc tera essa informação.

De uma brincada com o framework que as coisas ficam mais claras … e posta as duvidas por aqui mesmo

[]s

Gilmar_Rodrigues

Lí o seu tutorial e estou usando o webwork em um projeto. A única coisa q eu fiquei em dúvida foi sobre isso q vc acabou de falar sobre 2 botões. A princípio eu ia deixar um input hidden e colocar nele um valor conforme o botão apertado, mas já q vc falou q tem como eu saber q botão foi pressionado, fiquei curioso, como eu sei qual botão foi pressionado?

ricardolecheta

http://wiki.opensymphony.com/space/Webwork+2+HTML+form+buttons+Howto

A

Então Smota

puxei seu tutorial aqui do GUJ, e dei uma olhada, e realmente não entendi uma coisa simples, que acredito que resolva uma das minhas dúvidas.

No seu form do login.jsp, ele chama o login.action
<ww:form name="'login'" action="'login.action'" method="'POST'">
	<ww:textfield label="getText('login.username')" name="'username'" value="username" size="15"/>
	<ww:password  label="getText('login.password')" name="'password'" value="password" size="15"/>
	<ww:submit value="getText('login.enter')"/>
</ww:form>
dentro do xwork.xml você tem a tag para esse form assim
<action name="login" class="br.com.guj.actions.Login">
		<result name="input" type="dispatcher">
			<param name="location">/login.jsp</param>
		</result>
		<result name="error" type="dispatcher">
			<param name="location">/login.jsp</param>
		</result>
		<result name="success" type="redirect">
			<param name="location">/interno.action</param>
		</result>
	</action>

o xwork chama a classe br.com.guj.actions.Login

essa classe tem o método execute(), e nesse método está assim
public class Login 
		extends SystemAction 
		implements DisableSecurityAction
{

	private static final Log log = LogFactory.getLog(Login.class);
	
	private User model = new User();
	
	public String execute() {
		
		// --> AQUI deveria validar de verdade o usuário
		if(!model.getUsername().equals("guj")) {
			addActionError(getText("login.invalidCredentials"));
			addFieldError("username", getText("login.unknowUser"));
			return ERROR;
		}

O que da pra perceber aqui, é que dentro do método execute() ele já testa o objeto model.getUsername, esse objeto model é o bean User.
Pergunta.. como que o Bean User poi preenchidos com os dados? Eu procurei nos códigos e não achei, será que foi mágina :roll: :roll:

smota

sim sim … foi automagicamente preenchido pelo framework (na verdade é um interceptor que preenche, se não me engano é o Parameters interceptor).

Note que os nomes dos campos são os mesmos das propriedades dos beans, com isso o framework consegue preenche-lo sem problemas.

Se você não usar commanddriven ele procurará na própria Action as propriedades do campo, podendo inclusive ser propriedades compostas (i.e: se tiver no form uma propriedade phone.ddd ele chamará na action getPhone().setDdd() e por ai vai)

A

então, eu realmente imaginei que algo era responsável por preencher o Bean e que os campos no formulário teriam que ter o mesmo nome, até ae sem problemas.

O que você me disse foi que isso é através de um Interceptor. Mas onde você configurou isso?

Procurei no arquivo xwork.xml por interceptor e achei essas linhas
<interceptors>
		<interceptor
			class="br.com.guj.system.ApplicationSecurityInterceptor" name="appsecurity"/>
	
		<interceptor-stack name="systemDefaultStack">
			<interceptor-ref name="model-driven"/>
			<interceptor-ref name="component"/>
            <interceptor-ref name="appsecurity"/>
			<interceptor-ref name="validationWorkflowStack"/>
			<interceptor-ref name="logger"/>
			<interceptor-ref name="timer"/>
		</interceptor-stack>
	</interceptors>

Pelo menos que eu vi, nao tem nada falando para preencher o Bean User.

Estou quase chegando lá, pelo menos eu espero :oops:

smota

My bad :oops:

Realmente não ficou muito claro.

Veja que no xwork.xml que criamos nós incluimos um arquivo chamado webwork-default.xml, este arquivo está no arquivo jar do webwork.
Ele tem um monte de configurações iniciais e entre elas os principais interceptors, results e por ai vai.

Abra esse arquivo e você verá que existe um stack (pilha mesmo) de interceptors nele chamada validationWorkflowStack que inclui uma outra pilha chamada defaultStack … nós adicionamos a primeira na nossa systemDefaultStack e por isso os interceptors estão aplicados. Não usamos direto nenhuma das duas já declaradas porque queriamos aplicar mais alguns interceptors.

Ficou mais claro?

Criado 21 de abril de 2004
Ultima resposta 22 de abr. de 2004
Respostas 7
Participantes 4