title: Delay concurrent requests from a client until HttpSession is created
body: <p>I have a <code>servlet.Filter</code> implementation that does a lookup of a client's user ID in a database table (based on the IP address), it attaches this data to an <code>HttpSession</code> attribute. The filter does this whenever it receives a request from a client without a defined <code>HttpSession</code>.</p>
  
  <p>In other words, if there is no session attached to a request, the filter will: </p>
  
  <ul>
  <li>create a session for the client</li>
  <li>do a database lookup for the user ID</li>
  <li>attach the user ID as a session attribute</li>
  </ul>
  
  <p>This all works fine if there is some time in between requests from a "session-less" client.</p>
  
  <p>But if a "session-less" client sends 10 requests within milliseconds of each other I end up with 10 sessions and 10 database queries. It still "works" but I don't like all of these sessions and queries for resource reasons.</p>
  
  <p>I <em>think</em> this is because the requests are so close together. When a "session-less" client sends a request and gets a response before another request is sent I don't have this problem.</p>
  
  <p>The relevant parts of my filter are:</p>
  
  <pre><code>// some other imports
  
  import org.apache.commons.dbutils.QueryRunner;
  import org.apache.commons.dbutils.handlers.MapHandler;
  
  public class QueryFilter implements Filter {
  
      private QueryRunner myQueryRunner;  
      private String myStoredProcedure;
      private String myPermissionQuery;
      private MapHandler myMapHandler;
  
      @Override
      public void init(final FilterConfig filterConfig) throws ServletException {
          Config config = Config.getInstance(filterConfig.getServletContext());
          myQueryRunner = config.getQueryRunner();
          myStoredProcedure = config.getStoredProcedure();
          myUserQuery = filterConfig.getInitParameter("user.query");
          myMapHandler = new MapHandler();
      }
  
      @Override
      public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 
              throws ServletException {
  
          HttpServletRequest myHttpRequest = (HttpServletRequest) request;
          HttpServletResponse myHttpResponse = (HttpServletResponse) response;
          HttpSession myHttpSession = myHttpRequest.getSession(false);
          String remoteAddress = request.getRemoteAddr();
  
          // if there is not already a session
          if (null == myHttpSession) {
  
              // create a session
              myHttpSession = myHttpRequest.getSession();
  
              // build a query parameter object to request the user data
              Object[] queryParams = new Object[] { 
                  myUserQuery, 
                  remoteAddress
              };
  
              // query the database for user data
              try {
                  Map&lt;String, Object&gt; userData = myQueryRunner.query(myStoredProcedure, myMapHandler, queryParams);
  
                  // attach the user data to session attributes
                  for (Entry&lt;String, Object&gt; userDatum : userData.entrySet()) {
                      myHttpSession.setAttribute(userDatum.getKey(), userDatum.getValue());
                  }
  
              } catch (SQLException e) {
                  throw new ServletException(e);
              }
  
              // see below for the results of this logging
              System.out.println(myHttpSession.getCreationTime());
          }
  
          // ... some other filtering actions based on session
      }
  }
  </code></pre>
  
  <p>Here are the results of logging <code>myHttpSession.getCreationTime()</code> (timestamps) from ONE client:</p>
  
  <pre><code>1343944955586
  1343944955602
  1343944955617
  1343944955633
  1343944955664
  1343944955680
  1343944955804
  1343944955836
  1343944955867
  1343944955898
  1343944955945
  1343944955945
  1343944956007
  1343944956054
  </code></pre>
  
  <p>As you can see, almost all the sessions are different. These timestamps also give a good idea of how close the requests are spaced together (20ms - 50ms).</p>
  
  <p>I can't redesign all client-side applications to ensure that they get at least one response before they send another request intially, so I want to do that in my filter.</p>
  
  <p>Also, I don't want to just make the subsequent requests fail, I would like to figure out a way to handle them.</p>
  
  <p><strong>Question</strong></p>
  
  <ul>
  <li><p>Is there a way to put subsequent requests from the same client (IP address) into "limbo" until a session has been established from the first request?</p></li>
  <li><p>And, if I manage that, how can I get the correct <code>HttpSession</code> (the one that I attached the user data to) when I call <code>aSubsequentRequest.getSession()</code> afterwards? I don't think I can assign a session to a request but I could be wrong.</p></li>
  </ul>
  
  <p>Maybe there is some better way to go about this entirely. I basically would just like to stop this filter from running the lookup query 10 - 20 times unnecessarily within a 2 second time period.</p>