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.