I have a session attribute in my controller #SessionAttribute("sample_dto"). I need to work with the sample_dto even after session get timeout. What is the way to do this properly.
PS: When session get timeout, browser is redirected to login screen. How can I avoid it and bring it back to the place where I was before session get timeout.
Thanks
According to your question, I think you don't need a session attribute. Because you need to access the same data item in between
separate sessions. The simplest solution is to use a normal instance variable. Because your controller is singleton in default.
It is similar to application scope since you don't change the scope of your controller and don't restart your application.
If this task is user specific (your data item should persist per user basis), then you can use cookies for saving the temporary user status.
In order to set the cookies you can implement your own HttpSessionListener class and within the sessionDestroyed method you can do your cookie saving things.
Because you need to do this thing only when your session is get destroyed(timeout).
If your data is much bigger, then you can save the data in the database by referring to the relevant user. You can use the same sessionDestroyed method.
Related
Okay. What I want to do is be able to, when I update a user, invalidate any session that they currently have in order to force a refresh of credentials. I don't care about being able to directly access the session-specific user data. Ideally, I would also be able to restrict users to one session by a similar manner.
What I tried doing is creating a HashMap using the username as key and HttpSession as the value (my actual setup is a little more involved, but after repeated seemingly inexplicable failures, I boiled it down to this simple test). However, whenever I attempt to tell the retrieved HttpSession to invalidate, it seems to be invalidating the current [admin] session. Is HttpSession inextricably bound to the current request?
Or is there an entirely different way to deal with this?
If it happens to matter, I'm using Jetty 6.1.26.
There's no straight forward way. The easiest way I can think of is to keep a flag on the database (or a cahche) and check it's validity on each request.
Or you can implement a HTTP Session listener and keep a HashMap of user sessions that can be accessed and invalidated.
I haven't tried any of these out so I don't know of any performance issues. But it should be acceptable for most applications.
Well, as far as I can tell, there's no way around it. Using a request-scoped bean didn't work as I expected (although it did give me good insights into how Spring operates, intercepting field accesses). I ended up using a dirty flag on my SessionHandler (a session-scoped bean) with a very high-priority aspect checking and, if necessary, calling invalidate() on the session in the user's next request. I still ended up having all my SessionHandlers register with a SessionManager, and a #PreDestroy method to unregister them in order to avoid a bunch of null entries in the map.
It's as simple. In Spring MVC, how and where do I store a complex java object so that it is available across the action servlets. For example if an ajax is called on next page, the business object from within some previously called servlet, stored somewhere should be accessible in that ajax action method in java. I did this by creating a singleton bean but it failed when multiple users hit the application. User outputs are affected among each other. I need to achieve this in a non-singleton manner.
You can store objects in your request object:
request.setAttribute("key", valueObject);
To get the object, simply use
request.getAttribute("key");
Or, as Subir Kumar Sao said in the comments, use the session to store your stuff:
request.getSession().setAttribute("key", valueObject);
and
request.getSession().getAttribute("key");
You can use either
request.setAttribute("key", valueObject);
request.getAttribute("key");
or
session.setAttribute("key", valueObject);
session.getAttribute("key");
Difference between them : Request-scoped attribute is visible only while current request is processed. Session-scoped attribute is persistent between several requests from the same user.
You should keep your objects on session level. As long as the session is alive, you can access your session level variables, regardless of the requests.
request.getSession().getAttribute("key");
request.getSession().getAttribute("key", value);
Keep in my mind that once a session level attribute is set, that is always there until, session is killed or invalidated. So you may need to remove the attribute according to your logic.
request.getSession().removeAttribute("key");
Is there a way to set a session variable AFTER the response has been delivered?
I want to avoid that any filter will see this change in the current request.
To clarify the context I will talk about the use case.
My task is to adapt a complex Java EE application (Spring, acegi, struts, JSP, Apache Tiles, aso) to user needs.
Users could login to this application.
If a user account is used a second time, the new session should warn that continuing will invalidate the original session.
Any request after presenting the warning (due to clicking a link) should invalidate the original session.
One problem is, that currently setting session variable were visible to other (spring) filters.
You can create a filter which is the first in the filter chain. This filter will be called last when the request is postprocessed. And you can set the session variable when the filter is called the second time.
If you have a session, you can keep a variable only server-side. Keeping it in a session bean would be the normal procedure. Quite simple.
In our web application (in JBoss using Struts) we use sessions largely for security as well as to cache some data for a User. Thus, every user logged into the application has a session and different data cached in it.
Based on some parameter change, i want to change the cache of the subset of users who are logged in (i.e. have session)
Can this be achieved? I have not been able to find anything so far from general search.
You can use a HttpAttributeListener
a basic example here
HttpSessionAttributeListener:
The HttpSessionAttributeListener interface enables an object to
monitor changes to the attribute lists of sessions within a given Web
application. The HttpSessionAttributeListener in turn extends
java.util.EventListener. The methods in it are
attributeAdded(HttpSessionBindingEvent se)- This is the notification that an attribute has been added to a session.
attributeRemoved(HttpSessionBindingEvent se)- This is the notification that an attribute has been removed from a session.
attributeReplaced(HttpSessionBindingEvent se)- This is the notification that an attribute has been replaced in a session.
You can do it by storing each session object in a static List<Session> in some holder object. You can put it by a HttpSessionListener#sessionCreated(..). Remember to remove it from the list on sessionDestroyed(..)
Then, whenever you want to do something, simply loop the previously stored list of sessions and do whatever you want with them.
You have basically 2 options:
Push the changes. Get hold of all HttpSession instances in an application wide map which you manage with help of a HttpSessionListener. This way you can just get them from the application scope and walk through them to make the necessary changes directly.
Poll the changes. Store a change instruction in the application scope. On every HTTP request, check with help of a Filter or ServletRequestListener if a change is required, then make the necessary change in the current session and remove/disable the change instruction.
A completely different alternative is to use an application wide shared cache, such as Terracotta or Ehcache, so that you don't need to duplicate the same data over all HTTP sessions. You'd just need to deal with the data on a per-request basis. When database access comes into picture with JPA, then read on about "2nd level cache", that's exactly what it does.
I wanted to understand how we can implement a safe logout method in a website. I am trying a logout page in jsp. Is destroying a session enough when the user clicks logout ? If it isn't what are the steps necessary for the logout, to be a safe operation for the user ?
Generally I'd say yes, but it depends on what other information you may be storing client-side. For example, if you have any cookies with sensitive information (hopefully you don't) then you should clear those out as well.
If you stored any user related cookies, you need to clean-up them as well. In other words, any information that used by your server to identify a user should be cleaned up. If it's only the session - then in you case that is sufficient.
Define "safe".
You'd also likely want to turn off caching so hitting the "Back" button wouldn't show potentially-sensitive information. Other than that, not sure what else you're concerned about.
Depends on your application requirement what functionality do you want during logout. Apart from refreshing or releasing the user session some times there are few variables set in the session, they should also be released properly.
Yep, once you invalidate session, then the session id is no longer valid, probably the session cookie would be also destroyed, so the session is gone (together with all data stored in session).
In order to logout user (either from servlet or from JSP page):
<%
HttpSession s = request.getSession();
s.invalidate();
%>
That was the easy part. Now, if you store some important, user specyfic data in a custom cookie, then make sure you clean them. The same applies to HTML 5 local storage - it has to be manualy cleaned.