I'm worked with Spring in the past on a big project, but I've never started a Spring MVC web app from scratch.
Well that's what I'm currently doing now for practice as I have a project coming up that will require it.
I was successfully able to make a simple Spring MVC Web App that used .JSP pages (using annotations, no XML). I wanted to use Thymeleaf though and started my conversion process to that.
Well now I'm getting a 404 Error and my HomeController class isn't even being hit it seems like.
I get no errors in the Console output.
I've Google search, read through tutorials, and code samples. Second pair of eyes would be nice. Thanks! :)
Note: going from .JSP to Thymeleaf the only changes made was the addition of the ThymeleafConfig class. I don't see how it went from working to not working.
Here's my code:
WebInit.java
public class WebInit implements WebApplicationInitializer { @Override public void onStartup(ServletContext servletContext) throws ServletException { // Creates the root application context AnnotationConfigWebApplicationContext appContext = new AnnotationConfigWebApplicationContext(); appContext.register(ServletConfig.class); appContext.setDisplayName("REPLACE ME"); appContext.setConfigLocation("com.demo.config"); // Creates the Spring Container shared by all Servlets and Filters servletContext.addListener(new ContextLoaderListener(appContext)); // Further configures the servlet context ServletRegistration.Dynamic dispatcher = servletContext.addServlet( "dispatcher", new DispatcherServlet(appContext)); dispatcher.setLoadOnStartup(1); dispatcher.setAsyncSupported(true); dispatcher.addMapping("/"); } } ServetConfig.java
@Configuration @Import(WebConfig.class) @ImportResource({/*"classpath:META-INF/spring/persistence-context.xml"*/}) public class ServletConfig { } WebConfig.java
@Configuration @ComponentScan("com.illinois.dnr") @EnableAspectJAutoProxy @EnableWebMvc @Import({ThymeleafConfig.class}) public class WebConfig extends WebMvcConfigurerAdapter { // Maps resources path to webapp/resources @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/resources/**").addResourceLocations( "/resources/"); } // Provides internationalization of messages @Bean public ResourceBundleMessageSource messageSource() { ResourceBundleMessageSource source = new ResourceBundleMessageSource(); source.setBasename("messages"); return source; } } Thymeleaf.java
@Configuration public class ThymeleafConfig { @Bean public ServletContextTemplateResolver templateResolver() { ServletContextTemplateResolver resolver = new ServletContextTemplateResolver(); resolver.setPrefix("/WEB-INF/views/"); resolver.setSuffix(".html"); resolver.setTemplateMode("HTML5"); resolver.setOrder(1); return resolver; } @Bean public SpringTemplateEngine templateEngine() { SpringTemplateEngine engine = new SpringTemplateEngine(); engine.setTemplateResolver(templateResolver()); return engine; } @Bean public ThymeleafViewResolver thymeleafViewResolver() { ThymeleafViewResolver resolver = new ThymeleafViewResolver(); resolver.setTemplateEngine(templateEngine()); return resolver; } } HomeController.java
@Controller public class HomeController { private static final Logger logger = LoggerFactory.getLogger(HomeController.class); /** * Simply selects the home view to render by returning its name. */ @RequestMapping(value = "/dnr", method = RequestMethod.GET) public String home(Locale locale, Model model) { logger.info("Welcome home! The client locale is {}.", locale); Date date = new Date(); DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale); String formattedDate = dateFormat.format(date); model.addAttribute("serverTime", formattedDate); return "home"; } @RequestMapping(value = "/login", method = RequestMethod.GET) public String loginPage(Locale locale, Model model) { logger.info("Login"); return "login"; } @RequestMapping(value = "/home", method = RequestMethod.POST) public String login(@Validated User user, Model model) { model.addAttribute("userName", user.getUserName()); logger.info("User"); return "user"; } @RequestMapping(value = { "/", "/welcome**" }, method = RequestMethod.GET) public ModelAndView welcomePage() { ModelAndView model = new ModelAndView(); model.addObject("title", "Spring Security Hello World"); model.addObject("message", "This is welcome page!"); model.setViewName("hello"); logger.info("Hello"); return model; } @RequestMapping(value = "/admin**", method = RequestMethod.GET) public ModelAndView adminPage() { ModelAndView model = new ModelAndView(); model.addObject("title", "Spring Security Hello World"); model.addObject("message", "This is protected page - Admin Page!"); model.setViewName("admin"); logger.info("admin"); return model; } @RequestMapping(value = "/dba**", method = RequestMethod.GET) public ModelAndView dbaPage() { ModelAndView model = new ModelAndView(); model.addObject("title", "Spring Security Hello World"); model.addObject("message", "This is protected page - Database Page!"); model.setViewName("admin"); logger.info("dba"); return model; } }
System.out.println()'s in yourThymeleafConfig` methods to make sure they are running. Are all your Thymeleaf templates in WEB-INF/views?