How to differentiate between the session timeout by the Tomcat container and logout link press by the user? - spring

Is there a way to differentiate between the session timeout by the Tomcat container and logout link press by the user?
EDIT1: My environment details : Java 1.8, Apache Tomcat 8.0.36 on Windows Server 2012
I have a MyHttpSessionListener class that implements javax.servlet.http.HttpSessionListener
public class MyHttpSessionListener implements HttpSessionListener {
#Override
public void sessionCreated(HttpSessionEvent httpSessionEvent) {
System.out.println(httpSessionEvent.getSession().getId()+" was CREATED");
}
#Override
public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
System.out.println(httpSessionEvent.getSession().getId()+" was DESTROYED");
}
}
and corresponding configuration declaration within the web.xml file
<listener>
<listener-class>com.webapp.listeners.MyHttpSessionListener</listener-class>
</listener>
I'm not using Spring Security for my webapp.

HttpSessionListener will tackle it at Servlet level. Here one important question is that which Application/Web Server are you using?
You need to have a look at SessionDeletedEvent and SessionExpiredEvent
For now have a try with SessionDestroyedEvent
#Component
public class SessionEndedListener implements ApplicationListener<SessionDestroyedEvent> {
#Override
public void onApplicationEvent(SessionDestroyedEvent event)
{
for (SecurityContext securityContext : event.getSecurityContexts())
{
Authentication authentication = securityContext.getAuthentication();
YourPrincipalClass user = (YourPrincipalClass) authentication.getPrincipal();
// do something
}
}
}
and you also need to register this in web.xml
<listener>
<listener-class>
org.springframework.security.web.session.HttpSessionEventPublisher
</listener-class>
</listener>
Updated Answer
After the recent edit, Now for this case you need to use
HttpSessionBindingListener
This is being called when object is removed from the session (either explicitly by removeAttribute() method of HTTPSession or by an invalidation/expire of the session).

You could parse session lastAccessTime, and if it's some time ago (configured expiration time) then it expired.

Related

Spring Cloud Config Client Without Spring Boot

We have an existing spring web app deployed as a WAR file into Amazon Elastic Beanstalk. Currently we load properties files as http resources to give us a single source of property placeholder config resolution. Im investigating replacing this with the new spring cloud configuration server to give us the benefits of git versioning etc.
However the documentation (http://cloud.spring.io/spring-cloud-config/spring-cloud-config.html) only seems to describe a Spring Boot client application. Is it possible to set up the Spring Cloud Config Client in an existing web app? Do I need to manually set up the Bootstrap parent application context etc - are there any examples of this? Our current spring configuration is XML based.
Refrenced: https://wenku.baidu.com/view/493cf9eba300a6c30d229f49.html
Root WebApplicationContext and the Servlet WebApplicationContext uses Environment and initializes PropertySources based on the spring profile. For non-spring boot apps, we need to customize these to get the properties from Config Server and to refresh the beans whenever there is a property change. Below are the changes that needs to happen to get the config working in SpringMVC. You will also need a system property for spring.profile.active
Create a CustomBeanFactoryPostProcessor and set lazyInit on all bean definitions to true to initialize all bean lazily i.e. beans are initialized only upon a request.
#Component
public class AddRefreshScopeProcessor implements BeanFactoryPostProcessor, ApplicationContextAware {
private static ApplicationContext applicationContext;
#SuppressWarnings("unchecked")
#Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
String[] beanNames = applicationContext.getBeanDefinitionNames();
for(int i=0; i<beanNames.length; i++){
BeanDefinition beanDef = beanFactory.getBeanDefinition(beanNames[i]);
beanDef.setLazyInit(true);
beanDef.setScope("refresh");
}
}
#Override
public void setApplicationContext(ApplicationContext context)
throws BeansException {
applicationContext = context;
}
/**
* Get a Spring bean by type.
*
* #param beanClass
* #return
*/
public static <T> T getBean(Class<T> beanClass) {
return applicationContext.getBean(beanClass);
}
/**
* Get a Spring bean by name.
*
* #param beanName
* #return
*/
public static Object getBean(String beanName) {
return applicationContext.getBean(beanName);
}
}
Create a custom class extending StandardServletEnvironment and overriding the initPropertySources method to load additional PropertySources (from config server).
public class CloudEnvironment extends StandardServletEnvironment {
#Override
public void initPropertySources(ServletContext servletContext, ServletConfig servletConfig) {
super.initPropertySources(servletContext,servletConfig);
customizePropertySources(this.getPropertySources());
}
#Override
protected void customizePropertySources(MutablePropertySources propertySources) {
super.customizePropertySources(propertySources);
try {
PropertySource<?> source = initConfigServicePropertySourceLocator(this);
propertySources.addLast(source);
} catch (
Exception ex) {
ex.printStackTrace();
}
}
private PropertySource<?> initConfigServicePropertySourceLocator(Environment environment) {
ConfigClientProperties configClientProperties = new ConfigClientProperties(environment);
configClientProperties.setUri("http://localhost:8888");
configClientProperties.setProfile("dev");
configClientProperties.setLabel("master");
configClientProperties.setName("YourApplicationName");
System.out.println("##################### will load the client configuration");
System.out.println(configClientProperties);
ConfigServicePropertySourceLocator configServicePropertySourceLocator =
new ConfigServicePropertySourceLocator(configClientProperties);
return configServicePropertySourceLocator.locate(environment);
}
}
Create a custom ApplicatonContextInitializer and override the initialize method to set the custom Enviroment instead of the StandardServletEnvironment.
public class ConfigAppContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
#Override
public void initialize(ConfigurableApplicationContext applicationContext) {
applicationContext.setEnvironment(new CloudEnvironment());
}
}
Modify web.xml to use this custom context initializer for both application context and servlet context.
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<init-param>
<param-name>contextInitializerClasses</param-name>
<param-value>com.my.context.ConfigAppContextInitializer</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextInitializerClasses</param-name>
<param-value>com.my.context.ConfigAppContextInitializer</param-value>
</context-param>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/dispatcher-servlet.xml</param-value>
</context-param>
To refresh the beans created a refresh endpoint you will also need to refresh the application Context.
#Controller
public class RefreshController {
#Autowired
private RefreshAppplicationContext refreshAppplicationContext;
#Autowired
private RefreshScope refreshScope;
#RequestMapping(path = "/refreshall", method = RequestMethod.GET)
public String refresh() {
refreshScope.refreshAll();
refreshAppplicationContext.refreshctx();
return "Refreshed";
}
}
RefreshAppplicationContext.java
#Component
public class RefreshAppplicationContext implements ApplicationContextAware {
private ApplicationContext applicationContext;
public void setApplicationContext(ApplicationContext applicationContext) {
this.applicationContext = applicationContext;
}
public void refreshctx(){
((XmlWebApplicationContext)(applicationContext)).refresh();
}
}
I have similar requirement; I have a Web Application that uses Spring XML configuration to define some beans, the value of the properties are stored in .property files. The requirement is that the configuration should be loaded from the hard disk during the development, and from a Spring Cloud Config server in the production environment.
My idea is to have two definition for the PropertyPlaceholderConfigurer; the first one will be used to load the configuration from the hard disk :
<bean id="resources" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" doc:name="Bean">
<property name="locations">
<list>
<value>dcm.properties</value>
<value>post_process.properties</value>
</list>
</property>
</bean>
The second one will load the .properties from the Spring Config Server :
<bean id="resources" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" doc:name="Bean">
<property name="locations">
<list>
<value>http://localhost:8888/trunk/dcm-qa.properties</value>
</list>
</property>
</bean>
Everything that "just works" with Spring Boot is actually no more than some configuration. It's all just a Spring application at the end of the day. So I believe you can probably set everything up manually that Boot does for you automatically, but I'm not aware of anyone actually trying this particular angle. Creating a bootstrap application context is certainly the preferred approach, but depending on your use case you might get it to work with a single context if you make sure the property source locators are executed early enough.
Non Spring (or non Spring Boot) apps can access plain text or binary files in the config server. E.g. in Spring you could use a #PropertySource with a resource location that was a URL, like http://configserver/{app}/{profile}/{label}/application.properties or http://configserver/{app}-{profile}.properties. It's all covered in the user guide.
I found a solution for using spring-cloud-zookeeper without Spring Boot, based on the idea provided here https://wenku.baidu.com/view/493cf9eba300a6c30d229f49.html
It should be easily updated to match your needs and using a Spring Cloud Config Server (the CloudEnvironement class needs to be updated to load the file from the server instead of Zookeeper)
First, create a CloudEnvironement class that will create a PropertySource (ex from Zookeeper) :
CloudEnvironement.java
public class CloudEnvironment extends StandardServletEnvironment {
#Override
protected void customizePropertySources(MutablePropertySources propertySources) {
super.customizePropertySources(propertySources);
try {
propertySources.addLast(initConfigServicePropertySourceLocator(this));
}
catch (Exception ex) {
logger.warn("failed to initialize cloud config environment", ex);
}
}
private PropertySource<?> initConfigServicePropertySourceLocator(Environment environment) {
ZookeeperConfigProperties configProp = new ZookeeperConfigProperties();
ZookeeperProperties props = new ZookeeperProperties();
props.setConnectString("myzookeeper:2181");
CuratorFramework fwk = curatorFramework(exponentialBackoffRetry(props), props);
ZookeeperPropertySourceLocator propertySourceLocator = new ZookeeperPropertySourceLocator(fwk, configProp);
PropertySource<?> source= propertySourceLocator.locate(environment);
return source ;
}
private CuratorFramework curatorFramework(RetryPolicy retryPolicy, ZookeeperProperties properties) {
CuratorFrameworkFactory.Builder builder = CuratorFrameworkFactory.builder();
builder.connectString(properties.getConnectString());
CuratorFramework curator = builder.retryPolicy(retryPolicy).build();
curator.start();
try {
curator.blockUntilConnected(properties.getBlockUntilConnectedWait(), properties.getBlockUntilConnectedUnit());
}
catch (InterruptedException e) {
throw new RuntimeException(e);
}
return curator;
}
private RetryPolicy exponentialBackoffRetry(ZookeeperProperties properties) {
return new ExponentialBackoffRetry(properties.getBaseSleepTimeMs(),
properties.getMaxRetries(),
properties.getMaxSleepMs());
}
}
Then create a custom XmlWebApplicationContext class : it will enable to load the PropertySource from Zookeeper when your webapplication start and replace the bootstrap magic of Spring Boot:
MyConfigurableWebApplicationContext.java
public class MyConfigurableWebApplicationContext extends XmlWebApplicationContext {
#Override
protected ConfigurableEnvironment createEnvironment() {
return new CloudEnvironment();
}
}
Last, in your web.xml file add the following context-param for using your MyConfigurableWebApplicationContext class and bootstraping your CloudEnvironement.
<context-param>
<param-name>contextClass</param-name>
<param-value>com.kiabi.config.MyConfigurableWebApplicationContext</param-value>
</context-param>
If you use a standard property file configurer, it should still be loaded so you can have properties in both a local file and Zookeeper.
For all this to work you need to have spring-cloud-starter-zookeeper-config and curator-framework jar in your classpath with their dependancy, if you use maven you can add the following to your pom.xml
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-zookeeper-dependencies</artifactId>
<version>1.1.1.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zookeeper-config</artifactId>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
</dependency>
</dependencies>
Posting as an answer because I don't have enough points to comment on Dave Syer's excellent answer. We have implemented his proposed solution in production and it is working as expected. Our newer apps are being written using Boot, while our legacy apps use Spring, but not boot. We were able to use Spring Cloud Config to create a property service that serves properties for both. The changes were minimal. I moved the legacy property files out of the war file to the property service git repository, and changed the property definition from a classpath reference to a URL as Dave describes and inserted our system environment variable just as we did for classpath. It was easy and effective.
<util:properties id="envProperties" location="https://properties.me.com/property-service/services-#{envName}.properties" />
<context:property-placeholder properties-ref="envProperties" ignore-resource-not-found="true" ignore-unresolvable="true" order="0" />
<util:properties id="defaultProperties" location="https://properties.me.com/property-service/services-default.properties" />
<context:property-placeholder properties-ref="defaultProperties" ignore-resource-not-found="true" ignore-unresolvable="true" order="10" />

how to detect tomcat session expiration using spring

i am running wicket with spring and use spring security , when tomcat session , the one which declared in the web.xml expired
<session-config>
<session-timeout>1</session-timeout>
</session-config>
I want to catch this event using a filter(not overiding existing httpSession or Session )
how can I achive that using spring ?
10x
You can use a listener class to achieve this. Define a listener component as below:
#Component
public class AppLogoutListener implements
ApplicationListener<SessionDestroyedEvent> {
#Override
public void onApplicationEvent(SessionDestroyedEvent event) {
// from event you can obtain SecurityContexts to work with
}
}
You need to define a session event publisher in your web.xml:
<listener>
<listener-class>org.springframework.security.web.session.HttpSessionEventPublisher</listener-class>
</listener>
Here the HttpSessionEventPublisher publishes the session life cycle events whenever sessions are created and expired.

GWTP using Spring in server side

I am working with gwtp and I would like to use Spring on the server side. I have seen that Spring is include in gwtp, but I don't know how I can use it. Anyone can help me about that?
Will be cool some example.
I have looked for by google, but no way :(
Thanks a lot!!
GWTP is using GIN pattern (Dependency Injection at Client Side) and it's default integration with GUICE at DI server side. for more detail GWTP
Spring is server side DI pattern.
I have seen that Spring is include in gwtp,
It does not include Spring at all. it's default integration with GUICE. but you can use spring with it.
gwtp-sample-basic-spring example
Well, at first you have to configure Spring in your web.xml descriptor:
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>
<servlet>
<servlet-name>springGwtRemoteServiceServlet</servlet-name>
<servlet-class>org.spring4gwt.server.SpringGwtRemoteServiceServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>springGwtRemoteServiceServlet</servlet-name>
<url-pattern>/yourProjectName/springGwtServices/*</url-pattern>
</servlet-mapping>
Notice that you need the Spring4GWT library for this example.
Next, in your RemoteService interfaces you need to specify the RemoteServiceRelativePath like this example:
import com.google.gwt.user.client.rpc.RemoteServiceRelativePath;
import com.google.gwt.user.client.rpc.RemoteService;
#RemoteServiceRelativePath("springGwtServices/userService")
public interface UserService extends extends RemoteService{
public User getUserByLogin(String name);
public void logout();
public void deleteUserById(Long userId);
}
And now, you just need to implement your service as in any Spring app.
Example, suppose you want an action to delete a User by ID and using the GWTP paradigm:
In server side, here is the Handler:
#Repository("deleteUserHandler")
public class DeleteUserHandler extends AbstractActionHandler<DeleteUserAction, DeleteUserResult> {
#Autowired
private UserService userService;
public DeleteUserHandler(){
super(DeleteUserAction.class);
}
#Override
public DeleteUserResult execute(DeleteUserAction action, ExecutionContext arg1)
throws ActionException {
Long idToDel = action.getUserToDeleteId();
if(idToDel != null){
userService.deleteUserById(idToDel);
}
return new DeleteUserResult();
}
#Override
public void undo(DeleteUserAction arg0, DeleteUserResult arg1,
ExecutionContext arg2) throws ActionException {
// TODO Auto-generated method stub
}
}
The DeleteUserAction is as follows
public class DeleteUserAction extends UnsecuredActionImpl<DeleteUserResult> {
private Long userToDeleteId;
public DeleteUserAction(Long userToDel) {
this.userToDeleteId = userToDel;
}
/**
* For serialization only.
*/
#SuppressWarnings("unused")
private DeleteUserAction() {
}
public Long getUserToDeleteId() {
return userToDeleteId;
}
public void setUserToDeleteId(Long userToDeleteId) {
this.userToDeleteId = userToDeleteId;
}
}
And finally the Result class:
public class DeleteUserResult implements Result {
/**
* For serialization only.
*/
//#SuppressWarnings("unused")
public DeleteUserResult() {
}
}
I hope this helps.
PS: I suppose you can do the Spring things (application context etc..) by yourself, if not, please tell
You can find some good examples on GWTP repository in Github. We recently migrated all of our from Google Code to Github, which hosts the latest version.
Remember you can also use REST communication using the new GWTP-Dispatch-Rest, with that you don't need a lot of configuration code to integrate GWTP with Spring server side.
https://github.com/ArcBees/GWTP-Samples

How to set active spring 3.1 environment profile via a properites file and not via an env variable or system property

We use the new environment profiles feature of spring 3.1. We currently set the active profile by setting the environment variable spring.profiles.active=xxxxx on the server to which we deploy the application.
We think this is a suboptimal solution as the war file we want to deploy should just have an additional properties file which sets the environment in which the spring app context should load so the deployment is not dependent on some env var set on the server.
I tried to figure out how to do that and found:
ConfigurableEnvironment.setActiveProfiles()
which I can use to programmatically set the profile but then I still don't know where and when to execute this code. Somewhere where the spring context loads up? Can I load the parameter I want to pass to the method from a properties file?
UPDATE: I just found at docs which I might be able to implement to set the active profile?
In web.xml
<context-param>
<param-name>spring.profiles.active</param-name>
<param-value>profileName</param-value>
</context-param>
Using WebApplicationInitializer
This approach is used when you don't have a web.xml file in Servlet 3.0 environment and are bootstrapping the Spring completely from Java:
class SpringInitializer extends WebApplicationInitializer {
void onStartup(ServletContext container) {
AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
rootContext.getEnvironment().setActiveProfiles("profileName");
rootContext.register(SpringConfiguration.class);
container.addListener(new ContextLoaderListener(rootContext));
}
}
Where SpringConfiguration class is annotated with #Configuration.
The answer from Thomasz is valid as long as the profile name can be provided statically in the web.xml or one uses the new XML-less configuration type where one could programmatically load the profile to set from a properties file.
As we still use the XML version I investigated further and found the following nice solution where you implement your own ApplicationContextInitializer where you just add a new PropertySource with a properties file to the list of sources to search for environment specific configuration settings. in the example below one could set the spring.profiles.active property in the env.properties file.
public class P13nApplicationContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
private static Logger LOG = LoggerFactory.getLogger(P13nApplicationContextInitializer.class);
#Override
public void initialize(ConfigurableApplicationContext applicationContext) {
ConfigurableEnvironment environment = applicationContext.getEnvironment();
try {
environment.getPropertySources().addFirst(new ResourcePropertySource("classpath:env.properties"));
LOG.info("env.properties loaded");
} catch (IOException e) {
// it's ok if the file is not there. we will just log that info.
LOG.info("didn't find env.properties in classpath so not loading it in the AppContextInitialized");
}
}
}
You then need to add that initializer as a parameter to the ContextLoaderListener of spring as follows to your web.xml:
<context-param>
<param-name>contextInitializerClasses</param-name>
<param-value>somepackage.P13nApplicationContextInitializer</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
You can also apply it to DispatcherServlet:
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextInitializerClasses</param-name>
<param-value>somepackage.P13nApplicationContextInitializer</param-value>
</init-param>
</servlet>
For some reason only one way works for me
public class ActiveProfileConfiguration implements ServletContextListener {
#Override
public void contextInitialized(ServletContextEvent sce) {
System.setProperty(AbstractEnvironment.DEFAULT_PROFILES_PROPERTY_NAME, "dev");
System.setProperty(AbstractEnvironment.ACTIVE_PROFILES_PROPERTY_NAME, "dev");
}
....
<listener>
<listener-class>somepackahe.ActiveProfileConfiguration</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
Here is a variation on the P13nApplicationContextInitializer approach. However, this time we obtain the path to env properties from JNDI. In my case I set a JNDI global environment variable as coacorrect/spring-profile = file:/tmp/env.properties
In tomcat/tomee server.xml add this: <Environment name="coacorrect/spring-profile" type="java.lang.String" value="/opt/WebSphere/props"/>
Further, in tomcat/tomee, add to the WAR's META-INF/context.xml <ResourceLink global="coacorrect/spring-profile" name="coacorrect/spring-profile" type="java.lang.String"/>
In any container, add appropriate in web.xml
public class SpringProfileApplicationContextInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext>{
public static final Logger log = LoggerFactory.getLogger(SpringProfileApplicationContextInitializer.class);
private static final String profileJNDIName="coacorrect/spring-profile";
private static final String failsafeProfile="remote-coac-dbserver";
#Override
public void initialize(ConfigurableApplicationContext applicationContext) {
ConfigurableEnvironment environment = applicationContext.getEnvironment();
try {
InitialContext ic = new InitialContext();
Object r1 = ic.lookup(profileJNDIName);
if (r1 == null) {
// try the tomcat variant of JNDI lookups in case we are on tomcat/tomee
r1 = ic.lookup("java:comp/env/"+profileJNDIName);
}
if (r1 == null) {
log.error("Unable to locate JNDI environment variable {}", profileJNDIName);
return;
}
String profilePath=(String)r1;
log.debug("Found JNDI env variable {} = {}",r1);
environment.getPropertySources().addFirst(new ResourcePropertySource(profilePath.trim()));
log.debug("Loaded COAC dbprofile path. Profiles defined {} ", Arrays.asList(environment.getDefaultProfiles()));
} catch (IOException e) {
// it's ok if the file is not there. we will just log that info.
log.warn("Could not load spring-profile, defaulting to {} spring profile",failsafeProfile);
environment.setDefaultProfiles(failsafeProfile);
} catch (NamingException ne) {
log.error("Could not locate JNDI variable {}, defaulting to {} spring profile.",profileJNDIName,failsafeProfile);
environment.setDefaultProfiles(failsafeProfile);
}
}
}

Spring applicationcontext loading hooks

Are there any hooks into the Spring ApplicationContext loading process?
I want to run a piece of code just before the application context loads (before any beans/properties/aspects/etc... are instantiated).
thanks in advance
Maybe BeanFactoryPostProcessors will suite your needs? They are run after the whole XML configuration files are read, but before any (other) beans are instantiated.
You can also use the ApplicationListener to receive notification of events like ContextClosedEvent, ContextStartedEvent or ContextStoppedEvent.
More information in the IoC Container chapter.
I just declared my own ContextLoaderListener in order to perform the desired work before loading the Spring context. It suits for web-apps, just declare it before the Spring context listener:
public class MyServletContextListener implements ServletContextListener {
#Override
public void contextDestroyed(ServletContextEvent arg0) {
}
#Override
public void contextInitialized(ServletContextEvent arg0) {
//Perform your stuff here
}
}
<listener>
<listener-class>
com.myCompany.listeners.MyServletContextListener</listener-class>
</listener>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

Resources