How can I handle the session expired in spring MVC and what is the best place to handle it? where can I specify the session time out? It would be great if you could show me by some example.
For sessions timeout I am using 'plain' Servlet API.
Custom javax.servlet.http.HttpSessionListener defined in web.xml and in method sessionCreated on session set timeout using setMaxInactiveInterval (in [s]).
I know it is 'old school', but is simple and working for me.
If you want to get timeout value from spring, there is access to ServletContext from session.
ApplicationContext applicationContext = WebApplicationContextUtils.getWebApplicationContext(session.getServletContext());
applicationContext.getBean("...");
One option is to use the event mechanism in ApplicationContext, you would then register a HttpSessionListener in web.xml that when a session timeouts fires an event in the root WebApplicationContext to all beans that observes that event. Get the root WebApplicationContext using WebApplicationContextUtils.
Related
I would like to delete some temporal files when user session finishes. The information associated with the files is stored in an object annotated with #SessionAttributes.
The only way I've found to deal with this is creating an HttpSessionListener.
Is there a higher level, simplified, Springy way to listen to the session end event where I could easily get my annotated object?
You most likely will need to create a HttpSessionListener.
Another stackoverflow answer:
Detect session timeout in Spring 3/Spring Security 2.0.5
Also and example on how to load spring beans into it:
http://www.mkyong.com/spring/spring-how-to-do-dependency-injection-in-your-session-listener/
Two options to use HttpSessionListener with spring beans:
The first is to use WebApplicationContextUtils.getRequiredApplicationContext(servletContext) to obtain the servlet context. From there you have two sub-options:
use getBean(..)
If you want to use #Autowired / #Inject use getAutowireCapablyBeanFactory().autowireBean(this). You will have to do this only once (check if the fields are null), because the listener is singleton.
The second option is to use AspectJ and #Configurable on the listener.
Not directly related, but might be an interesting project to look at.
https://github.com/shawnmclean/Idle.js
Session deletion typically happens on the server side, when the session expires (usually 30mn). The project above allows to detect user behaviors in the front end.
How to get the application scope in the http session listeners in servlets?
Basically I need to remove some values from application scope on automatic session expiry.
Thanks
The Servlet term for “your entire web app at runtime” is context.
In the listener, get servlet context from the session object.
Invoking session.getServletContext().removeAttribute() should solve your problem.
You can get the context this way:
void sessionDestroyed(HttpSessionEvent se){
ServletContext context=HttpServlet.getServletContext();
// Add/delete objects from context
context.removeAttribute("xyz")
}
se.getSession().getServletContext();
In our application we use jsf,we have
to redirect the user to home page
after their session will be expired.For that i need a path of the home page which i kept in my logout managed bean as a managed bean property.But after session expired if i try to access that it will arise null pointer exception(managed bean becomes null).Then
i have decide to try alternative (i.e)create logout class manually and try to access the property, at that time the property which i wants to access is become null.How can i access
that property?
Please help me.
Thanks in advance.
In addition to the previous answer:
You could use (in web.xml)
<error-page>
<exception-type>javax.faces.application.ViewExpiredException</exception-type>
<location>viewexpired.jsp</location>
</error-page>
Or Context Parameters instead of Session Attributes. See:
http://tomcat.apache.org/tomcat-5.5-doc/config/context.html
http://safebox.guisho.com/jsf-how-to-get-webxml-parameters
Or use (in faces-context.xml)
<managed-bean-scope>application</managed-bean-scope>
for your bean, so it will stay independent from the session.
Correct way of doing this is declaring exception handler factory in faces-config.xml, then implementing the factory by subclassing javax.faces.context.ExceptionHandlerFactory, and then overriding handle() method in your implementation of javax.faces.context.ExceptionHandlerWrapper.
There you should analyze the exception for the ViewExpiredException class and redirect to your view expired page in that case.
It seems to me that "session" scope is another means to keep objects in session as
using setAttrubute / getAttribute
Correct?
You know, dont know why, it does not work for me.
<bean id="sabreUser" class="util.MyUser" factory-method="getSomeUser" scope="session">
<const args...>
What I see is that after the initialization and initial deploy the MyUser properties are correct.
Then, in the first session I change MyUser property, the session is closed.
The second session runs and it sees the last set value from the previous session!
What does that mean?
I expect this object to be initialized whenever a new session starts. But it better looks as singleton, though you see - "session" attribute is set.
I can see the cause of the problem in that a Servlet's fields is initialized with #Autowired
so, once it is initialized, every other session will see its fields set and does not "ReWire" this properties. It happens once? How to overcome this problem?
The Spring session does not exactly match the HttpSession, and even the Spring documentation on the #SessionAttributes annotation says that it might be stored in the session or "some conversational storage". I got that from The Spring docs for 2.5
I've basically quit trying to make sense of it, and just got on with my life, if I want something stored in the HttpSession, I just have Spring inject the HttpSession to me, assuming you're using Spring MVC its pretty easy, instructions on the same page.
Session-scoped beans are beans that live throughout the http session. They are stored in the session via setAttribute in some way.
So - yes.
Session scoped beans are stored in Http Session by Spring framework. This scope is valid only in the context of Web application.It also works for Portlet envionments . When using in Portlet environment, there are two notions of session, application scope and portlet scope (default).
How can I access request headers from a SessionListener?
I need to set a timeout on the current session when it is created. The timeout needs to vary based on a header in the HttpServletRequest. I already have a SessionListener (implements HttpSessionListener) that logs the creation and destruction of new sessions, and it seems to be the most logical place to set the timeout.
I've tried the following, but it always sets ctx to null.
FacesContext ctx = FacesContext.getCurrentInstance();
The HttpSessionListener does not have access to the request because it is invoked when no request has been made—to notify of session destruction.
So, a Filter or Servlet would be better places to examine the request and specify the session timeout.
FacesContext ctx = FacesContext.getCurrentInstance();
JSF contexts are per-request and thread-local. So, this method call will probably return null outside the JSF controller invocations (e.g. FacesServlet.service) - so, other threads and any requests that don't pass through the Faces servlet mapping.
It is technically possible to set this time-out using a JSF mechanism - you could use a phase listener to check for a session after RENDER RESPONSE, though you would still have to cast to the servlet API to set the time-out. The advantage of phase listeners is that they can be registered either globally in faces-config (see spec) or for specific views. A global phase listener defined in a JAR with a META-INF/faces-config.xml can be dropped into multiple WARs, allowing you to easily reuse the functionality.
(You could also override how the session is provisioned to JSF, but the amount of work is excessive.)
For a one-off, erickson's suggestion of a Filter is really straightforward.
You can't ( see the API ). The request allows you to access the session, but not the other way around.
You might even have concurrent requests for the same session, so this is not feasible.