I am creating a basic Spring MVC + Repositories + Security configuration.
I leveraged THIS GUIDE and got to the configuration I am reporting below.
According to that configuration, I would expect some welcome page to show up at localhost:8080/HPLAN/welcome
; I also get redirected to that URL after typing localhost:8080/HPLAN/
, but I always get a 404 error. Server log does not receive any request (server log does not show any "no request mapping"). At the deployment location "HPLAN" folder is present.
I also need to mention that database tables are NOT created.
So, my configuration is this:
Security
@Configuration @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { @SuppressWarnings("unused") @Autowired private DataSource dataSource; @Autowired private CustomUserDetailsService customUserDetailsService; @Override protected void configure(AuthenticationManagerBuilder registry) throws Exception { registry.userDetailsService(customUserDetailsService); } @Override public void configure(WebSecurity web) throws Exception { web.ignoring().antMatchers("/resources/**"); // #3 } @Override protected void configure(HttpSecurity http) throws Exception { http.csrf().disable().authorizeRequests().antMatchers("/login", "/login/form**", "/register", "/logout") .permitAll() // #4 .antMatchers("/admin", "/admin/**").hasRole("ADMIN") // #6 .anyRequest().authenticated() // 7 .and().formLogin() // #8 .loginPage("/login/form") // #9 .loginProcessingUrl("/login").failureUrl("/login/form?error").permitAll(); // #5 }
}
Persistence
@Configuration @EnableTransactionManagement @EnableJpaRepositories(basePackages = "com.tek4b.hplan.repositories") public class PersistenceConfig { @Autowired private Environment env; @Value("${init-db:false}") private String initDatabase; @Bean public PlatformTransactionManager transactionManager() { EntityManagerFactory factory = entityManagerFactory().getObject(); return new JpaTransactionManager(factory); } @Bean public LocalContainerEntityManagerFactoryBean entityManagerFactory() { LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean(); HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter(); vendorAdapter.setGenerateDdl(Boolean.TRUE); vendorAdapter.setShowSql(Boolean.TRUE); factory.setDataSource(dataSource()); factory.setJpaVendorAdapter(vendorAdapter); factory.setPackagesToScan("com.tek4b.hplan.entities"); Properties jpaProperties = new Properties(); jpaProperties.put("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto")); factory.setJpaProperties(jpaProperties); factory.afterPropertiesSet(); factory.setLoadTimeWeaver(new InstrumentationLoadTimeWeaver()); return factory; } @Bean public HibernateExceptionTranslator hibernateExceptionTranslator() { return new HibernateExceptionTranslator(); } @Bean public DataSource dataSource() { BasicDataSource dataSource = new BasicDataSource(); dataSource.setDriverClassName(env.getProperty("jdbc.driverClassName")); dataSource.setUrl(env.getProperty("jdbc.url")); dataSource.setUsername(env.getProperty("jdbc.username")); dataSource.setPassword(env.getProperty("jdbc.password")); return dataSource; } @Bean public DataSourceInitializer dataSourceInitializer(DataSource dataSource) { DataSourceInitializer dataSourceInitializer = new DataSourceInitializer(); dataSourceInitializer.setDataSource(dataSource); ResourceDatabasePopulator databasePopulator = new ResourceDatabasePopulator(); databasePopulator.addScript(new ClassPathResource("db.sql")); dataSourceInitializer.setDatabasePopulator(databasePopulator); dataSourceInitializer.setEnabled(Boolean.parseBoolean(initDatabase)); return dataSourceInitializer; }
}
AppConfig
@Configuration @ComponentScan(basePackages = { "com.tek4b.hplan" }, excludeFilters = @ComponentScan.Filter(type = FilterType.REGEX, pattern = { "com.tek4b.hplan.web.*" }) ) @PropertySource(value = { "classpath:application.properties" }) @EnableScheduling @EnableAspectJAutoProxy @EnableCaching public class AppConfig { @Autowired private Environment env; @Bean public static PropertySourcesPlaceholderConfigurer placeHolderConfigurer() { return new PropertySourcesPlaceholderConfigurer(); } @Bean public CacheManager cacheManager() { return new ConcurrentMapCacheManager(); }
}
MVC:
@Configuration @ComponentScan(basePackages = { "com.tek4b.hplan.web" }) @EnableWebMvc public class WebMvcConfig extends WebMvcConfigurerAdapter { @Override public void addViewControllers(ViewControllerRegistry registry) { super.addViewControllers(registry); registry.addViewController("login/form").setViewName("login"); registry.addViewController("welcome").setViewName("welcome"); registry.addViewController("admin").setViewName("admin"); } @Bean public ViewResolver resolver() { InternalResourceViewResolver url = new InternalResourceViewResolver(); url.setPrefix("/WEB-INF/jsp/"); url.setSuffix(".jsp"); return url; } @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/resources/**").addResourceLocations("/resources/"); } @Override public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) { configurer.enable(); } @Bean(name = "messageSource") public MessageSource configureMessageSource() { ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource(); messageSource.setBasename("classpath:messages"); messageSource.setCacheSeconds(5); messageSource.setDefaultEncoding("UTF-8"); return messageSource; } @Bean public SimpleMappingExceptionResolver simpleMappingExceptionResolver() { SimpleMappingExceptionResolver b = new SimpleMappingExceptionResolver(); Properties mappings = new Properties(); mappings.put("org.springframework.dao.DataAccessException", "error"); b.setExceptionMappings(mappings); return b; }
}
Web.xml
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0"> <display-name>HPLAN</display-name>
My project structure:
I created the database and the server seems to start correctly:
Aug 13, 2015 7:26:11 PM org.apache.catalina.core.AprLifecycleListener init
INFO: The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: <hidden by me>;.
Aug 13, 2015 7:26:11 PM org.apache.tomcat.util.digester.SetPropertiesRule begin
WARNING: [SetPropertiesRule]{Server/Service/Engine/Host/Context} Setting property 'source' to 'org.eclipse.jst.jee.server:HPLAN' did not find a matching property.
Aug 13, 2015 7:26:11 PM org.apache.coyote.AbstractProtocol init
INFO: Initializing ProtocolHandler ["http-bio-8080"]
Aug 13, 2015 7:26:11 PM org.apache.coyote.AbstractProtocol init
INFO: Initializing ProtocolHandler ["ajp-bio-8009"]
Aug 13, 2015 7:26:11 PM org.apache.catalina.startup.Catalina load
INFO: Initialization processed in 694 ms
Aug 13, 2015 7:26:11 PM org.apache.catalina.core.StandardService startInternal
INFO: Starting service Catalina
Aug 13, 2015 7:26:11 PM org.apache.catalina.core.StandardEngine startInternal
INFO: Starting Servlet Engine: Apache Tomcat/7.0.47
Aug 13, 2015 7:26:12 PM org.apache.catalina.util.SessionIdGenerator createSecureRandom
INFO: Creation of SecureRandom instance for session ID generation using [SHA1PRNG] took [281] milliseconds.
Aug 13, 2015 7:26:14 PM org.apache.catalina.core.ApplicationContext log
INFO: No Spring WebApplicationInitializer types detected on classpath
Aug 13, 2015 7:26:14 PM org.apache.coyote.AbstractProtocol start
INFO: Starting ProtocolHandler ["http-bio-8080"]
Aug 13, 2015 7:26:14 PM org.apache.coyote.AbstractProtocol start
INFO: Starting ProtocolHandler ["ajp-bio-8009"]
Aug 13, 2015 7:26:14 PM org.apache.catalina.startup.Catalina start
INFO: Server startup in 2767 ms
Then it stands like that regardless of my requests. What's wrong with it?
============UPDATE 6. AppInitializer class:
public class SpringWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class<?>[] { AppConfig.class };
}
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class<?>[] { WebMvcConfig.class };
}
@Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
@Override
protected Filter[] getServletFilters() {
return new Filter[] { new DelegatingFilterProxy("springSecurityFilterChain"),
new OpenEntityManagerInViewFilter() };
}
}