Spring session handling: HttpSessionDestroyedEvent not received - spring

I have a web app where in the web.xml I have added the HttpSessionEventPublisher as listener. The web app runs on Jetty 7.x and we are using Spring 3.1.1.
This is supposed to fire HttpSessionCreatedEvent and HttpSessionDestroyedEvent to Spring context event listeners.
I have a Bean (#Controller) that implements ApplicationListener<ApplicationEvent>. ApplicationEvent is the common parent class of HttpSessionCreatedEvent and HttpSessionDestroyedEvent. When I now login to my web application or log out from it I'd expect these events to be fired to the onApplicationEvent(ApplicationEvent event) method. I have received other events like some request handling event, but the expected event's didn't show up. I have traced the app a bit, the HttpSessionEventPublisher definitely fires the event to the context, but the listener isn't approached. what do I miss here?

The issue is that HttpSessionEventPublisher publishes events on the "Spring Root WebApplicationContext" per the javadoc, this is the application context registered through ContextLoaderListener entry in your web.xml file. Your #Controller on the other hand is probably registered through a different application context altogether - the one registered through the DispatcherServlet. So I would suggest that you create a different ApplicationListener, register it to the Root WebapplicationContext, the events should come through then.

Facing a similar problem, if it not possible to move your ApplicationListener to the root context, you can use the org.springframework.security.context.DelegatingApplicationListener.
Just autowire a DelegatingApplicationListener in your Bean and use constructor / #PostConstruct to register your listener against the DelegatingApplicationListener (one should be already in place by spring-security)

Related

Correct way to find if spring context was started

In my spring bean I want to use send spring event functionality. The problem is event can't be sent if spring context was not initialized and my bean by some reasons can send events before that happen.
I used the following:
implement ApplicationContextAware and use ConfigurableApplicationContext.isActive() - this becomes true in the beginning of the context initialization phase
use ConfigurableApplicationContext.isRunning() - this throws exception IllegalStateException("LifecycleProcessor not initialized...
listen for ContextRefreshedEvent - this doesn't work because this is inner bean and is used as a property for the bean that implements BeanFactoryPostProcessor
implementing SmartLifecycle also doesn't work because for inner beans
So what is the EASY and correct way to determine if context is running and event can be sent?
Hopefully this is already fixed SPR-13667 in spring 4.1.7.

Spring ApplicationListener gets fired twice on webapp

I have an application listener that's supposed to execute only once per webapp startup, since it loads basic user info data.
public class DefaultUsersDataLoader implements ApplicationListener<ContextRefreshedEvent> {
#Override
#Transactional
public void onApplicationEvent(ContextRefreshedEvent e) {...}
}
Somehow, it gets executed twice: on app startup and when the first request arrives to the server. Why is this happening and how can I prevent it?
Generally in a Spring MVC application you have both a ContextLoaderListener and DispatcherServlet. Both components create their own ApplicationContext which in turn both fire a ContextRefreshedEvent.
The DispatcherServlet uses the ApplicationContext as created by the ContextLoaderListener as its parent. Events fired from child contexts are propagated to the parent context.
Now if you have an ApplicationListener<ContextRefreshedEvent> defined in the root context (the one loaded by the ContextLoaderListener) it will receive an event twice.
Do not annotated your Listener Class's method with #EventListener

Need to create a html file in web root folder at startup

I'm using spring 3.1. And I need to make a html file in my web root at spring startUp.
Of course I know JSP makes a html, but it's about request-response. I need to create a html on the startup.
And.. I hope my job is possible in pure Spring framework.
I know of Quartz.. but I don't want to use quartz. Because I'm afraid that adopting Quartz may need many changes in my Spring config.
You can create a bean that implements ApplicationListener. An ApplicationListener listens to events published by the context.
The ApplicationContext publishes certain types of events when loading
the beans. For example, a ContextStartedEvent is published when the
context is started and ContextStoppedEvent is published when the
context is stopped.
Using an application listener allows you to execute some tasks when the application is first started or the context is refreshed.
Here is an example of a basic ApplicationListener from one of my projects:
public class MyApplicationListener implements ApplicationListener<ContextRefreshedEvent> {
#Override
public void onApplicationEvent(ContextRefreshedEvent event) {
//Generate html file here, this method is called when event happens
}
}
And its configuration:
<!-- Fired when different application events occur such as context refresh or startup -->
<bean id="myListener" class="fully.qualified.MyApplicationListener" />

How to Retrieve current ApplicationContext loaded by Multipart Dispatcher Servlet without creating a new one?

When my application server starts, my ApplicationContext is loaded by Multipart Servlet.
I have multiple inbound message listener on some queues. Each message-read from different queue represents a different thread. The messages travel along my application flow and I need to retrieve the current application context (loaded before by multipart) and inject into my singleton class.
Is there a method to achieve this?
PS: I don't have control on dispatcher servlet ... it's a big problem
The OP wrote:
I resolved it. I create a classfactorybean on xml that implements ApplicationContextAware with relatives methods (particular setApplicationContext). This last method is called by callback and retrieve automatically the context loaded by Multipart at server startup and inject the context into my bean (in the bootstrap phase).

Recommended way to access Spring Context in a JMS Listener

I am working in a Web Application running in JBoss that utilizes Spring and whenever requests come into the application our web layer gets access to the Spring ApplicationContext via
ApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(request.getSession().getServletContext() );
We are adding some JMS Listeners in our application that also need access to ApplicationContext, but
unfortunately the JMS Listeners don't have access to the HttpServletRequest api.
What is the best practice in Spring to get access to the ApplicationContext inside a MessageListener. Our JMS Listeners are also injected via our spring configuration files.
If your JMS listeners are themselves Spring beans, as you suggest, then why not just wire the resources needed by the listener directly into it? The listener is just like any other bean - don't fetch the beans from the context, have them injected.

Resources