Solucionado (ver solução)
Solucionado
(ver solução)
8
respostas

Problemas com o método getItens()

Olá

Não estou conseguindo renderizar a lista do carrinho de compras, já verifiquei que consigo inserir o livro no carrinho, porém após o redirect, o carrinho fica vazio.

Segue abaixo o meu código


@Model
public class CarrinhoComprasBean {

    private Integer id;
    @Inject
    private LivroDao dao;

    @Inject
    private CarrinhoCompras carrinho;

    public String add(Integer id) {
        Livro livro = dao.buscarPorId(id);
        CarrinhoItem item = new CarrinhoItem(livro);
        carrinho.add(item);

        System.out.println(carrinho.getItens().size());

        return "carrinho?faces-redirect=true";
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public LivroDao getDao() {
        return dao;
    }

    public void setDao(LivroDao dao) {
        this.dao = dao;
    }

    public CarrinhoCompras getCarrinho() {
        return carrinho;
    }

    public void setCarrinho(CarrinhoCompras carrinho) {
        this.carrinho = carrinho;
    }

    public List<CarrinhoItem>getItens(){

        return carrinho.getItens();

    }

}


@Named
@SessionScoped
public class CarrinhoCompras implements Serializable {

    private static final long serialVersionUID = 1L;
    private Set<CarrinhoItem> itens = new HashSet<>();

    public void add(CarrinhoItem item) {
        itens.add(item);
    }

    public List<CarrinhoItem> getItens() {
        return new ArrayList<CarrinhoItem>(itens);
    }

}

public class CarrinhoItem {

    private Livro livro;
    private Integer quantidade;

    public CarrinhoItem(Livro livro) {
        this.livro = livro;
        this.quantidade = 1;
    }

    public Livro getLivro() {
        return livro;
    }

    public void setLivro(Livro livro) {
        this.livro = livro;
    }

    public Integer getQuantidade() {
        return quantidade;
    }

    public void setQuantidade(Integer quantidade) {
        this.quantidade = quantidade;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((livro == null) ? 0 : livro.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        CarrinhoItem other = (CarrinhoItem) obj;
        if (livro == null) {
            if (other.livro != null)
                return false;
        } else if (!livro.equals(other.livro))
            return false;
        return true;
    }

    @Override
    public String toString() {
        return "CarrinhoItem [livro=" + livro.getTitulo() + ", quantidade=" + quantidade + "]";
    }

}
8 respostas

ola Julio, tudo bem?

você poderia mandar a sua view também?

Olá Samir, Desculpa! Segue as views, apenas com as partes principais, porque não estava conseguindo colocá-las na integra.

<!-- detalhe-livro-->
<!DOCTYPE html>

<f:metadata>
    <f:viewParam id="id" name="id" value="#{livroDetalheBean.id}"/>
    <f:viewAction action="#{livroDetalheBean.carregarDetalhe()}"/>
</f:metadata>

    <title>#{livroDetalheBean.livro.titulo} - Casa do Código</title>

<form jsf:id="form-comprar"  method="POST" class="adicionarAoCarrinho">
    <ul class="adicionarAoCarrinho-listaOfertas">
        <li class="adicionarAoCarrinho-oferta" itemprop="offers" itemscope="" itemtype="http://schema.org/Offer">
            <label class="adicionarAoCarrinho-infosDaOferta" for="product-variant-2055441665">
                <span class="adicionarAoCarrinho-tipoDaOferta" role="presentation" itemprop="category" itemscope="" itemtype="http://schema.org/Ebook">
                    <span class="adicionarAoCarrinho-tipoDaOferta-nome">
                        E-book
                    </span>
                    <small class="adicionarAoCarrinho-tipoDaOferta-detalhe">
                        (.pdf, .epub e .mobi)
                    </small>
                </span>
                <p class="adicionarAoCarrinho-preco">
                        <small class="adicionarAoCarrinho-preco-promocao">
                            <del class="adicionarAoCarrinho-preco-promocao-valor">R$ 1099,90</del> por
                        </small>
                    <span class="adicionarAoCarrinho-preco-valor" itemprop="price">
                        R$ #{livroDetalheBean.livro.preco}
                    </span>
                </p>
            </label>
                <button jsf:action="#{carrinhoComprasBean.add(livroDetalheBean.id)}" class="adicionarAoCarrinho-botaoComprar" type="submit"  title="Compre o E-book">
                    Comprar
                </button>
        </li>
    </ul>
</form>

<!-- carrinho.xhtml -->
    <form class="formularioDoCarrinho" action="https://www.casadocodigo.com.br/cart" method="post">
        <table class="formularioDoCarrinho-tabela">
        <thead class="formularioDoCarrinho-cabecalho">
            <tr>
                <th></th>
                <th class="formularioDoCarrinho-cabecalho-item">Item</th>
                <th class="formularioDoCarrinho-cabecalho-item formularioDoCarrinho-cabecalho-preco">Preço</th>
                <th class="formularioDoCarrinho-cabecalho-item">Qtd</th>
                <th class="formularioDoCarrinho-cabecalho-item">Total</th>
                <th></th>
            </tr>
        </thead>
        <tbody>


                    <ui:repeat value="#{carrinhoComprasBean.itens}" var="carrinhoItem">
                        <tr>
                            <td class="formularioDoCarrinho-item"><a
                                href="#{request.contextPath}/detalhe-livro.xhtml?id=#{carrinhoItem.livro.id}">
                                    <img class="formularioDoCarrinho-item-imagem"
                                    src="#{request.contextPath}/files/#{carrinhoItem.livro.capaPath}" />
                                </a>
                            </td>
                            <td class="formularioDoCarrinho-item">
                                <h2 class="formularioDoCarrinho-item-titulo">#{carrinhoItem.livro.titulo}</h2>
                            </td>
                            <td
                                class="formularioDoCarrinho-item formularioDoCarrinho-item-preco">#{carrinhoItem.livro.preco}</td>
                            <td class="formularioDoCarrinho-item"><input
                                class="formularioDoCarrinho-item-quantidade" type="number"
                                min="0" value="#{carrinhoItem.quantidade}" /></td>
                            <td
                                class="formularioDoCarrinho-item formularioDoCarrinho-item-precoTotal"
                                title="Preço unitário: #{carrinhoItem.livro.preco}">#{carrinhoItem.livro.preco}
                                </td>
                            <td class="formularioDoCarrinho-item"><a
                                href="https://www.casadocodigo.com.br/cart/change?id=18404155847&amp;quantity=0">
                                    <img class="formularioDoCarrinho-item-remover-imagem"
                                    src="#{request.contextPath}/resources/imagens/trash.png"
                                    alt="X" title="Remover" />
                            </a></td>
                        </tr>
                    </ui:repeat>

                </tbody>
        <tfoot class="formularioDoCarrinho-rodape">
            <tr>
                <td class="formularioDoCarrinho-rodape-item formularioDoCarrinho-finalizar" colspan="3">
                    <button class="formularioDoCarrinho-finalizar-botao" type="submit" name="checkout">Finalizar<span class="formularioDoCarrinho-finalizar-botao-texto" role="presentation"> compra</span></button>
                </td>
                <td class="formularioDoCarrinho-rodape-item">
                    <button class="formularioDoCarrinho-atualizar" type="submit" name="update">Atualizar</button>
                </td>
                <td class="formularioDoCarrinho-rodape-item">
                    R$29,90
                </td>
                <td></td>
            </tr>
        </tfoot>
    </table>
</form>

Encontrei dos erros nas minha classes, mas que não resolvem o problema. O método getItens() do carrinhoCompras estava errado e consequentemente o getItens do carrinhoComprasBean também.

Abaixo seguem as classes consertadas.

@Named
@RequestScoped
public class CarrinhoComprasBean {

//    private Integer id;
    @Inject
    private LivroDao dao;


    @Inject
    private CarrinhoCompras carrinho;

    public String add(Integer id) {
        Livro livro = dao.buscarPorId(id);
        CarrinhoItem item = new CarrinhoItem(livro);
        carrinho.add(item);

        System.out.println(carrinho.getItens().size());

        return "carrinho?faces-redirect=true";
    }


    public List<CarrinhoItem> getItens() {
        return new ArrayList<CarrinhoItem>(carrinho.getItens());
    }


}

@SessionScoped
@Named
public class CarrinhoCompras implements Serializable {

    private static final long serialVersionUID = -8805176140594051579L;
    private Set<CarrinhoItem> itens = new HashSet<>();

    public void add(CarrinhoItem item) {
        itens.add(item);
    }

    public Set<CarrinhoItem> getItens() {
        return itens;
    }



    public BigDecimal getTotal(){
        BigDecimal total = BigDecimal.ZERO;
        for (CarrinhoItem carrinhoItem : itens) {
            total = total.add(carrinhoItem.getLivro().getPreco().multiply(new BigDecimal(carrinhoItem.getQuantidade())));
        }
        return total;
    }

    public BigDecimal getTotal(CarrinhoItem item) {
        return item.getLivro().getPreco().multiply(new BigDecimal(item.getQuantidade()));
    }
}

Identifiquei, debugando, que o carrinho está vindo zerado porque o cdi, faz uma nova injeção quando invoca o método getItens() de carrinhoCompras, e por isso retorna os itens zerados. Existe algum outro escopo do CDI que me permite evitar esse problema?

Oi Julio, acredito que se vc colocar o seu Bean com SessionScoped resolva o seu problema.

Como vc esta querendo pegar os dados do Bean, se ele durar apenas um request não conseguirá manter os dados.

Olá Samir, valeu pela atenção!

Resolvi o problema anotando a classe carrinhoCompras com @ApplicationScoped.

Finalmente!

Boa Julio!!

mas veja se o escopo do carrinho realmente deve ter o Scopo de Aplicação, dessa forma ele vai durar desde o momento em que vc sobe o servidor até a hora que ele cai. E todas as Sessões usarão o mesmo carrinho também.

Boa Samir, você tem razão! vou verificar com mais atenção hoje, ontem já não estava rendendo.

solução!

Olá Samir!

Eu estava usando o chrome e então resolvi fazer um teste usando o firefox e funcionou normalmente, com o @SessionScoped. Não sei se tem algo a ver com retorno do Código HTTP chrome, mas enfim! Vou continuar, por enquanto no firefox para prosseguir com o curso e depois bato cabeça em busca de uma solução.