Monday, June 15, 2009

Session Handling

Normal web pages are "stateless". This means that every time they're loaded is like the first. They don't keep any information around about the user loading them.

This doesn't work for web applications, where we do want to keep information about the user around from page to page. To carry information over from page load to page load, we need to create something called a "session".

A session is basically an id that gets sent to the browser and stored in a cookie. Future page loads on the same domain will send that session id along with the page request. The server then uses that session id as the primary key in a datastore lookup to load in any information you wanted to carry over from page load to page load.

By default, session support in the Java version of App Engine is not enabled. Right click on war/WEB-INF/appengine-web.xml and choose Open With->Text Editor. Just before the ending /appengine-web-app tag, put this line:


<sessions-enabled>true</sessions-enabled>


This makes the class HttpSession available to your servlets. The HttpSession class is how you'll set data on one page and get it on another page. Inside RPXResults.java, after we have the User instance, we can get the HttpSession instance like this:


HttpSession session = req.getSession ();


The HttpSession class then has methods for getting to data you've previously set, and for setting data. Think of it like a map between a property name and a property value. Use the setAttribute method to set property values, and the getAttribute method to get property values.

Another useful method on HttpSession is setMaxInactiveInterval, where you specify the number of seconds the session will live without activity (e.g. the timeout). Pass in a negative value to make the session live forever (or at least until the user clears their cookies).

What do we need to store in the session? Not much, really. The datastore already will have our User records (and other entity records we'll add later), so in the session we just need enough to get to the User in the datastore.

So let's store the user's primary key in the session. From there we can look up the rest of their fields.


HttpSession session = req.getSession();
session.setAttribute("userid", user.getId());


And that's it. In other code we can use getAttribute to fetch the user's id, and then use the datastore to fetch the full User instance for that id.

So the user is officially logged in at this point, although we don't have much of a web site yet to demonstrate that fact. So that's next, to develop a very simple web site that will reflect the logged in status of the user.

2 comments:

  1. HttpSession session = req.getSession();
    session.setAttribute("userid", user.getId());

    This doesn't work with the previous code as user is defined local to the if and else blocks.

    ReplyDelete
  2. Hi Dan, yep there might be some code refactoring that needs to go on working the new techniques in. Since this is written for students in a course, I provide a lot of code early on and less as we go on, expecting them to work through the details of making it work together.

    ReplyDelete