JSF - How to save managedBean state when session times out? - session

I am working for a client that has it's own session management system in case of idle timeouts. What happens is the following :
User stays idle for the set amount of time.
Session times out redirecting to login page
User enters credentials and is redirected back to where he was.
Now the above process is handled by passing a POST request passing the javax.faces.ViewState to the session management system. However, in case of timeouts it needs only 8K of data in the request to process and redirect. But since my managed bean is saving a lot of data (banking app, need to keep track of the calculations!) the size of the request is high (around 20K) due to which redirection fails.
So is there any way I can somehow save the ViewState? Or better, any way I can prevent the timeout? Something like keeping the session alive?
All my managed beans have a session scope.
EDIT: Just in case required, the javax.faces.STATE_SAVING_METHOD context-param in web.xml is set to client for performance purposes.
EDIT: Did a trace of the flow using HttpWatch and found out that javax.faces.ViewState is taking up 18kB of the total 22kB of size of the POST request. So my aim is narrowed down to reducing the size of ViewState. Any way to I can do this ?

State saving only keeps the data associated with the current view. Your problem here is that the session scoped beans are lost. I suggest two ways of solving the problem:
1) Implement a HttpSessionListener and in its sessionDestroyed() method get the beans, serialize them and store them in a database row associated with the current user. When the user logs in again you can fetch the beans, deserialize them and put them in the user's session.
2) Implement ajax poll that will ping the server in a specific period and this way the session will not timetout. You could achive this using Richfaces JSF library that has a built-in JSF component for ajax poll.

Related

How to use data saved from an old session in next session?

I have been using cookies to share non-sensitive data across sessions. I want to store some lastUsedEntity (a string literal) from the current session at user logout event so that that entity can be read/used at next login session. The said entity belongs to a session bean of my application.
I decided to extract and store this entity in #PreDestroy method of the session bean. The method ran successfully at session timeout of the application. But storing cookie failed because FacesContext.getCurrentInstance() was null in #PreDestroy method, maybe because JSF Lifecycle request-response cycle completed by then. I tried caching FacesContext.getCurrentInstance() in #PostContruct method of my session bean so that I could access faces context cached instance but then I faced another problem java.lang.IllegalStateException at com.sun.faces.context.FacesContextImpl.assertNotReleased because I used FacesContext as instance variable of my session scoped class. I would appreciate if I could get some heads up here or any other better idea in order to persist my old session data for further use in this scenario.
There's not necessarily means of a HTTP request when a HTTP session gets expired in server side due to enduser inactivity. The enduser itself is the only one who can send a HTTP request. If there's no HTTP request which invoked the FacesServlet, then there's no FacesContext either. Let alone a HTTP response on which you could return the cookie.
You'd better rethink your logic. E.g. set the cookie immediately on every request, overriding the previous one, if necessary on a specific path and/or with a timestamp in the cookie value. Depending on the concrete functional requirement there may be better ways though as cookies are fully manipulatable by the enduser and you should absolutely not depend critical business logic on that. If it's purely for presentation, it should be okayish, otherwise better store it in the database associated with logged-in user.

Would ajax request too often cause session expired?

I don't really deeply understand of the session mechanism but just good enough as a casual user of the technology. I have a page implemented with jQuery ajax request. If I keep refreshing the page at a fast pace it would make the session expired and I have to login again. I would appreciate for an explanation of the phenomenon and solution to prevent that.
Sessions consists in to main parameters
Cookies and Server-side session data
In a very little explanation
cookies contains session ID, that references to the server to get session data. Server then fetchs data with the session ID and matches it inside a file with various parameters.
Your problem must be session timeout, it depends mainly on session timeout parameter configured.
Your ajax requests only works if the session timeout hasnt expired thats why it prompts you for login.
You can solve this by defining a service that does not require authentication, you can define your functions on a specific file with no session initialization so the request can bypass the security session, and your other pages that need security are secured at the same time. Like amazon mechanism.

How to do custom action before session invalidation (time-out)?

I want to store some information of current session's user when a session is getting invalidated (because of time out). How can I do that?
If this helps, I'm using Spring Security 3.1. So if there is any configuration in Spring I'm having no trouble understanding that.
There is a thing in Spring Security as Session Expiration. When a session expires, a filter catches it and I can have my desired information from it.
However the problem is when a session gets invalidated (because of timeout). Because, for the next request there will be a new session created and I'm not able to have access to the old one. I want to know how I can customize session invalidation ?

Spring do not update session for ajax polling

We are currently running into a problem with session time outs on one of our Spring web applications. The session never times out because we have a continuous ajax request polling the server. Is there a way to tell spring to ignore this request and not update the session so that time out works as expected?
You could run a timer, equal to your session timeout, along side the continuous ajax request that would log the user out if the page never refreshes. Another idea would be to host the URL that you are hitting in a separate web application on the same domain. I'm not sure if Spring has something built in for what you are doing.
I thought about this some more. You could implement your own session registry that ignores the Ajax URLs. Basically you wouldn't set the last accessed time for a user in the session registry if the URL matched one that you defined in your ignore list or filter defined in the Spring Security filter chain.
See SessionRegistry

How do backing bean scopes work?

I have some misunderstanding with JSF backing bean scope. I am new to JSF and now writing a simple project and all my beans mostly have session scope. But if my site will have many users that means my session will be very very big and kill my server. Some people have told me that the solution is use request scope beans. But, for example, when my page must be validated and if validation is failure show error messages and save all user input, what can I do in this situation? I am trying use component that use AJAX-request and hoped that my request bean will be not reconstructed, but this doesn't work (I am using <rich:datascroller> ).
I think I have big hole in my JSF understanding, I will be grateful if somebody explain what I must do in this situation or link me on some good article about bean scopes.
Scope defines the lifetime of the beans.
Request scope beans live during the servicing of one HTTP request, so thay are available both while you analyze the user's input and formulate the response page. So for simple validation and response I'd expect request-scoped beans to be what you need - the exception being perhaps if you send a redirect back to the browser and that submits a new request, then you may need ...
Session scoped beans live for the life of the user's session, ie. across several requests. Sessions might last for some time, but eventually the user logs out, or becomes quiscent and his session gets timed-out. So it doesn't matter how many users overall you have, just how many are active at once. It's pretty common to keep some session data around for each user (like at least who is, and perhaps his recently viewed stuff) so there's no fundamental reason to be worried by some data being kept. You just need to ensure you keep it tidy, don't keep the data for old pages very very long - perhaps just a "current data" bean or some such.

Resources