Solucionado (ver solução)
Solucionado
(ver solução)
1
resposta

Erro 404 ao adicionar item no carrinho. Link montado incorretamente

Olá a todos.

Estou fazendo a aula 4 (Spring Security) do curso Spring MVC 2 e durante a mudança do form da página "detalhe.jsp", percebi que o botão "Comprar" que adiciona o item no carrinho não está mais funcionando. Está aparecendo o erro 404.

Percebi que o link desse botão está sendo criado incorretamente. Ao invés desse link ser "/casadocodigo/carrinho/add" é "/casadocodigo/produtos/detalhe/30/carrinho/add".

Eu já revi o meu código e a aula e não entendi onde que eu errei. No vídeo da aula dá para ver que o link criado está correto. Não sei se é algum problema de configuração ou na tag form do spring.

Abaixo é o código antigo e que funciona

<form action="<c:url value='/carrinho/add' />" method="post" class="container">
                <input type="hidden" value="${produto.id }" name="produtoId" >
                <ul id="variants" class="clearfix">
                    <c:forEach items="${produto.precos }" var="preco">
                        <li class="buy-option">
                            <input type="radio" name="tipoPreco" class="variant-radio" id="tipoPreco" value="${preco.tipo }" checked="checked" /> 
                            <label class="variant-label" >${preco.tipo }</label> 
                            <small class="compare-at-price">R$ 39,90</small>
                            <p class="variant-price">${preco.valor }</p>
                        </li>
                    </c:forEach>
                </ul>
                <button type="submit" class="submit-image icon-basket-alt" title="Compre Agora ${produto.titulo }"></button>
            </form>

Abaixo é o código implementado na aula e que está gerando o link errado:

<form:form servletRelativeAction="/carrinho/add" method="post" cssClass="container">
                <input type="hidden" value="${produto.id }" name="produtoId" >
                <ul id="variants" class="clearfix">
                    <c:forEach items="${produto.precos }" var="preco">
                        <li class="buy-option">
                            <input type="radio" name="tipoPreco" class="variant-radio" id="tipoPreco" value="${preco.tipo }" checked="checked" /> 
                            <label class="variant-label" >${preco.tipo }</label> 
                            <small class="compare-at-price">R$ 39,90</small>
                            <p class="variant-price">${preco.valor }</p>
                        </li>
                    </c:forEach>
                </ul>
                <button type="submit" class="submit-image icon-basket-alt" title="Compre Agora ${produto.titulo }"></button>
            </form:form>

Abaixo é o código da classe CarrinhoComprasController:

@Controller
@RequestMapping("/carrinho")
@Scope(value=WebApplicationContext.SCOPE_REQUEST)
public class CarrinhoComprasController {

    @Autowired
    private ProdutoDAO produtoDao;

    @Autowired
    private CarrinhoCompras carrinho;

    @RequestMapping("/add")
    public ModelAndView add(Integer produtoId, TipoPreco tipoPreco) {
        ModelAndView modelAndView = new ModelAndView("redirect:/carrinho");
        CarrinhoItem carrinhoItem = criaItem(produtoId, tipoPreco);
        carrinho.add(carrinhoItem);
        return modelAndView;
    }


    @RequestMapping(method=RequestMethod.GET)
    public ModelAndView itens() {
        return new ModelAndView("carrinho/itens");
    }

    private CarrinhoItem criaItem(Integer produtoId, TipoPreco tipoPreco) {
        Produto produto = this.produtoDao.find(produtoId);
        CarrinhoItem carrinhoItem = new CarrinhoItem(produto, tipoPreco);
        return carrinhoItem;
    }

    @RequestMapping("/remover")
    public ModelAndView remover(Integer produtoId, TipoPreco tipoPreco) {
        carrinho.remover(produtoId, tipoPreco);
        return new ModelAndView("redirect:/carrinho");
    }
}

Alguém tem alguma ideia de onde está o erro?

Se quiserem analisar mais alguma classe do projeto, eu subi o projeto no GitLab no seguinte link: https://gitlab.com/MauryOshiro/projeto-curso-spring-mvc-2-alura---casa-do-codigo.git

1 resposta
solução!

Encontrei a solução do problema ao pegar os arquivos iniciais da aula 06.

Percebi que durante a aula 04 o instrutor usou o atributo servletRelativeAction da tag form, mas no arquivo inicial da aula 06 foi usado action usando como valor uma variável criada usando expression language.

É meio complicado de explicar descrevendo a diferença, então vamos lá:

A aula 04 diz para usar o seguinte trecho de código:

<form:form servletRelativeAction="/carrinho/add" 
    method="post" cssClass="container">

E no arquivo que peguei estava assim:

<form:form action='${contextPath }carrinho/add' 
method="post" cssClass="container">

Um pequeno detalhe: foi usado a seguinte linha no topo da página o sistema jogar o caminho correto nessa variável contextPath:

<c:url value="/" var="contextPath" />

O estranho é que eu terminei a aula 5 e não vi o uso do form dessa forma. De qualquer forma eu fiz uma sugestão de melhoria na atividade da aula 4 para que esse problema não ocorra com outros alunos.