Passar dados de 1 action para outra

11 respostas
desk

Olá, estou tentando fazer 1 carrinho de compras com struts2, é o seguinte: Tenho uma action que faz a busca no banco de tal produto e mostra na tela, nessa view q está mostrando o tal produto tem 1 botao para adicionar ao carrinho. quando clicar ao botão, queria que pegasse esses valores e enviasse para outra action, q pegaria esses valores e entao adicionaria a sessão .

O problema que estou tendo com o carrinho de compras é que ele não tá conseguindo pegar os valores do tal produto, para adicionar… queria saber como faz para eu usar os resultados de 1 action em outra action? ex: tenho 1 action que mostra o tal produto (${produto.nome}) e nela 1 botao para add ao carrinho, no caso iria por na sessão. Esse tal botão xama a action, que pegaria os dados do tal produto e adicionaria à sessão… porém como fazer isso? como pegar os dados que uma action está mostrando e enviar para outra action esses tais dados? segue meu codigo:
modelo de carrinho -> http://pastebin.com/07A3h314
modelo de itemCarrinho -> http://pastebin.com/48L4z9A6
action -> http://pastebin.com/gTBaBYWs

view ->

nome: ${livro.nome} <a href="adicionaCarrinho"> <img src="images/carrinho-compras-add.png" /> </a>

Já tentei pensar em passar por mas aaxo q não daria muito certo pq estou mostrando 1 objeto e iria pegar com outro.

Outra pergunta, teria como eu na view por um <jsp:useBean class=“itemCarrinho”> e setar os valores sendo mostrados para ele?

11 Respostas

roland

Cara vamo ver se consigo t ajudar. Suponho q vc ja tenha um bean que contenha os itens que vc quer armazenar na session.
Sendo assim, vamo pensa:
Vc tem uma action que tem um atributo do tipo
private MeuBean meuBean.
Na view vc setta este bean atraves da action, tipo isso:
value=${minhaAction.meuBean.nome}, sei la não conheço o struts.
Então setando este bean na sua action vc pode usá-lo dentro dela para passar para outra action.
A explicação não é das melhores , mas acho que a idéia é mais ou menos assim.
Espero ter ajudado.
Falow!

desk

roland:
Cara vamo ver se consigo t ajudar. Suponho q vc ja tenha um bean que contenha os itens que vc quer armazenar na session.
Sendo assim, vamo pensa:
Vc tem uma action que tem um atributo do tipo
private MeuBean meuBean.
Na view vc setta este bean atraves da action, tipo isso:
value=${minhaAction.meuBean.nome}, sei la não conheço o struts.
Então setando este bean na sua action vc pode usá-lo dentro dela para passar para outra action.
A explicação não é das melhores , mas acho que a idéia é mais ou menos assim.
Espero ter ajudado.
Falow!

Então cara, o problema é esse… estou mostrando os valores de uma action já… no caso ${livro.nome} … entao como eu farei para setar o meu bean com esse parametro? usando taglib tem como setar tal bean? tipo fazer um <jsp:usebean> e depois o setproperty ? grato!

edmarr

Bom dia ,
Vc pode criar um formulário na sua action com os valores necessários para sua jsp,
ao disparar a action vc tera na sua jsp todos os dados carregados no formulários , independente se eh somente um atributo
ou se eh uma lista de atributos .

Ou voçe pode usar algo como o seguinte

<package name="aula11" extends="freemarker-default" namespace="/aula11"> <action name="cadastrar!*" class="br.com.miniprojeto.action.CadastrarAction" method="{1}"> <result name="input">/WEB-INF/pages/aula11/form.ftl</result> <result type="chain"> <param name="actionName">ver</param> <param name="namespace">/aula11b</param> </result> </action> </package>

roland

Cara fazer isso value=${minhaAction.meuBean.nome} na sua jsp significa settar ou fazer um get.
A sua action faz isso sozinha. Veja: value=${"1"minhaAction."2"meuBean."3"autor}

  1. Esta é a sua classe action, feita em java, que suponho que faz o controller
  2. Esta é a sua classe bean, feita em java, que é o espelho da tabela do bd. Tipo:
class Livros{
     private Integer id;
     private String titulo;
     private String autor;
     ....
     //getters and setters destes atributos
}
  1. Feito isto, na sua jsp, por exemplo, o campo de texto referente ao autor tem receber o autor através do value obviamente.
    Então se vc ta criando um novo autor a instrução value=${minhaAction.Livros.autor} ta fazendo um set no atributo autor.
    Caso vc estivesse editando, para exibir um autor a instrução na jsp é a mesma, porém a sua action fará um get. Neste caso, onde
    está escrito autor serve para get e set, por isso aparece somente a palavra autor e não getAutor e setAutor;
desk
@roland então cara, mas o problema é o seguinte.. o cara vai tá na pagina de tal produto sendo mostrado certo? e ai tem opção de add ao carrinho.. o produto que está sendo mostrado está sendo pego do bd e tem 1 modelo que é o espelho, como vc disse.. porém esse modelo é outra classe diferente das que envolve o carrinho.. no caso a classe é Livros.. e as que estão referentes ao carrinho são ItemCarrinho e Carrinho... no caso como eu conseguiria setar as coisas q estao sendo mostradas de livro para outro bean? intende? tentei fazer oq vc disse +- só q não está mostrando os tais itens, não sei se estou fazendo errado.. segue:
<td> ${livro.nome} <br> 
	<font color="blue"> ${livro.autor} </font> <br> 
	<fmt:setLocale value="pt_BR"/> R$: <font color="red"> <fmt:formatNumber value="${livro.preco}" minFractionDigits="2" /> </font> 
</td>
<td>
	<form action="adicionaCarrinho">
		${AdicionaCarrinhoAction.ItemCarrinho.livro}
		<input type="submit" value="adicionar"/>
	</form>
</td>
página que mostram os itens do carrinho:
<table>
	<tr>
		<th> Nome </th>
		<th> Quantidade </th>
		<th> Preço </th>
		<th> TOTAL </th>
	</tr>
	<c:forEach var="carrinho" items="${carrinhoCompras}">
		<tr>
			<td> ${carrinho.livros} </td>
		</tr>
	</c:forEach>
</table>

@edmarr cara, então.. eu tinha lido a respeito e axo que resolveria com esse chain ai mesmo, só q não achei nada que me ajuda-se. Não to acustumado com struts2 em xml, faço por annotations.. vc poderia me explicar oq acontece ae? no caso quando chamar cadastrar vai chamar a action CadastrarAction que tem 1 resultado input que creio que seja de erro né, e um chain.. oque acontece entao? oque esse chain faz?
No caso vc acha que com isso eu consigo fazer oq quero?

Grato!

roland

Vamo de novo q daqui um pouco tu t acha.
Seguinte, não sei como q ta as tuas classes AdicionaCarrinhoAction, ItemCarrinho e Carrinho.
Mas suponho que ItemCarrinho tenha um list de livros e Carrinho um list de ItemsCarrinho.
Eu não conheço o struts 2, mas segue um padrão semelhante ao jsf, então acho que esta linha

${AdicionaCarrinhoAction.ItemCarrinho.livro}

obtem um livro para adicionar na classe ItemCarrinho, mas onde tu setta o livro, isto é, tu ta settando
a classe Livro com o livro selecionado pelo usuario para depois add ao ItemCarrinho.
Outra coisa, vc não deveria colocar, no primeiro código dos dois que vc colocou no ultimo post, tudo dentro das tags
<form /> em vez de somente a action?

Tenta da uma olhada, mas provavelmente vc não ta settando a classe Livros, ou então não ta conseguindo obter a instância
dela depois que setta. Se eu estou certo quando digo que a sua classe ItemCarrinho tem um list de Livros, então esta classe
deve conter um referência a classe Livros para poder acessá-la sem fazer um new Livros.
Falow

desk
po intendi +- isso ai hehe. então, fui tentar de outro jeito e modifiquei o codigo.. porém na hora de exibir fica de putaria.. axo que não tá indo pra sessão, não sei oq pode estar errado no codigo.. oq estou tentando fazer ai é o seguinte, seto o id do itemcarrinho para o do tal produto que está sendo mostrado, dae então faço 1 busca no banco para pegar todos os dados do tal produto, então ele pega e adiciona a sessão... Parece que não pode castar itemcarrinho para livros?
java.lang.ClassCastException: br.com.ibooker.modelo.Livros$$EnhancerByCGLIB$$54b003f3 cannot be cast to br.com.ibooker.modelo.ItemCarrinho
	br.com.ibooker.dao.LivrosDAO.procurar(LivrosDAO.java:39)
	br.com.ibooker.action.AdicionaCarrinhoAction.execute(AdicionaCarrinhoAction.java:23)
segue o codigo:
public class ItemCarrinho {
	private Livros livro ;
	private int quantidade ;
	
	public int getQuantidade() {
		return quantidade;
	}
	public void setQuantidade(int quantidade) {
		this.quantidade = quantidade;
	}
	public void setLivro(Livros livro) {
		this.livro = livro;
	}
	public Livros getLivro() {
		return livro;
	}
}
public class Carrinho {
	private List<ItemCarrinho> itens = new ArrayList<ItemCarrinho>() ;
	private Double total = 0.0 ;
	
	public void adicionaLivro(ItemCarrinho l) {
		this.itens.add(l) ;
		this.total += l.getLivro().getPreco() * l.getQuantidade() ;
	}

	public Double getTotal() {
		return total;
	}
	public List<ItemCarrinho> getItens() {
		return itens;
	}
	public void setItens(List<ItemCarrinho> itens) {
		this.itens = itens;
	}
	public void setTotal(Double total) {
		this.total = total;
	}

}
// DAO 
public ItemCarrinho procurar(Long id) {
		return (ItemCarrinho) session.load(Livros.class, id) ;
 	}
public class AdicionaCarrinhoAction {
	private ItemCarrinho livros ;
	private Long id ;
	private Carrinho carro = new Carrinho() ;


	@Action(value="adicionaItem", results={
			@Result(name="ok", location="/carrinho-compras.jsp")
	})
	public String execute() {
		livros = new LivrosDAO().procurar(id) ;
		carro.adicionaLivro(livros) ;
		ActionContext.getContext().getSession().put("carrinhoCompras", carro) ;
		return "ok" ;
	}
	
	
	public Long getId() {
		return id;
	}
	public void setId(Long id) {
		this.id = id;
	}
	public Carrinho getCarro() {
		return carro;
	}
	public void setCarro(Carrinho carro) {
		this.carro = carro;
	}
	public ItemCarrinho getLivros() {
		return livros;
	}
	public void setLivros(ItemCarrinho livros) {
		this.livros = livros;
	}
}
// view que mostra tal produto para add ao carrinho
<table>
	<tr>
		<td> ${livro.nome} <br> 
		<td>
			<form action="adicionaItem">
				<input type="hidden" name="itemCarrinho.livro.id" value="${livro.id}"/>
				<input type="text" name="livro.quantidade" value="1"/>
				<input type="submit" value="adicionar"/>
			</form>
		</td>
	</tr>
</table>
//view que mostra os produtos no carrinho
<table>
	<tr>
		<th> Nome </th>
		<th> Quantidade </th>
		<th> Preço </th>
		<th> TOTAL </th>
	</tr>
	<c:forEach var="carrinho" items="${carrinhoCompras}">
		<tr>
			<td> ${carrinho.itens.nome} </td>
		</tr>
	</c:forEach>
</table>
roland

E dae tchê!

Cara é o seguinte. O teu problema pelo código que tu postou é de Casting, ou seja, tu ta tentando colocar um objeto de um tipo (no caso LivrosDAO)
em um objeto de outro tipo (no caso ItemCarrinho). Então vamos pelo método do jack (o estripador), ou seja, por partes.
Primeiro para resolver o erro eu acho que basta mudar o execute do teu código para isso aqui.

public String execute() {  
        LivrosDAO dao = new LivrosDAO();
	    livros = dao.procurar(id) ;// este método procurar deve retornar somente um livro por vez e o teu dao deve garantir isso
        carro.adicionaLivro(dao) ;  
        ActionContext.getContext().getSession().put("carrinhoCompras", carro) ;  
        return "ok" ;  
    }

Acredito que isso já resolva o teu problema. Não sei explicar em termos técnicos, mas como o java é fortemente tipado ele não permite fazer as coisa do jeito
que como estava antes.

A outra parte, é que olhando o teu código eu vi que tu ta desenvolvendo em camadas. Então:
Atente para uma correta distribuição dos pacotes. Não sei se ta de acordo com os padrões, ou não, mas me parece que a classe Livros deveria ficar em um pacote
de beans e os DAOs no modelo. Mas como te disse não sei como ta a estrutura do teu projeto, por isso só tu pode verificar.

Uma regra básica de OO é que uma classe deve ter o minímo de responsabilidades possíveis, ou seja, uma classe DAO deve fazer somente as operações com o BD. Então as
classes DAO conterão, por exemplo as intruções SQL, que somente ela conhece, e quaisquer outras classes que necessitem de informações do BD, por exemplo uma
classe de controller, devem solicitar a respectiva classe DAO. E vice-versa.

Digo isso pq vc deveria evitar colocar controle de sessão nos DAOs. Além do mais não vejo necessidade disso no teu código. Por isso ai vai uma sugestão para melhorar o código.

public ItemCarrinho procurar(Long id) {  
        return ItemCarrinho ;  
    }
public String execute() {  
        LivrosDAO dao = new LivrosDAO();
	    livros = dao.procurar(id) ;// este método procurar deve retornar somente um livro por vez e o teu dao deve garantir isso
        carro.adicionaLivro(dao) ;  

        /*A ideia é: depois de obter as informações do BD coloque na sessão. E na Action de buscar as informações para colocar no carrinho
        recupere a session*/
        HttpSession session = session.setAtribute(String, object); //aqui usei HttpSession, mas faz como vc achar melhor.
        return "ok" ;  
    }

É isso aí! Os dois últimos códigos é só uma sugestão. E espero que o teu código pare de ficar de putaria! HAHAHA!
Falow

desk
Eae irmão.. então, tentei do jeito que tu falou ai porém tá dando o mesmo erro hauhaua quanto ao DAO ali.. é pq to usando hibernate tambem saca?! por isso o load e tal.. poo então, não to conseguindo desse jeito ai e tentie denovo por 1 otra metodologia + simples.. que era de setar e pasasr esses tais parametros q foram setados certo?! no caso as classes continuam a mesma só que tirei as coisas de pegar no banco e tal.. queria passar pelo form mesmo, porém tá dando nullexception na hora de add.. qual solução?! ;( segue o codigo:
public class AdicionaCarrinhoAction {
	private ItemCarrinho livros ;
	private Carrinho carro = new Carrinho() ;


	@Action(value="adicionaItem", results={
			@Result(name="ok", location="/carrinho-compras.jsp")
	})
	public String execute() { 
		carro.adicionaLivro(livros) ;
		ActionContext.getContext().getSession().put("carrinhoCompras", carro) ;
		return "ok" ;
	}

	
	public Carrinho getCarro() {
		return carro;
	}
	public void setCarro(Carrinho carro) {
		this.carro = carro;
	}
	public ItemCarrinho getLivros() {
		return livros;
	}
	public void setLivros(ItemCarrinho livros) {
		this.livros = livros;
	}
}
// view que mostra tal produto para add ao carrinho
<table>
	<tr>  
                // mostrando as coisas sobre o produto (nome, preço.. etc)
		<td> ${livro.nome} <br> 
		<td>
			<form action="adicionaItem">
                   // setando do jeito q tu me ensinou.. no caso estaria setando o objeto que está sendo referenciado pela variavel livros da action..
				<input type="hidden" name="livros.livro.nome" value="${livro.nome}"/>
				<input type="text" name="livros.quantidade" value="1"/>
				<input type="submit" value="adicionar"/>
			</form>
		</td>
	</tr>
</table>
java.lang.NullPointerException
// é a linha onde tá adicionando o livro .. 
	br.com.ibooker.modelo.Carrinho.adicionaLivro(Carrinho.java:7)
roland

Cara geralmente quando aparece o erro NullPointerException é que tem alguma classe que vc não deu um new,
não instanciou, certo.
E quanto ao hibernate no teu projeto eu não sabia é claro e dae como não conheço nada de hibernate não poderei
te dizer se é ou não o hibernate.
Falow
Vai mandando ai que de todo jeito to aprendendo contigo tb.

desk
Então, deixa eu te falar.. tava com hibernate antigamente né.. eu passava o id do tal produto sendo mostrado.. e fazia uma busca no banco pra pegar as coisas daquele tal id.. isso que fazia aquilo do dao lá, o .load faz 1 busca por id.. intende? dai eu vi que não tava dando certo fazer desas maneira e tentei de outra maneira, aquela q vc falou.. apenas setando o tal bean e depois adicionalo.. mas creio q não tá setando corretamente.. pq tá dando nullexception ao tentar adicionar ou seja, creio q tá tentando adicionar algo vazio intende?.. agora eu te pergunto, estou setando corretamente?? No casto estou querendo setar o itemCarrinho ali da action. segue:
// view que mostra tal produto para add ao carrinho
<table>
	<tr>  
                // mostrando as coisas sobre o produto (nome, preço.. etc)
		<td> ${livro.nome} <br> 
		<td>
			<form action="adicionaItem">
                   // setando do jeito q tu me ensinou.. no caso estaria setando o objeto que está sendo referenciado pela variavel livros da action..
				<input type="hidden" name="livros.livro.nome" value="${livro.nome}"/>
				<input type="text" name="livros.quantidade" value="1"/>
				<input type="submit" value="adicionar"/>
			</form>
		</td>
	</tr>
</table>
public class AdicionaCarrinhoAction {
	private ItemCarrinho livros ;
	private Carrinho carro = new Carrinho() ;


	@Action(value="adicionaItem", results={
			@Result(name="ok", location="/carrinho-compras.jsp")
	})
	public String execute() { 
		carro.adicionaLivro(livros) ;
		ActionContext.getContext().getSession().put("carrinhoCompras", carro) ;
		return "ok" ;
	}

	
	public Carrinho getCarro() {
		return carro;
	}
	public void setCarro(Carrinho carro) {
		this.carro = carro;
	}
	public ItemCarrinho getLivros() {
		return livros;
	}
	public void setLivros(ItemCarrinho livros) {
		this.livros = livros;
	}
}
public class ItemCarrinho {
	private Livros livro ;
	private int quantidade ;
	
	public int getQuantidade() {
		return quantidade;
	}
	public void setQuantidade(int quantidade) {
		this.quantidade = quantidade;
	}
	public void setLivro(Livros livro) {
		this.livro = livro;
	}
	public Livros getLivro() {
		return livro;
	}
}
Criado 8 de maio de 2010
Ultima resposta 21 de mai. de 2010
Respostas 11
Participantes 3