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). [ad#blogs_content_inbetween]

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. 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()); } } }
Code language: Java (java)
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>
Code language: HTML, XML (xml)
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

View Comments

  • 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.

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

  • 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);

  • 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 :)

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

  • 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.

  • 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);
    }
    
  • 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);
    }

    }

  • 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.

  • 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();
    }
    }

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

Share
Published by
Viral Patel
Tags: http session java servlet filter JavaEE servlet servlet filters session handling

Recent Posts

  • Java

Java URL Encoder/Decoder Example

Java URL Encoder/Decoder Example - In this tutorial we will see how to URL encode/decode…

4 years ago
  • General

How to Show Multiple Examples in OpenAPI Spec

Show Multiple Examples in OpenAPI - OpenAPI (aka Swagger) Specifications has become a defecto standard…

4 years ago
  • General

How to Run Local WordPress using Docker

Local WordPress using Docker - Running a local WordPress development environment is crucial for testing…

4 years ago
  • Java

Create and Validate JWT Token in Java using JJWT

1. JWT Token Overview JSON Web Token (JWT) is an open standard defines a compact…

4 years ago
  • Spring Boot

Spring Boot GraphQL Subscription Realtime API

GraphQL Subscription provides a great way of building real-time API. In this tutorial we will…

4 years ago
  • Spring Boot

Spring Boot DynamoDB Integration Test using Testcontainers

1. Overview Spring Boot Webflux DynamoDB Integration tests - In this tutorial we will see…

4 years ago