Tuesday, April 3, 2007

Session Invalidation in struts

Some point of time i realize the error that if i keep the page idle for some time and i do any action in the page it will throw an error because of session invalidation.

Initially i thought to leave as it is and the user has to login again as i won't be get paid a single rupee for this. Later point of time, i thought it couldn't be a good thing to have a page like that. So i need to code to avoid such kind of error. Better way is redirect to login page or a common page where i can say "Your session is timed out ". i chose the first one that redirect to login page.

Then i googled to find out the solutions. But it is not easy to get the solutions. Finally i managed to get one solution.


First we should know how the request is processed in struts.

ActionServlet is the only servlet in Struts framework, and is responsible for handling all of the requests. Whenever it receives a request, it first tries to find a sub-application for the current request. Once a sub-application is found, it creates a RequestProcessor object for that sub-application and calls its process() method by passing it HttpServletRequest and HttpServletResponse objects.

This RequestProcessor class has so many methods to override. According to your business you can override the specific methods to acheive your goals. Now we have to concentrate on processPreProcess method for the above scenario.

Method Signature :
protected boolean processPreprocess javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response)

If this method returns false then the request will abort the processing. we can create our own RequestProcessor and implementing those required methods.

Here is the code to use

package org.val.system.la.action;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.apache.struts.action.RequestProcessor;


public class LASRequestProcessor extends RequestProcessor {
protected boolean processPreprocess( HttpServletRequest request, HttpServletResponse response ) {


boolean isValid = true;

HttpSession httpSession = request.getSession( false );

/* If the request comes from login or index then it should not block the process as these are the gateways in my project. In my project, the user has to login to proceed. Once the user has successful login then i put the information about him into session */

if ( request.getServletPath().equals( "/login.do" ) request.getServletPath().equals( "/index.do" ) ){
isValid = true;
}
else if ( httpSession != null && httpSession.getAttribute( "EMPLOYEEDETAILS" ) != null ){

/* Here we know that the user has successfully logged in as the session has his details */

isValid = true;
}else{
try{

/* Here you can easily assume that the session has expired or user has not yet logged in. One more case is copy the URL and paste it into another browser window. In these cases i forward the request to login page. You can do whatever you want */


request.getRequestDispatcher( "webapp/jsp/Index.jsp" ).forward( request, response );
isValid = false;
}
catch ( Exception ex ){
ex.printStackTrace();
}
}
return isValid;
}
}

Now we have created our custom class. But how does the Struts know that to use our RequestProcessor class.

Here is code to use

Put the below entry in struts-config.xml after action-mappings tag



<controller>
<set-property property="processorClass" value="org.val.system.la.action.LASRequestProcessor">
</controller>


This tag forced to use our RequestProcessor class.

Now if your session is timed out your application goes to login page......

Note: How to invalidate session thru web.xml


<session-config>
<session-timeout>15</session-timeout>
</session-config>


Here 15 is the minutes to keep the session alive. If the session is idle for 15 minutes then it will be timed out. You can set as 1 to test.

No comments: