SJS SJS - 2 days ago 4
Java Question

Why did my project need a applicationContext.xml for Spring Security with JavaConfig

I had a Spring MVC project that was using XML for all the config stuff but I remove all the XML and made them into JavaConfig (Everything but Spring Security). Once I try to get Spring Security working I could see that my project was blowing up looking for applicationContext.xml in WEB.INF. I dont have anything pointing to that so who do I need it>?

my secuirty.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/security"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/security
http://www.springframework.org/schema/security/spring-security-3.1.xsd">


<global-method-security pre-post-annotations="enabled" />

<http use-expressions="true">
<intercept-url access="hasRole('ROLE_VERIFIED_MEMBER')" pattern="/mrequest**" />
<intercept-url pattern='/*' access='permitAll' />
<form-login default-target-url="/visit" />

<logout logout-success-url="/" />
</http>

<authentication-manager>
<authentication-provider>
<user-service>
<user name="cpilling04@aol.com.dev" password="testing" authorities="ROLE_VERIFIED_MEMBER" />
</user-service>

</authentication-provider>
</authentication-manager>
</beans:beans>


Here is my webconfig:

@Configuration
@EnableWebMvc
@Import(DatabaseConfig.class)
@ImportResource("/WEB-INF/spring/secuirty.xml")
public class WebMVCConfig extends WebMvcConfigurerAdapter {

private static final String MESSAGE_SOURCE = "/WEB-INF/classes/messages";

private static final Logger logger = LoggerFactory.getLogger(WebMVCConfig.class);



@Bean
public ViewResolver resolver() {
UrlBasedViewResolver url = new UrlBasedViewResolver();
url.setPrefix("/WEB-INF/view/");
url.setViewClass(JstlView.class);
url.setSuffix(".jsp");
return url;
}


@Bean(name = "messageSource")
public MessageSource configureMessageSource() {
logger.debug("setting up message source");
ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
messageSource.setBasename(MESSAGE_SOURCE);
messageSource.setCacheSeconds(5);
messageSource.setDefaultEncoding("UTF-8");
return messageSource;
}

@Bean
public LocaleResolver localeResolver() {
SessionLocaleResolver lr = new SessionLocaleResolver();
lr.setDefaultLocale(Locale.ENGLISH);
return lr;
}

@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
logger.debug("setting up resource handlers");
registry.addResourceHandler("/resources/").addResourceLocations("/resources/**");
}

@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
logger.debug("configureDefaultServletHandling");
configurer.enable();
}

@Override
public void addInterceptors(final InterceptorRegistry registry) {
registry.addInterceptor(new LocaleChangeInterceptor());
}

@Bean
public SimpleMappingExceptionResolver simpleMappingExceptionResolver() {
SimpleMappingExceptionResolver b = new SimpleMappingExceptionResolver();

Properties mappings = new Properties();
mappings.put("org.springframework.web.servlet.PageNotFound", "p404");
mappings.put("org.springframework.dao.DataAccessException", "dataAccessFailure");
mappings.put("org.springframework.transaction.TransactionException", "dataAccessFailure");
b.setExceptionMappings(mappings);
return b;
}

@Bean
public RequestTrackerConfig requestTrackerConfig()
{
RequestTrackerConfig tr = new RequestTrackerConfig();
tr.setPassword("Waiting#$");
tr.setUrl("https://uftwfrt01-dev.uftmasterad.org/REST/1.0");
tr.setUser("root");

return tr;
}


}


Here is my DatabaseConfig:

@Configuration
@EnableTransactionManagement
@ComponentScan(basePackages= "org.uftwf")
@PropertySource(value = "classpath:application.properties")
public class DatabaseConfig {


private static final Logger logger = LoggerFactory.getLogger(DatabaseConfig.class);


@Value("${jdbc.driverClassName}")
private String driverClassName;

@Value("${jdbc.url}")
private String url;

@Value("${jdbc.username}")
private String username;

@Value("${jdbc.password}")
private String password;

@Value("${hibernate.dialect}")
private String hibernateDialect;

@Value("${hibernate.show_sql}")
private String hibernateShowSql;

@Value("${hibernate.hbm2ddl.auto}")
private String hibernateHbm2ddlAuto;

@Bean
public PropertyPlaceholderConfigurer getPropertyPlaceholderConfigurer()
{
PropertyPlaceholderConfigurer ppc = new PropertyPlaceholderConfigurer();
ppc.setLocation(new ClassPathResource("application.properties"));
ppc.setIgnoreUnresolvablePlaceholders(true);
return ppc;
}



@Bean
public DataSource dataSource() {

try {
Context ctx = new InitialContext();
return (DataSource) ctx.lookup("java:jboss/datasources/mySQLDB");
}
catch (Exception e)
{

}

return null;
}

@Bean
public SessionFactory sessionFactory()
{

LocalSessionFactoryBean factoryBean = new LocalSessionFactoryBean();
factoryBean.setDataSource(dataSource());
factoryBean.setHibernateProperties(getHibernateProperties());
factoryBean.setPackagesToScan("org.uftwf.inquiry.model");

try {
factoryBean.afterPropertiesSet();
} catch (IOException e) {
logger.error(e.getMessage());
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}


return factoryBean.getObject();
}

@Bean
public Properties getHibernateProperties()
{
Properties hibernateProperties = new Properties();

hibernateProperties.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQL5Dialect");
hibernateProperties.setProperty("hibernate.show_sql", "true");

hibernateProperties.setProperty("hibernate.format_sql", "true");
hibernateProperties.setProperty("hibernate.hbm2ddl.auto", "update");

hibernateProperties.setProperty("javax.persistence.validation.mode", "none");

//Audit History flags
hibernateProperties.setProperty("org.hibernate.envers.store_data_at_delete", "true");
hibernateProperties.setProperty("org.hibernate.envers.global_with_modified_flag", "true");

return hibernateProperties;
}



@Bean
public HibernateTransactionManager hibernateTransactionManager()
{
HibernateTransactionManager htm = new HibernateTransactionManager();
htm.setSessionFactory(sessionFactory());
htm.afterPropertiesSet();
return htm;
}


}


and my 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_2_5.xsd"
id="WebApp_ID" version="2.5">


<display-name>Inquiry</display-name>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>

<servlet>
<servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextClass</param-name>
<param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
</init-param>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>org.uftwf.inquiry.config, org.uftwf.inquiry.controller</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
<servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>





<filter>
<filter-name>springSecurityFilterChain</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
<filter-name>springSecurityFilterChain</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

<!--


<security-constraint>
<web-resource-collection>
<web-resource-name>securedapp</web-resource-name>
<url-pattern>/*</url-pattern>
</web-resource-collection>

<user-data-constraint>
<transport-guarantee>CONFIDENTIAL</transport-guarantee>
</user-data-constraint>
</security-constraint>
-->
</web-app>


So I dont see anything looking for applicationContext.xml .... can someone please tell me why I need it to add it and once I did it started to work

Answer

Spring Application contexts are hierarchical. The typical arrangement in a web app is that the context loader listener bootstraps your AC and makes them available 'globally', then each individual DispatcherServlet will have its own child application context that can 'see' all the beans (typically services, data sources, etc.) from the context loader listener's AC. In all cases - when specifying the ContextLoaderListener or the DispatcherServlet - Spring will automatically (based on convention) look for an XML application context and attempt to load it. Usually you can disable this by simply specifying an empty contextConfigLocation param ("") or by telling it that it should expect a Java config class, instead (contextClass attribute). BTW, it is possible to have multiple DispatcherServlets. You might, for example, use Spring Integration's inbound HTTP adapter with one, a Spring Web Services endpoint with another, Spring MVC app on another and a Spring HTTP invoker endpoint on another still, and they'd all be exposed via a DispatcherServlet. You could, theoretically, make them all work in the same DispatcherServlet, but the isolation helps keep things less cluttered and they can all share the same single instances of global, more expensive beans, like DataSources.

Comments