Tutorial: HTTP Session handling using Servlet Filters

Following small piece of code comes handy whenever you are working for a J2EE web application in JSP/Servlet/Struts/JSF or any Servlet oriented web framework.
A lot of time we have to handle session errors in such applications and redirect user to particular error page. Generally user is redirected to the login page where she can giver her credential and log in the application again.
In my previous post, I wrote about handling session errors and other server errors at client side using AJAX. But for doing this still we have to handle the session errors first at server side.

Let us see how we can track user session using Servlet Filter and redirect her to login page if session is already invalidated. We will induce session tracking facility to our web project (for this tutorial, I am using normal JSP web application in Eclipse).

Step 1: Create Servlet Filter to track Session

Create a package to place our session filter (in this case net.viralpatel.servlet.filter) and create a Java class SessionFilter.
session-handle-servlet-filter
Copy following code in the Java file.

package net.viralpatel.servlet.filter;

import java.io.IOException;
import java.util.ArrayList;
import java.util.StringTokenizer;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

public class SessionFilter implements Filter {

	private ArrayList<String> urlList;
	
	public void destroy() {
	}

	public void doFilter(ServletRequest req, ServletResponse res,
			FilterChain chain) throws IOException, ServletException {

		HttpServletRequest request = (HttpServletRequest) req;
		HttpServletResponse response = (HttpServletResponse) res;
		String url = request.getServletPath();
		boolean allowedRequest = false;
		
		if(urlList.contains(url)) {
			allowedRequest = true;
		}
			
		if (!allowedRequest) {
			HttpSession session = request.getSession(false);
			if (null == session) {
				response.sendRedirect("index.jsp");
			}
		}
		
		chain.doFilter(req, res);
	}

	public void init(FilterConfig config) throws ServletException {
		String urls = config.getInitParameter("avoid-urls");
		StringTokenizer token = new StringTokenizer(urls, ",");

		urlList = new ArrayList<String>();

		while (token.hasMoreTokens()) {
			urlList.add(token.nextToken());

		}
	}
}

The init() method will get called by the servlet container and will get FilterConfig object as arguement. From this config object, we read the init parameters. We will see shortly what parameters do we passed in filter.

The doFilter() method will be called for each request of our application. Hence we can check the session in this method and see if it is valid. From init() method, we had generated a list of pages (urls) that were having access although the session is null. Index pages, error pages and other pages that you think user can access without logging in should be specified in this list.

In doFilter() method, you will notice one response.sendRedirect. I have redirected my user to index.jsp page if session is not valid. You can give any landing URL that you want your user to go when session is not valid. Alternatively you may want to create a JSON response and send it to client if you think the request was originated from AJAX.

Step 2: Specify filter entry in Web.xml deployment descriptor

Copy following entry in your application’s Web.xml file.

<filter>
	<filter-name>SessionFilter</filter-name>
	<filter-class>
		net.viralpatel.servlet.filter.SessionFilter
	</filter-class>
	<init-param>
		<param-name>avoid-urls</param-name>
		<param-value>index.jsp</param-value>
	</init-param>
</filter>
<filter-mapping>
	<filter-name>SessionFilter</filter-name>
	<url-pattern>/*</url-pattern>
</filter-mapping>

We have specified the filter in web.xml file which will get called for url /*. You can configure the URL mapping like normal filters URL mapping. Also note that we have specified a parameter avoid-url in init-parameters of filter. The value of this parameter will be a comma separated paths that we do not want to apply session validations on. I have specified index.jsp, you can give more urls separated by comma.
e.g.
index.jsp, someAction.do, Request.jsp, Message.jsf



41 Comments

  • Corey Cole 14 February, 2009, 1:02

    Wouldn\’t you want a \"break\" statement after line 35?

    With the current implementation it’s a meaningless optimization, but if there were a number of non-session oriented pages you wouldn’t want to continually do String compares when it doesn’t change the result.

  • Viral Patel 18 February, 2009, 14:45

    Thanks Corey.
    I have updated the post and added the break statement. Certainly a break will be needed in order to skip unnecessary comparisons.

  • Shahram 16 April, 2009, 4:24

    Based on J2EE javadoc, HttpServletRequest.getSession() will always return a session object. (If the session dose not already exists, it will create a new one). I think in line 41 you need to have HttpSession session = request.getSession(false);

  • Viral Patel 16 April, 2009, 13:24

    Thanks Shahram for pointing out the error. I have modified the code and added HttpSession session = request.getSession(false); instead of HttpSession session = request.getSession();
    Thanks again :)

  • dod 28 May, 2009, 19:20

    it doesn,t works.
    I have this exception :
    java.lang.IllegalStateException: Cannot forward after response has been committed

  • Viral Patel 28 May, 2009, 19:40

    Hi Dod,
    Can you please paste your Filter code? The above code seems to be working for me.
    The error you are getting comes when you try to do response.sendRedirect( ) after printing something in response. You may have some out.print () statements before the redirect.

    Still I am not sure about the problem.

  • dod 28 May, 2009, 20:14

    that’s my code:

    public void doFilter(ServletRequest req, ServletResponse res, 
    	FilterChain chain) throws IOException, ServletException {
    
    	HttpServletRequest request = (HttpServletRequest) req;  
    	HttpServletResponse response = (HttpServletResponse) res;  
    
    	String url = request.getServletPath();  
    	boolean allowedRequest = false;  
    
    	for(int i=0; i<totalURLS; i++) {  
    		if(url.contains(urlList.get(i))) {  
    			allowedRequest = true;  
    			break;  
    	    	}  
    	}  
    	if (!allowedRequest) {  
    		RequestDispatcher disp = null;
    		HttpSession session = request.getSession();  
    		if (null == session) {  
    		response.sendRedirect("/jsp/loginError.jsp");  
    		}else{
    
    			String logged = (String) session.getAttribute("logged-in");
    			if (logged == null) {
    				response.sendRedirect("/jsp/loginError.jsp");  
    			}
    		}
    	}
    
    	chain.doFilter(request, response);
    }
    
  • dod 28 May, 2009, 20:56

    Ok, so the code seems to be working

    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {

    HttpServletRequest request = (HttpServletRequest) req;
    HttpServletResponse response = (HttpServletResponse) res;

    String url = request.getServletPath();
    String contextPath = request.getContextPath();
    boolean allowedRequest = false;

    for(int i=0; i<totalURLS; i++) {
    if(url.contains(urlList.get(i))) {
    allowedRequest = true;
    break;
    }
    }
    if (!allowedRequest) {
    HttpSession session = request.getSession();
    if (null == session) {
    response.sendRedirect(contextPath+”/jsp/loginError.jsp”);
    }else{
    String logged = (String) session.getAttribute(“logged-in”);
    if (logged == null){
    response.sendRedirect(contextPath+”/jsp/loginError.jsp”);
    }else{
    chain.doFilter(request, response);
    }
    }
    } else{
    chain.doFilter(request, response);
    }

    }

  • Viral Patel 28 May, 2009, 21:05

    Nice to see that your error got resolved :-)
    I think the code HttpSession session = request.getSession(); needs to be replaced with HttpSession session = request.getSession(false); otherwise everytime a new session will get created.

  • FlorianR 16 October, 2009, 15:43

    Hi dod,

    you’ve got an error in line 34, please remove the semicolon.
    Additionally i get the “Cannot create a session after the response has been committed”-message, too, although i don’t put anything in out?!

    Any idea?

    ————–
    public class SessionFilter implements Filter {
    private ArrayList urlList;
    private int totalURLS;

    public void destroy() {
    }

    public void doFilter(ServletRequest req, ServletResponse res,
    FilterChain chain) throws IOException, ServletException {

    HttpServletRequest request = (HttpServletRequest) req;
    HttpServletResponse response = (HttpServletResponse) res;
    String url = request.getServletPath();
    boolean noSessionNeeded = false;

    for(int i=0; i<totalURLS; i++) {
    String pattern=urlList.get(i);
    if(url.contains(pattern)) {
    noSessionNeeded = true;
    break;
    }
    }

    if (!noSessionNeeded) {
    HttpSession session = request.getSession(false);
    boolean exists=(session!=null);
    boolean isNew=session.isNew();
    if(!exists) response.sendRedirect("index.jsp");
    if(isNew) response.sendRedirect("index.jsp");
    }

    chain.doFilter(req, res);
    }

    public void init(FilterConfig config) throws ServletException {
    String urls = config.getInitParameter("noSessionNeeded");
    StringTokenizer token = new StringTokenizer(urls, ",");

    urlList = new ArrayList();

    while (token.hasMoreTokens()) {
    urlList.add(token.nextToken());

    }
    totalURLS = urlList.size();
    }
    }

    • Arjun 18 June, 2012, 13:01

      Add a return after the forward/redirect statement, this will remove the illegalArgumentException

  • daniel 29 October, 2009, 17:35

    I had the problem with “Cannot create a session after the response has been committed” when using filter and JSF.
    The solution was to do a requestDispatcher.forward instead of response.sendRedirect.
    Look here:
    http://javaboutique.internet.com/tutorials/Servlet_Filters/redirect.html

    • Viral Patel 30 October, 2009, 18:57

      Hi daniel, Thanks for sharing useful link.

  • Keith 30 October, 2009, 20:25

    When my session expires it’s not making it to the filter? Any idea of what I might be missing that is causing this to happen?

  • Keith 9 November, 2009, 23:39

    Hello Viral,

    Thank you for this tutorial it’s been very useful. Is there a way to send the user to the page they’ve selected when the session expired?

    What I have done is to store the selected link as an attribute and tried to alter the response by setting it as the string of the response.sendRedirect but this isn’t working for me. Do you have any advice as to how I might be able to achieve this?

    Thanks.

  • Selvanayagam 17 November, 2009, 10:15

    I have a problem

    After the session expires. the user is asked to relogin. When he relogins
    he must be redirected to the page the where the session expired. I please to send me your
    reply to mail id. I am waiting for your reply

    thanks in advance

  • Chandra 23 February, 2010, 22:53

    Hi Viral,

    Can we do the same thing..i.e when user copy paste the URL in new window, he must be redirected to Login page using JSPs. I am using Struts 2.0 framework. I am not using servlets. Filters are available for servlets only or for JSPs also?

    TIA

    • Viral Patel 23 February, 2010, 23:41

      @Chandra: The above example will work for you in any case. i.e. it will work for JSPs, Servlets or Struts2 as well. Filters are available for both servlets and JSPs because we have mapped /* url with filter SessionFilter.

  • Nageswar 10 June, 2010, 22:28

    Hi I am getting StringTokenizer null pointer error, i Tried but same thing is comming.
    if you have any solution plz send me

    String urls = filterConfig.getInitParameter(“avoid-urls”);
    StringTokenizer token = new StringTokenizer(urls, “,”);
    urlList = new ArrayList();
    while (token.hasMoreElements()) {
    urlList.add(token.nextToken());
    }
    totalURLS = urlList.size();

  • sai 24 June, 2010, 9:09

    Hi,

    how can use this for ajax applications. per say, i have extjs spring applications. need to handle session time out or if session is not their, redirect to different page..

  • raju 6 December, 2010, 23:23

    wrt a prg html page(login.html) which accept username and password.Authenticaticate them using filters and then to helloworld servlet if the user is a valid .(if username is “genesis” print response as “hello” ,otherwise print response as “invaliduser” )……………

    answer give me

  • Alex Vicente Chacón Jiménez 20 February, 2011, 21:32

    Thank you very much for this article.
    But I improved the example in the following way:

    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException
    	{
    
    		HttpServletRequest request = (HttpServletRequest) req;
    		HttpServletResponse response = (HttpServletResponse) res;
    		String url = request.getServletPath();
    		
    		if (urlList.contains(url))
    		{
    			chain.doFilter(req, res);
    		}
    		else
    		{
    			HttpSession session = request.getSession(false);
    			
    			if (session == null )
    			{
    				response.sendRedirect(request.getContextPath());
    			}
    			else
    			{
    				chain.doFilter(req, res);
    			}
    		}	
    	}
    

    This code prevent a java.lang.IllegalStateException: Cannot forward after response has been committed

  • learner 23 March, 2011, 17:03

    Hi I keep on getting The page isn’t redirecting properly error, any ideas?

    thanks

  • Sandeep 22 August, 2011, 19:13

    Hi, I’m developing a web application using JSP. In my application, after user login, if he clicks back button of the browser, he should not go to the index page of my website. can u help me with this?

  • Gisli 8 September, 2011, 22:46

    I’m basically getting the same error as “learner”. I didn’t use this code but rather wrote my own. I have discovered that if I call getSession()/getSession(true), I always geta brand new session. If I call getSession(false) I always get null. I’ve been tearing my hair out over this the past few days. If I set session attributes in the filter and check them in the page where the filter redirects me to, I can read the values. But if I set attributes in the page, the filter never sees them because, as I said, getSession either returns null or a brand new session.

    I’m using Tomcat 7.0.2. I’ve been using basic JSPs for years but this is the first time I create a servlet filter. I thought it was so brilliant until I hit this wall.

    Hope you can help me. I would post the code but don’t have access to it right now.

    • Chripin 19 September, 2011, 17:22

      @Gisli I am getting the same problem. But when i use tomcat v6 i don’t get the problem.
      My problem is that the values i place in the session are lost.
      If you find the solution please update me.

  • Costas 1 March, 2012, 10:50

    Hello,
    nice tutorial, but i have a problem with me web.xml. I copied it like you have but still doesnt work for me. what changes do i have to make on both of them?
    do i have to do something else to the other jsp files ?
    thanks

  • vikas 5 September, 2012, 14:52

    hello Sir thank you very much for ur nice tutorial
    But I am getting following error…

    “The page isn’t redirecting properly”
    Any suggestion will be herately appreciated …….

    here is my web.xml code

    SessionFilter

    SessionFilter

    avoid-urls
    index.jsp

    SessionFilter
    /*

    LoginServlet
    LoginServlet

    SuccessPage
    SuccessPage

    Failure
    Failure

    SessionFilter
    SessionFilter

    LoginServlet
    /LoginServlet

    SuccessPage
    /SuccessPage

    Failure
    /Failure

    1

  • vikas 6 September, 2012, 12:03

    hello Sir,
    Thank you very much for such nice article but in my case its not working

    Error is ““The page isn’t redirecting properly””.plz sir help me to resolve the problem
    As I am in need of it badly in my current App
    Plz sir reply soon plz sir

  • bhuvana 12 November, 2012, 15:27

    Hi sir,
    How can i handle session when it is expired.
    Actually i want to save the expired time in to database….when i click.

    plz replay me soon….

    • Johnson George 8 January, 2013, 12:10

      u can check is session invalid or not in inside filter class

  • Pankaj 23 December, 2012, 21:08

    Hello Mr Patel
    Its really an awesome article.
    I have been searching for an example code where i can get some idea about session filter to implement.Your code did this for me and its working well.
    except two things 1. should have a return after redirect and 2.request dispatcher.
    otherwise it was throwing error like “…..after the response has been committed”
    After reading all responses these issues are resolved.
    Thanks a lot.

  • Yogesh 9 January, 2013, 19:34

    HttpSession session = request.getSession(false);
    if(session == null){
    //code
    }

    For the first request i am getting session null but on second request it returns org.apache.catalina.session.StandardSessionFacade

    so what could be the problem?

    • aryan 11 January, 2013, 0:50

      Dear Yogesh,

      same problem facing, one of my workmate, I’ll ask him. ;)

  • henry & pao 6 July, 2013, 2:53

    you just saved our lives and our jobs, love you you are the best, we have been dealing with this months ago………….

  • Pankaj 14 July, 2013, 2:51

    Is there any way to set the time out time?

  • Anuja Patil 7 October, 2013, 23:51

    hello.. i m observing in my maven proj web app code while using filters that when we write HttpSession session=request.getSession(true) in servlet, a new session is created. Now acc. to my code, before calling this servlet, filter should be called. In filter, request.getSession().getAttribute and likely instructions create new session. My question is , is it like when you call filter before servlet, a new session would be created with above lines? Because, in my servlet i have invalidated current session and i am trying to call servlet through address bar to check if session is actually expired or not. However because of request.getAttribute() creates a new session instead of null.

  • balza 25 October, 2013, 14:44

    This filter should chain to other filters (row 43). If you redirect to index.jsp (row 39), the remaining filter will activate and you’ll get a “Response already committed” error . To avoid this behaviour you have to break the filters chain putting a

    return;

    after row 39.

  • Akhil 6 December, 2013, 11:38

    Good Content. Thanks Virat. This tutorial helped me a lot.

  • Gagan Chamria 12 February, 2014, 18:19

    replace this line:

     <param-value>index.jsp</param-value>

    with this:

     <param-value>/index.jsp</param-value>

    as below line of code return servlet path with prefix “/” :

     String url = request.getServletPath();  
  • Sachin 5 March, 2014, 21:06

    Hi Viral,

    Can you please provide some tutorial on how to remove JSessionId from URLs in Spring MVC application (at programming side and as well server side).

    Thanks,
    Sachin

Leave a Reply

Your email address will not be published. Required fields are marked *

Note

To post source code in comment, use [code language] [/code] tag, for example:

  • [code java] Java source code here [/code]
  • [code html] HTML here [/code]

Current ye@r *