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

Erro 404 ao tentar cadastrar produto

Tudo funcionando bem até começar os exercícios do módulo 3 de Spring MVC-I. Ao acessar a for.jsp, preencher o formulário e clicar em "Cadastrar", recebo um erro 404. Onde errei?

package br.com.casadocodigo.loja.conf;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.view.InternalResourceViewResolver;

import br.com.casadocodigo.loja.controllers.HomeController;
import br.com.casadocodigo.loja.daos.ProdutoDAO;

@EnableWebMvc
@ComponentScan(basePackageClasses={HomeController.class, ProdutoDAO.class})
public class AppWebConfiguration {

    @Bean
    public InternalResourceViewResolver internalResourceViewResolver() {
        InternalResourceViewResolver resolver = new InternalResourceViewResolver();
        resolver.setPrefix("/WEB-INF/views/");
        resolver.setSuffix(".jsp");
        return resolver;
    }

}
package br.com.casadocodigo.loja.conf;

import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;

public class ServletsSpringMVC extends AbstractAnnotationConfigDispatcherServletInitializer{

    @Override
    protected Class<?>[] getRootConfigClasses() {
        return null;
    }

    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class[] {AppWebConfiguration.class, JPAConfiguration.class};
    }

    @Override
    protected String[] getServletMappings() {
        return new String [] {"/"};
    }

}
package br.com.casadocodigo.loja.controllers;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

import br.com.casadocodigo.loja.daos.ProdutoDAO;
import br.com.casadocodigo.loja.models.Produto;
import br.com.casadocodigo.loja.models.TipoPreco;

@Controller
public class ProdutosControllers {

    @Autowired
    private ProdutoDAO produtoDAO;

    @RequestMapping("/produtos/form")
    public ModelAndView form() {
        ModelAndView modelAndView = new ModelAndView("produtos/form");
        modelAndView.addObject("tipos", TipoPreco.values());
        return modelAndView;
    }

    @RequestMapping("/produtos/ok")
    public String gravar(Produto produto) {
        System.out.println(produto);
        produtoDAO.gravar(produto);
        return "produtos/ok";
    }

}
package br.com.casadocodigo.loja.conf;

import java.util.Properties;

import javax.persistence.EntityManagerFactory;

import org.springframework.context.annotation.Bean;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.JpaVendorAdapter;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.annotation.EnableTransactionManagement;

@EnableTransactionManagement
public class JPAConfiguration {

    @Bean
    public LocalContainerEntityManagerFactoryBean bean() {
        LocalContainerEntityManagerFactoryBean factoryBean = new LocalContainerEntityManagerFactoryBean();
        JpaVendorAdapter adapter = new HibernateJpaVendorAdapter();

        factoryBean.setJpaVendorAdapter(adapter);

        DriverManagerDataSource source = new DriverManagerDataSource();
        source.setUsername("root");
        source.setPassword("20acessar");
        source.setUrl("jdbc:mysql://localhost:3306/casadocodigo");
        source.setDriverClassName("com.mysql.jdbc.Driver");

        factoryBean.setDataSource(source);

        Properties props = new Properties();
        props.setProperty("hibernate.dialet", "org.hibernate.dialect.MySQL5Dialect");
        props.setProperty("hibernate.show_sql", "true");
        props.setProperty("hibernate.hbm2ddl.auto", "update");

        factoryBean.setJpaProperties(props);

        factoryBean.setPackagesToScan("br.com.casadocodigo.loja.models");

        return factoryBean;
    }

    @Bean
    public JpaTransactionManager transactionManager(EntityManagerFactory emf) {
        return new JpaTransactionManager(emf);
    }

}
package br.com.casadocodigo.loja.models;

import java.util.List;

import javax.persistence.ElementCollection;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Entity
public class Produto {

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private int id;

    private String titulo;
    private String descricao;
    private int paginas;

    @ElementCollection
    private List<Preco> precos;

    public int getId() {
        return id;
    }

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

    public List<Preco> getPrecos() {
        return precos;
    }

    public void setPrecos(List<Preco> precos) {
        this.precos = precos;
    }

    public String getTitulo() {
        return titulo;
    }

    public void setTitulo(String titulo) {
        this.titulo = titulo;
    }

    public String getDescricao() {
        return descricao;
    }

    public void setDescricao(String descricao) {
        this.descricao = descricao;
    }

    public int getPaginas() {
        return paginas;
    }

    public void setPaginas(int paginas) {
        this.paginas = paginas;
    }

    @Override
    public String toString() {
        return "Produto [titulo: " + titulo + ", descrição: " + descricao + ", páginas: " + paginas + "]";
    }

}
package br.com.casadocodigo.loja.models;

import java.math.BigDecimal;

import javax.persistence.Embeddable;

@Embeddable
public class Preco {

    private BigDecimal valor;
    private TipoPreco tipo;

    public BigDecimal getValor() {
        return valor;
    }

    public void setValor(BigDecimal valor) {
        this.valor = valor;
    }

    public TipoPreco getTipo() {
        return tipo;
    }

    public void setTipo(TipoPreco tipo) {
        this.tipo = tipo;
    }

}
package br.com.casadocodigo.loja.daos;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import br.com.casadocodigo.loja.models.Produto;

@Repository
@Transactional
public class ProdutoDAO {

    @PersistenceContext
    private EntityManager manager;

    public void gravar (Produto produto) {
        manager.persist(produto);
    }

}

Saída do terminal:

ago 24, 2016 12:50:24 PM 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.
ago 24, 2016 12:50:24 PM org.apache.catalina.startup.VersionLoggerListener log
INFORMAÇÕES: Server version:        Apache Tomcat/8.0.36
ago 24, 2016 12:50:24 PM org.apache.catalina.startup.VersionLoggerListener log
INFORMAÇÕES: Server built:          Jun 9 2016 13:55:50 UTC
ago 24, 2016 12:50:24 PM org.apache.catalina.startup.VersionLoggerListener log
INFORMAÇÕES: Server number:         8.0.36.0
ago 24, 2016 12:50:24 PM org.apache.catalina.startup.VersionLoggerListener log
INFORMAÇÕES: OS Name:               Windows 10
ago 24, 2016 12:50:24 PM org.apache.catalina.startup.VersionLoggerListener log
INFORMAÇÕES: OS Version:            10.0
ago 24, 2016 12:50:24 PM org.apache.catalina.startup.VersionLoggerListener log
INFORMAÇÕES: Architecture:          amd64
ago 24, 2016 12:50:24 PM org.apache.catalina.startup.VersionLoggerListener log
INFORMAÇÕES: Java Home:             C:\Program Files\Java\jre1.8.0_73
ago 24, 2016 12:50:24 PM org.apache.catalina.startup.VersionLoggerListener log
INFORMAÇÕES: JVM Version:           1.8.0_73-b02
ago 24, 2016 12:50:24 PM org.apache.catalina.startup.VersionLoggerListener log
INFORMAÇÕES: JVM Vendor:            Oracle Corporation
ago 24, 2016 12:50:24 PM org.apache.catalina.startup.VersionLoggerListener log
INFORMAÇÕES: CATALINA_BASE:         C:\Users\Adriano\workspace\Aprendizado\.metadata\.plugins\org.eclipse.wst.server.core\tmp0
ago 24, 2016 12:50:24 PM org.apache.catalina.startup.VersionLoggerListener log
INFORMAÇÕES: CATALINA_HOME:         C:\Users\Adriano\workspace\Armazém\apache-tomcat-8.0.36
ago 24, 2016 12:50:24 PM org.apache.catalina.startup.VersionLoggerListener log
INFORMAÇÕES: Command line argument: -Dcatalina.base=C:\Users\Adriano\workspace\Aprendizado\.metadata\.plugins\org.eclipse.wst.server.core\tmp0
ago 24, 2016 12:50:24 PM org.apache.catalina.startup.VersionLoggerListener log
INFORMAÇÕES: Command line argument: -Dcatalina.home=C:\Users\Adriano\workspace\Armazém\apache-tomcat-8.0.36
ago 24, 2016 12:50:24 PM org.apache.catalina.startup.VersionLoggerListener log
INFORMAÇÕES: Command line argument: -Dwtp.deploy=C:\Users\Adriano\workspace\Aprendizado\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps
ago 24, 2016 12:50:24 PM org.apache.catalina.startup.VersionLoggerListener log
INFORMAÇÕES: Command line argument: -Djava.endorsed.dirs=C:\Users\Adriano\workspace\Armazém\apache-tomcat-8.0.36\endorsed
ago 24, 2016 12:50:24 PM org.apache.catalina.startup.VersionLoggerListener log
INFORMAÇÕES: Command line argument: -Dfile.encoding=Cp1252
ago 24, 2016 12:50:24 PM 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_73\bin;C:\WINDOWS\Sun\Java\bin;C:\WINDOWS\system32;C:\WINDOWS;C:/Program Files/Java/jre1.8.0_73/bin/server;C:/Program Files/Java/jre1.8.0_73/bin;C:/Program Files/Java/jre1.8.0_73/lib/amd64;C:\ProgramData\Oracle\Java\javapath;C:\Program Files\Common Files\Microsoft Shared\Windows Live;C:\Program Files (x86)\Common Files\Microsoft Shared\Windows Live;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\Program Files (x86)\Windows Live\Shared;C:\Program Files (x86)\MySQL\MySQL Server 5.7\bin;C:\users\Adriano\workspace\Armazém\apache-maven-3.3.9\bin;C:\Program Files\Java\jdk1.8.0_65\bin;C:\Users\Adriano\AppData\Local\Microsoft\WindowsApps;;C:\Users\Adriano\jee-neon2\eclipse;;.
ago 24, 2016 12:50:25 PM org.apache.coyote.AbstractProtocol init
INFORMAÇÕES: Initializing ProtocolHandler ["http-nio-8080"]
ago 24, 2016 12:50:25 PM org.apache.tomcat.util.net.NioSelectorPool getSharedSelector
INFORMAÇÕES: Using a shared selector for servlet write/read
ago 24, 2016 12:50:25 PM org.apache.coyote.AbstractProtocol init
INFORMAÇÕES: Initializing ProtocolHandler ["ajp-nio-8009"]
ago 24, 2016 12:50:25 PM org.apache.tomcat.util.net.NioSelectorPool getSharedSelector
INFORMAÇÕES: Using a shared selector for servlet write/read
ago 24, 2016 12:50:25 PM org.apache.catalina.startup.Catalina load
INFORMAÇÕES: Initialization processed in 1021 ms
ago 24, 2016 12:50:25 PM org.apache.catalina.core.StandardService startInternal
INFORMAÇÕES: Starting service Catalina
ago 24, 2016 12:50:25 PM org.apache.catalina.core.StandardEngine startInternal
INFORMAÇÕES: Starting Servlet Engine: Apache Tomcat/8.0.36
ago 24, 2016 12:50:25 PM org.apache.catalina.util.SessionIdGeneratorBase createSecureRandom
INFORMAÇÕES: Creation of SecureRandom instance for session ID generation using [SHA1PRNG] took [103] milliseconds.
ago 24, 2016 12:50:28 PM org.apache.jasper.servlet.TldScanner scanJars
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.
ago 24, 2016 12:50:28 PM org.apache.catalina.core.ApplicationContext log
INFORMAÇÕES: Spring WebApplicationInitializers detected on classpath: [br.com.casadocodigo.loja.conf.ServletsSpringMVC@443dd65a]
log4j:WARN No appenders could be found for logger (br.com.casadocodigo.loja.conf.ServletsSpringMVC).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
ago 24, 2016 12:50:28 PM org.apache.catalina.core.ApplicationContext log
INFORMAÇÕES: Initializing Spring FrameworkServlet 'dispatcher'
ago 24, 2016 12:50:33 PM org.apache.coyote.AbstractProtocol start
INFORMAÇÕES: Starting ProtocolHandler ["http-nio-8080"]
ago 24, 2016 12:50:33 PM org.apache.coyote.AbstractProtocol start
INFORMAÇÕES: Starting ProtocolHandler ["ajp-nio-8009"]
ago 24, 2016 12:50:33 PM org.apache.catalina.startup.Catalina start
INFORMAÇÕES: Server startup in 8489 ms
Entrando na Home da Casa do Código.
9 respostas

Lembre-se de sempre incluir código entre dois grupos de três backticks ```, para facilitar a visualização. Editei seu post para incluir a formatação =)

Sem formatação:

public class ClasseA { public void metodoUm(String parametro) { return parametro + "-um"; } }

Com formatação:

public class ClasseA {
  public void metodoUm(String parametro) {
     return parametro + "-um";
  }
}

@Adriano, imagino que seu formulário na form.jsp esteja utilizando o método POST, certo? Tente então alterar o mapeamento da rota do formulário para

@RequestMapping(value="/produtos/ok", method=RequestMethod.POST)

Se isso não der certo, compartilhe a form.jsp também para podermos avaliar. Pode ser um problema na rota que você está usando no seu formulário. =)

Desculpa pela falta de formatação! Alterei a rota, mas agora recebo um erro 400. Eis meu form.jsp:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>

<!DOCTYPE html>
<html>
<head>
<title>Livros de Java, Android, iPhone, Ruby, PHP e muito mais -
    Casa do Código</title>
</head>

<body>

    <form action="/casadocodigo/produtos" method="post">

        <div>
            <label>Título</label> <input type="text" name="titulo" />
        </div>

        <div>
            <label>Descrição</label>
            <textarea rows="10" cols="20" name="descricao"></textarea>
        </div>

        <div>
            <label>Páginas</label> <input type="text" name="paginas" />
        </div>

        <c:forEach items="${tipos}" var="tipoPreco" varStatus="status">
            <div>
                <label>${tipoPreco}</label> <input type="text" name="precos[${status.index}].valor" />
                <input type="hidden" name="precos[${status.index}].tipo" value="${tipoPreco}" />
            </div>
        </c:forEach>

        <button type="submit">Cadastrar</button>

    </form>

</body>

</html>

@Adriano, pode compartilhar os registros de execução (LOGs) de quando ocorre o erro?

Enquanto isso, eu reparei que a ação do seu formulário é /casadocodigo/produtos:

<form action="/casadocodigo/produtos" method="post">

Essa rota não existe no seu controller, existe? Não encontrei no código que você compartilhou e isso devia estar causando o erro 404.

Tente alterar para /casadocodigo/produtos/ok ou /produtos/ok e veja se isso resolve seu problema.

Sr. Marco Salles, fiz as alterações propostas, mas todas resultaram em erro 404. Sobre a rota, fiz conforme ditado na vídeo-aula, logo deveriam estar funcionando. Aqui vão os logs, mas eles não são diferentes daqueles que enviei antes - aliás, o Eclipse sequer acusa o erro no console.

ago 24, 2016 3:08:55 PM 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.
ago 24, 2016 3:08:55 PM org.apache.catalina.startup.VersionLoggerListener log
INFORMAÇÕES: Server version:        Apache Tomcat/8.0.36
ago 24, 2016 3:08:55 PM org.apache.catalina.startup.VersionLoggerListener log
INFORMAÇÕES: Server built:          Jun 9 2016 13:55:50 UTC
ago 24, 2016 3:08:55 PM org.apache.catalina.startup.VersionLoggerListener log
INFORMAÇÕES: Server number:         8.0.36.0
ago 24, 2016 3:08:55 PM org.apache.catalina.startup.VersionLoggerListener log
INFORMAÇÕES: OS Name:               Windows 10
ago 24, 2016 3:08:55 PM org.apache.catalina.startup.VersionLoggerListener log
INFORMAÇÕES: OS Version:            10.0
ago 24, 2016 3:08:55 PM org.apache.catalina.startup.VersionLoggerListener log
INFORMAÇÕES: Architecture:          amd64
ago 24, 2016 3:08:55 PM org.apache.catalina.startup.VersionLoggerListener log
INFORMAÇÕES: Java Home:             C:\Program Files\Java\jre1.8.0_73
ago 24, 2016 3:08:55 PM org.apache.catalina.startup.VersionLoggerListener log
INFORMAÇÕES: JVM Version:           1.8.0_73-b02
ago 24, 2016 3:08:55 PM org.apache.catalina.startup.VersionLoggerListener log
INFORMAÇÕES: JVM Vendor:            Oracle Corporation
ago 24, 2016 3:08:55 PM org.apache.catalina.startup.VersionLoggerListener log
INFORMAÇÕES: CATALINA_BASE:         C:\Users\Adriano\workspace\Aprendizado\.metadata\.plugins\org.eclipse.wst.server.core\tmp0
ago 24, 2016 3:08:55 PM org.apache.catalina.startup.VersionLoggerListener log
INFORMAÇÕES: CATALINA_HOME:         C:\Users\Adriano\workspace\Armazém\apache-tomcat-8.0.36
ago 24, 2016 3:08:55 PM org.apache.catalina.startup.VersionLoggerListener log
INFORMAÇÕES: Command line argument: -Dcatalina.base=C:\Users\Adriano\workspace\Aprendizado\.metadata\.plugins\org.eclipse.wst.server.core\tmp0
ago 24, 2016 3:08:55 PM org.apache.catalina.startup.VersionLoggerListener log
INFORMAÇÕES: Command line argument: -Dcatalina.home=C:\Users\Adriano\workspace\Armazém\apache-tomcat-8.0.36
ago 24, 2016 3:08:55 PM org.apache.catalina.startup.VersionLoggerListener log
INFORMAÇÕES: Command line argument: -Dwtp.deploy=C:\Users\Adriano\workspace\Aprendizado\.metadata\.plugins\org.eclipse.wst.server.core\tmp0\wtpwebapps
ago 24, 2016 3:08:55 PM org.apache.catalina.startup.VersionLoggerListener log
INFORMAÇÕES: Command line argument: -Djava.endorsed.dirs=C:\Users\Adriano\workspace\Armazém\apache-tomcat-8.0.36\endorsed
ago 24, 2016 3:08:55 PM org.apache.catalina.startup.VersionLoggerListener log
INFORMAÇÕES: Command line argument: -Dfile.encoding=Cp1252
ago 24, 2016 3:08:55 PM 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_73\bin;C:\WINDOWS\Sun\Java\bin;C:\WINDOWS\system32;C:\WINDOWS;C:/Program Files/Java/jre1.8.0_73/bin/server;C:/Program Files/Java/jre1.8.0_73/bin;C:/Program Files/Java/jre1.8.0_73/lib/amd64;C:\ProgramData\Oracle\Java\javapath;C:\Program Files\Common Files\Microsoft Shared\Windows Live;C:\Program Files (x86)\Common Files\Microsoft Shared\Windows Live;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\Program Files (x86)\Windows Live\Shared;C:\Program Files (x86)\MySQL\MySQL Server 5.7\bin;C:\users\Adriano\workspace\Armazém\apache-maven-3.3.9\bin;C:\Program Files\Java\jdk1.8.0_65\bin;C:\Users\Adriano\AppData\Local\Microsoft\WindowsApps;;C:\Users\Adriano\jee-neon2\eclipse;;.
ago 24, 2016 3:08:55 PM org.apache.coyote.AbstractProtocol init
INFORMAÇÕES: Initializing ProtocolHandler ["http-nio-8080"]
ago 24, 2016 3:08:55 PM org.apache.tomcat.util.net.NioSelectorPool getSharedSelector
INFORMAÇÕES: Using a shared selector for servlet write/read
ago 24, 2016 3:08:55 PM org.apache.coyote.AbstractProtocol init
INFORMAÇÕES: Initializing ProtocolHandler ["ajp-nio-8009"]
ago 24, 2016 3:08:55 PM org.apache.tomcat.util.net.NioSelectorPool getSharedSelector
INFORMAÇÕES: Using a shared selector for servlet write/read
ago 24, 2016 3:08:55 PM org.apache.catalina.startup.Catalina load
INFORMAÇÕES: Initialization processed in 996 ms
ago 24, 2016 3:08:55 PM org.apache.catalina.core.StandardService startInternal
INFORMAÇÕES: Starting service Catalina
ago 24, 2016 3:08:55 PM org.apache.catalina.core.StandardEngine startInternal
INFORMAÇÕES: Starting Servlet Engine: Apache Tomcat/8.0.36
ago 24, 2016 3:08:56 PM org.apache.catalina.util.SessionIdGeneratorBase createSecureRandom
INFORMAÇÕES: Creation of SecureRandom instance for session ID generation using [SHA1PRNG] took [104] milliseconds.
ago 24, 2016 3:08:58 PM org.apache.jasper.servlet.TldScanner scanJars
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.
ago 24, 2016 3:08:58 PM org.apache.catalina.core.ApplicationContext log
INFORMAÇÕES: Spring WebApplicationInitializers detected on classpath: [br.com.casadocodigo.loja.conf.ServletsSpringMVC@6bd71c75]
log4j:WARN No appenders could be found for logger (br.com.casadocodigo.loja.conf.ServletsSpringMVC).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
ago 24, 2016 3:08:59 PM org.apache.catalina.core.ApplicationContext log
INFORMAÇÕES: Initializing Spring FrameworkServlet 'dispatcher'
ago 24, 2016 3:09:03 PM org.apache.coyote.AbstractProtocol start
INFORMAÇÕES: Starting ProtocolHandler ["http-nio-8080"]
ago 24, 2016 3:09:03 PM org.apache.coyote.AbstractProtocol start
INFORMAÇÕES: Starting ProtocolHandler ["ajp-nio-8009"]
ago 24, 2016 3:09:03 PM org.apache.catalina.startup.Catalina start
INFORMAÇÕES: Server startup in 7694 ms

Aí resolvi refazer conforme mostrado no curso e recebi erro 400 ao invés de 404.

Oi Adriano,

Verifique se sua JSP está dentro de src/main/webapp/WEB-INF/views/produtos/ok.jsp

Se estiver, precisaremos ver o que aconteceu com o 400 mais de perto. Quando o 400 acontecer, pega o StackTrace do Console do Eclipse e cola aqui por favor. Não precisa ser esse de subida do servidor, só a Exception mesmo que der.

Se não der nenhuma exception, ai preciso que coloque seu código no github para poder dar uma olhada mais a fundo.

Sobre o mapeamento, o certo é manter o controller só com produtos e no form do JSP colocaria apenas produtos também, assim:

@RequestMapping("/produtos")
public String gravar(Produto produto) {
    // código aqui dentro
    return "produtos/ok";
}

E no formulário:

<form action="/casadocodigo/produtos" method="post">

Abraço

solução!

Olá instrutor Paulo!

Tudo está em seu devido lugar: jsp's, classes... Procurei em outros fóruns e no YouTube, mas também não achei uma solução - sem falar que no GUJ tinham dois usuários com o mesmo problema, sem solução também. Então eu resolvi refazer o projeto todo na unha, sem usar o JBoss Forge, via Maven seco. Segui todos os passos de tuas vídeo aulas e... deu certo!

Obrigado a todos pela força!

Poxa Adriano, sinto muito.

Mas que bom que está conseguindo evoluir agora. Qualquer dúvida estou a disposição.

Abraço

Esquenta não, mestre! O curso é bom e estou evoluindo.