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

Botão do form retorna um id Null

Após apertar no botão COMPRAR deveria redirecionar para a /casadocodigo/produtos , mas isso não acontece.

Ao invés disso ele me envia para carrinhos/add , onde dá erro 404.

CarrinhosComprasController

@Controller
@RequestMapping("/carrinho")
public class CarrinhosComprasController {

    @Autowired
    private ProdutoDAO produtoDao;

    @Autowired
    private CarrinhoCompras carrinho;

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

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

}

detalhe.jsp (form)

<form action='<c:url value="/carrinho/add" />' method="post" class="adicionarAoCarrinho">
    <ul class="adicionarAoCarrinho-listaOfertas">
    <input type="hidden" value="${produto.id}" value="produtoId" />
    <c:forEach items="${produto.precos}" var="preco">
        <li class="adicionarAoCarrinho-oferta" itemprop="offers" itemscope>
            <label class="adicionarAoCarrinho-infosDaOferta">
                <span class="adicionarAoCarrinho-tipoDaOferta"
                     role="presentation"
                     itemprop="category"
                      itemscope>
                     <input type="radio" name="tipo" class="variant-radio" id="tipo" value="${preco.tipo}"  checked="checked"  />
                    <span class="adicionarAoCarrinho-tipoDaOferta-nome">
                        ${preco.tipo}
                    </span>
                </span>
                <p class="adicionarAoCarrinho-preco">

                    <small class="adicionarAoCarrinho-preco-promocao">
                        <del class="adicionarAoCarrinho-preco-promocao-valor">R$ 39,90</del> por
                    </small>
                    <span class="adicionarAoCarrinho-preco-valor" itemprop="price">
                        ${preco.valor}
                    </span>
                </p>
            </label>
        </li>
        </c:forEach>
        <button type="submit" class="adicionarAoCarrinho-botaoComprar" title="Compre ${produto.titulo}">
            Comprar
        </button>
    </ul>
</form>
15 respostas

Fala Renato, tudo bem ?

Então .. Dê uma olhada se a execução está chegando no controller através do debugger ou com um sysout no início (bem mais fácil e rapido rs)

Pode ser que ele não esteja chegando na action pois não faz sentido mandar pra carrinhos/add. Seu mapeamento deveria mandar o post pra carrinho/add normalmente.

Tente verificar também nos logs se o mapeamento das actions estão normais.

Poste aqui pra gente saber.

Olá Rafael Rollo!

Eu acrescentei um sysout no início do método e realmente não apareceu no log.

    @RequestMapping("/add")
    public ModelAndView add(Integer produtoId, TipoPreco tipoPreco) {
        System.out.println("REDIRECIONANDO PARA PRODUTOS!");
        ModelAndView modelAndView = new ModelAndView("redirect:/produtos");
        CarrinhoItem carrinhoItem =  criaItem(produtoId, tipoPreco);
        carrinho.add(carrinhoItem);
        return modelAndView;
    }

Nem sequer está entrando no método... Eu caio no endereço:

http://localhost:8080/casadocodigo/carrinho/add

Oi Renato,

No seu jsp, onde está /carrinho/add, troque por /casadocodigo/produtos

Exemplo:

form action='<c:url value="/casadocodigo/produtos" />' method="post" class="adicionarAoCarrinho">

Valeu Renato,

Então, agora complica ainda mais (rs). Aparentemente está tudo ok no seu código. O mapeamento do controller está correto o formulário também, e o endereço http://localhost:8080/casadocodigo/carrinho/add era de fato onde precisava cair.

Dê uma olhada nos logs quando sobe o servidor, e tente verificar os mapeamentos das action do seu controller. Poste aqui pra gente ver.

Precisava de uma olhada com mais detalhes .. Se possível, coloque seu código em um repositório no github e compartilhe com a gente. Assim conseguimos investigar melhor.

Olá Fernando Matté, obrigado pela sua dica, mas infelizmente essa action me direciona para:

http://localhost:8080/casadocodigo/casadocodigo/produtos

o Spring deveria detectar quando fosse para carrinho/add e me enviar para /produtos novamente.

Rafael,

Estou de saída agora. Mas ainda hoje eu faço o que você me pediu e a gente soluciona essa birosca haha.

Abraços.

kkk

Ok Renato ..

Montando o mapeamento pelo código, o contexto do projeto + request mapping base da classe controller + request mapping especifico da action deveria atender normalmente em localhost:8080/casadocodigo/carrinho/add. Depois de adicionado no carrinho faria o redirect pra listagem de produtos.

Verifique se o pacote onde está essa classe está sendo escaneado pelo Spring. Se por acidente ele estiver fora de um pacote conhecido pelo container do Spring, ele não acha, instancia e nem mapeia qualquer action dentro da classe.

Olá, segue repositório no Github

https://github.com/renatocsare/spring

Até agora não consegui resolver, agradeço àqueles que dispenderem tempo para achar esse problema.

Aqui vai o log de inicialização do servidor:

jan 19, 2017 12:04:52 AM org.apache.tomcat.util.digester.SetPropertiesRule begin
ADVERTÊNCIA: [SetPropertiesRule]{Server/Service/Engine/Host/Context} Setting property 'source' to 'org.eclipse.jst.jee.server:casadocodigo' did not find a matching property.
jan 19, 2017 12:04:52 AM org.apache.catalina.startup.VersionLoggerListener log
INFORMAÇÕES: Server version:        Apache Tomcat/7.0.73
jan 19, 2017 12:04:52 AM org.apache.catalina.startup.VersionLoggerListener log
INFORMAÇÕES: Server built:          Nov 7 2016 21:27:23 UTC
jan 19, 2017 12:04:52 AM org.apache.catalina.startup.VersionLoggerListener log
INFORMAÇÕES: Server number:         7.0.73.0
jan 19, 2017 12:04:52 AM org.apache.catalina.startup.VersionLoggerListener log
INFORMAÇÕES: OS Name:               Windows 10
jan 19, 2017 12:04:52 AM org.apache.catalina.startup.VersionLoggerListener log
INFORMAÇÕES: OS Version:            10.0
jan 19, 2017 12:04:52 AM org.apache.catalina.startup.VersionLoggerListener log
INFORMAÇÕES: Architecture:          amd64
jan 19, 2017 12:04:52 AM org.apache.catalina.startup.VersionLoggerListener log
INFORMAÇÕES: Java Home:             C:\Program Files\Java\jre1.8.0_112
jan 19, 2017 12:04:52 AM org.apache.catalina.startup.VersionLoggerListener log
INFORMAÇÕES: JVM Version:           1.8.0_112-b15
jan 19, 2017 12:04:52 AM org.apache.catalina.startup.VersionLoggerListener log
INFORMAÇÕES: JVM Vendor:            Oracle Corporation
jan 19, 2017 12:04:52 AM org.apache.catalina.startup.VersionLoggerListener log
INFORMAÇÕES: CATALINA_BASE:         C:\Users\renat\workspace\Spring2\.metadata\.plugins\org.eclipse.wst.server.core\tmp0
jan 19, 2017 12:04:52 AM org.apache.catalina.startup.VersionLoggerListener log
INFORMAÇÕES: CATALINA_HOME:         D:\Tomcat7
jan 19, 2017 12:04:52 AM org.apache.catalina.startup.VersionLoggerListener log
INFORMAÇÕES: Command line argument: -Dcatalina.base=C:\Users\renat\workspace\Spring2\.metadata\.plugins\org.eclipse.wst.server.core\tmp0
jan 19, 2017 12:04:52 AM org.apache.catalina.startup.VersionLoggerListener log
INFORMAÇÕES: Command line argument: -Dcatalina.home=D:\Tomcat7
jan 19, 2017 12:04:52 AM org.apache.catalina.startup.VersionLoggerListener log
INFORMAÇÕES: Command line argument: -Dwtp.deploy=C:\Users\renat\workspace\Spring2\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps
jan 19, 2017 12:04:52 AM org.apache.catalina.startup.VersionLoggerListener log
INFORMAÇÕES: Command line argument: -Djava.endorsed.dirs=D:\Tomcat7\endorsed
jan 19, 2017 12:04:52 AM org.apache.catalina.startup.VersionLoggerListener log
INFORMAÇÕES: Command line argument: -Dfile.encoding=Cp1252
jan 19, 2017 12:04:52 AM org.apache.catalina.core.AprLifecycleListener lifecycleEvent
INFORMAÇÕES: The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: C:\Program Files\Java\jre1.8.0_112\bin;C:\WINDOWS\Sun\Java\bin;C:\WINDOWS\system32;C:\WINDOWS;C:/Program Files/Java/jre1.8.0_112/bin/server;C:/Program Files/Java/jre1.8.0_112/bin;C:/Program Files/Java/jre1.8.0_112/lib/amd64;C:\ProgramData\Oracle\Java\javapath;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\Program Files\VDownloader;C:\Program Files (x86)\NVIDIA Corporation\PhysX\Common;C:\Program Files (x86)\GtkSharp\2.12\bin;C:\Program Files (x86)\Windows Live\Shared;C:\Program Files (x86)\QuickTime\QTSystem\;C:\Program Files (x86)\Skype\Phone\;C:\Program Files (x86)\Calibre2\; %JAVA_HOME%\bin;C:\Program Files\WorldPainter;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\Program Files (x86)\Brackets\command;C:\Program Files\nodejs\;C:\Program Files\MySQL\MySQL Utilities 1.6\;C:\Program Files\Java\jdk1.7.0_80\bin;C:\Users\renat\AppData\Local\Microsoft\WindowsApps;C:\Users\renat\AppData\Roaming\npm;C:\Users\renat\Downloads\eclipse-jee-neon-2-win32-x86_64\eclipse;;.
jan 19, 2017 12:04:53 AM org.apache.coyote.AbstractProtocol init
INFORMAÇÕES: Initializing ProtocolHandler ["http-bio-8080"]
jan 19, 2017 12:04:53 AM org.apache.coyote.AbstractProtocol init
INFORMAÇÕES: Initializing ProtocolHandler ["ajp-bio-8009"]
jan 19, 2017 12:04:53 AM org.apache.catalina.startup.Catalina load
INFORMAÇÕES: Initialization processed in 1353 ms
jan 19, 2017 12:04:53 AM org.apache.catalina.core.StandardService startInternal
INFORMAÇÕES: Starting service Catalina
jan 19, 2017 12:04:53 AM org.apache.catalina.core.StandardEngine startInternal
INFORMAÇÕES: Starting Servlet Engine: Apache Tomcat/7.0.73
jan 19, 2017 12:04:53 AM org.apache.catalina.util.SessionIdGeneratorBase createSecureRandom
INFORMAÇÕES: Creation of SecureRandom instance for session ID generation using [SHA1PRNG] took [157] milliseconds.
jan 19, 2017 12:04:56 AM org.apache.catalina.startup.TldConfig execute
INFORMAÇÕES: At least one JAR was scanned for TLDs yet contained no TLDs. Enable debug logging for this logger for a complete list of JARs that were scanned but no TLDs were found in them. Skipping unneeded JARs during scanning can improve startup time and JSP compilation time.
jan 19, 2017 12:04:56 AM org.apache.catalina.core.ApplicationContext log
INFORMAÇÕES: Spring WebApplicationInitializers detected on classpath: [br.com.casadocodigo.loja.conf.ServletSpringMVC@7df3b525]
log4j:WARN No appenders could be found for logger (br.com.casadocodigo.loja.conf.ServletSpringMVC).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
jan 19, 2017 12:04:56 AM org.apache.catalina.core.ApplicationContext log
INFORMAÇÕES: Initializing Spring FrameworkServlet 'dispatcher'
jan 19, 2017 12:05:02 AM org.apache.coyote.AbstractProtocol start
INFORMAÇÕES: Starting ProtocolHandler ["http-bio-8080"]
jan 19, 2017 12:05:02 AM org.apache.coyote.AbstractProtocol start
INFORMAÇÕES: Starting ProtocolHandler ["ajp-bio-8009"]
jan 19, 2017 12:05:02 AM org.apache.catalina.startup.Catalina start
INFORMAÇÕES: Server startup in 9328 ms

Grato desde já!

Opa! O erro mudou, mas não sei o que fiz haha

HTTP Status 500 - Request processing failed; nested exception is javax.persistence.NoResultException: No entity found for query

O sysout dentro do método add da classe CarrinhoComprasController apareceu no log agora!

REDIRECIONANDO PARA PRODUTOS!
Hibernate: select distinct produto0_.id as id1_0_, produto0_.dataLancamento as dataLanc2_0_, produto0_.descricao as descrica3_0_, produto0_.paginas as paginas4_0_, produto0_.sumarioPath as sumarioP5_0_, produto0_.titulo as titulo6_0_, precos1_.Produto_id as Produto_1_0_0__, precos1_.tipo as tipo2_1_0__, precos1_.valor as valor3_1_0__ from Produto produto0_ inner join Produto_precos precos1_ on produto0_.id=precos1_.Produto_id where produto0_.id=?
jan 19, 2017 12:21:38 AM org.apache.catalina.core.StandardWrapperValve invoke
GRAVE: Servlet.service() for servlet [dispatcher] in context with path [/casadocodigo] threw exception [Request processing failed; nested exception is javax.persistence.NoResultException: No entity found for query] with root cause
javax.persistence.NoResultException: No entity found for query
    at org.hibernate.jpa.internal.QueryImpl.getSingleResult(QueryImpl.java:498)
    at br.com.casadocodigo.loja.daos.ProdutoDAO.find(ProdutoDAO.java:32)
    at br.com.casadocodigo.loja.daos.ProdutoDAO$$FastClassBySpringCGLIB$$92ebe7c5.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:717)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
    at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:98)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:266)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:95)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:653)
    at br.com.casadocodigo.loja.daos.ProdutoDAO$$EnhancerBySpringCGLIB$$d7f7c0c5.find(<generated>)
    at br.com.casadocodigo.loja.controllers.CarrinhosComprasController.criaItem(CarrinhosComprasController.java:37)
    at br.com.casadocodigo.loja.controllers.CarrinhosComprasController.add(CarrinhosComprasController.java:31)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.springframework.web.method.support.InvocableHandlerMethod.invoke(InvocableHandlerMethod.java:215)
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:132)
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:104)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandleMethod(RequestMappingHandlerAdapter.java:781)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:721)
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:83)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:943)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:877)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:961)
    at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:863)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:650)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:837)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:731)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:88)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:218)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:122)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:505)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:169)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:958)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:452)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1087)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:637)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:318)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Unknown Source)

Parece ser algum problema no método criaItem, na hora de fazer o find no produtoDAO...

Opa Renato,

Que bom que mudou. Não consegui dar uma olhada no código ainda, mas mudança de erro já é animador rs.

Isso mesmo, NoResultException (JPA) já é lá na outra ponta, significa que o produto buscado pela query (método find do ProdutoDao) não está presente na base com esse id, como mostra o trecho:

javax.persistence.NoResultException: No entity found for query
    at org.hibernate.jpa.internal.QueryImpl.getSingleResult(QueryImpl.java:498)
    at br.com.casadocodigo.loja.daos.ProdutoDAO.find(ProdutoDAO.java:32)

Verifique se de fato o produto existe na base. Caso exista, verifique como está chegando esse id na sua action do controller, e se a página está enviando devidamente pelo form. Podem ser essas as razões do problema.

Abraço

O produtoId e o tipoPreco estão NULL no método:

ModelAndView add(Integer produtoId, TipoPreco tipoPreco)

Provavelmente o problema é na hora no formulário, quando aperta o botão comprar não está passando o id do produto...

Eu infelizmente ainda não consegui uma solução para esse problema. Estou travado no curso "/

Opa Renato,

Vou testar o código localmente pra ver se descubro.

solução!

Fala Renato,

Na verdade nem vai precisar. Peguei o problema do formulário.

Dê uma olhada nos <input> do formulário:

<input type="hidden" value="${produto.id}" value="produtoId" />

 ...
<input type="radio" name="tipo" class="variant-radio" id="tipo" value="${preco.tipo}"  checked="checked"  />

Agora veja a action do controller:

@RequestMapping("/add")
public ModelAndView add(Integer produtoId, TipoPreco tipoPreco) { ... }

Perceba que no primeiro input citado nao existe name .. ele está com dois values. Acredito que no lugar do segundo value você gostaria de ter colocado name, assim bateria exatamente com o que espera receber na action (Integer produtoId).

No segundo até existe name, porém perceba que está diferente do que você espera receber na action. O name do input é "tipo", enquanto na action você denomina "tipoPreco".

Fazendo esses ajustes já deve funcionar. Abraço

Voilá!

Problema resolvido Rafael Rollo! Muito obrigado e grande abraço.