Session problem in ADF BC
We have an application developed in Jdev 10.1.3.4 (JSP, Struts, ADF BC) and running on OAS. Now we have a big problem with session, hope somebody can help with some ideas.
We set session time to 45 min in the web.xml. The problem is that sometimes some user work on a page with form,for instance performing some edit activity. If he/she leave the page open inactive for more than 45 minutes and come back from lunch, press the ’save’ button, the application would then commit the change to the wrong row in database, most probably the top row in the View Object(VO) instance. This is because the application module actually does a rollback when session expires, it loses all user data.(e.g. row currency in VO instance).
To avoid saving wrong data to the wrong place, we implemented a session Filter(see att. Below: ApplicationSessionExpiryFilter.java) to catch session time-out and forward request to an error page alerting user that their session has expired due to long time of inactivity. The Filter works as it should but it gives another problem. If user already has one of our application page open for very long time and open another page in a new browser (e.g. click a link from an email), he/she will get session-expire error immediately in the new browser. I guess it is because the session in the first browser already expires and the newly opened the browser shares the same session with the first one. That is how browsers works, we can do nothing about it.
But our users are of course not very happy about getting the session errors in a newly opened browser. So we tried implementing a heartbeat funtion in AJAX(see att. Below: Heartheat.html and Template.jsp) to keep the session alive until the page is closed. Basically what we do is adding an invisible div tag in every jsp page and invoke AJAX funtion to periodically update the div tag with a small html page. In this way, a request is being sent to the server every 5 minutes thus the session should be kept alive until the page/browser is closed.
It sounds to us like a very logical solution but it doesn’t work very properly. We sometimes still get the session error page immediately after opening a new page while we have another page open for long time.
Could anyone please help to look at our Filter and heatbeat funtion? Is there anything wrong with our Filter or the heartbeat? Why does the session still expire before we close the page?
All we do here is to try to avoid the initial probelm with saving data after session and the application module expires. If anyone has a better solution to this problem, we would very much like to try. Appreciate if anyone can share some ideas!
Thanks in advance!
*1. ApplicationSessionExpiryFilter.java*
public class ApplicationSessionExpiryFilter implements Filter {
private FilterConfig _filterConfig = null;
public void init(FilterConfig filterConfig) throws ServletException {
_filterConfig = filterConfig;
}
public void destroy() {
_filterConfig = null;
}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest)request;
boolean sessionInvalid = false;
if(httpRequest.getRequestedSessionId() != null) {
if(!httpRequest.isRequestedSessionIdValid()) {
if (!httpRequest.getRequestURI().endsWith("sessionExpired.do")) {
sessionInvalid = true;
}
}
}
if (sessionInvalid) {
((HttpServletResponse) response).sendRedirect(_filterConfig.getInitParameter("SessionTimeoutRedirect"));
}
else {
chain.doFilter(request, response);
}
}
}
*2. Heartheat.html* (A small html page to be invoked by template.jsp periodically)
<html>
<head>
<META Http-Equiv="Cache-Control" Content="no-cache, must-revalidate">
<META Http-Equiv="Pragma" Content="no-cache">
<META Http-Equiv="Expires" Content="Expires: Mon, 26 Jul 1997 05:00:00 GMT">
</head>
<body>
heartbeat to keep session alive!
</body>
</html>
*3. Template.jsp* (Template page to be extended by all jsp pages, invoke heart.html every 5 min)
<Html>
……
<body>
…..
<div id="heartbeat" style="display:none">
</div>
<script type="text/javascript" language="javascript">
new Ajax.PeriodicalUpdater('heartbeat','jsp/template/heartbeat.html',{ method: 'post', frequency: 300, decay: 1 }); // update heartbeat.html every 300 sec(5min)
</script>
</body></html>