Using Servlet Sessions in GWT – Tutorial

Posted January 17th, 2008 by

Introduction

GWT is a Java framework that allows you to easily develop AJAX (Asynchronous JavaScript and XML) based web applications. Because AJAX based web applications run inside of a browser, they are limited to making requests over HTTP. HTTP is a “stateless” protocol and doesn’t provide any facilities for tracking previous transactions. In this tutorial you will learn how to use GWT’s RPC mechanism, specifically the RemoteServiceServlet, to enable session support in your GWT application.

If you haven’t done so already, please read our previous GWT tutorials, in particular: GWT Introduction, Building a GWT RPC Service, GWT Object Serialization, and Managing History and Hyperlinks.

To learn more about GWT, I recommend reading these good books – GWT Solutions, GWT Applications, AJAX Security.

What is a session?

A session is a mechanism to identify a user across more than one page request or visit to a web-site.

Why do we need sessions?

Java’s Servlet API and by extension GWT’s RPC mechanism offers us the ability to use HTTPSession Interface to create session which can be used to identify users across multiple requests and visits to web-sites (in this case our GWT applications). Using HTTPSession Interface also allows us to bind objects to sessions, allowing user information to be persisted across multiple connections.

GWT and Sessions

In GWT, all GWT services are implemented in classes that extend the GWT RemoteServiceServlet class. The RemoteServiceServlet base class itself extends the HTTPServlet class and thus gives us access to HTTPSessions. The RemoteServiceServlet provides some really nice features outside of just automagically handling serializing incoming and outgoing requests from GWT clients. In this tutorial you will learn how to use a RemoteServiceServlet to get a session and how to use that session to store information on the server.

Need more help? developerlife.com offers training courses to empower you, and consulting services to enable you.

GWT sessions demo – The Weather Application

The Weather Application will be used to demonstrate how we can use sessions to store application information on the server. The Weather Application is an application that allows a user to enter a 5 digit zip-code and make a call to a GWT service to get the weather conditions at that zip-code. The service gets its weather data from weather.com’s XML data feed. Each successful weather query is saved to the server side session. The Weather Application displays the list of successful queries stored in the session as a list of GWT Hyperlinks. The Weather application is also History enabled. This means that users can use their browser’s back and forwards buttons in the Weather Application.

Accessing an HTTPSession in GWT

Server side sessions (HTTPSessions) can be accessed from inside of GWT remote service implementations. Before a GWT service implementation can get a hold of the current HTTPSession object, it needs to get a handle on the current request (HTTPServletRequest). The RemoteServiceServlet class makes actually getting the current request very simple. The following line of code must be called from inside of your remote service implementation class.

HttpServletRequest request = this.getThreadLocalRequest();

Once we have the HTTPServletRequest we can use it to get the current HTTPSession

HTTPSession session = request.getSession();

Storing data in a session

Now that we have the session, we can use it to persist information on the server side. Each HTTPSession object has a built-in data store that allows you to store any number of key/value pairs. The Weather Application uses the server side session to store a HashMap of unique successful queries. Here is code for methods that can be used to get and put a HashMap into a session. This code can be found in Utils.java:

   1: /**
   2:  * Get a HashMap from the session
   3:  *
   4:  * @param key       Key for the HashMap to be extracted from the Session
   5:  * @param session   session from which to get HashMap
   6:  * @return          A HashMap
   7:  */
   8: public static HashMap getHashMapFromSession(String key, HttpSession session) {
   9:   // If the session does not contain anything, create a new HashMap
  10:   if (session.getAttribute(key) == null) {
  11:     session.setAttribute(key, new HashMap());
  12:   }
  13:
  14:   // Return the HashMap
  15:   return (HashMap) session.getAttribute(key);
  16: }
  17:
  18:
  19: /**
  20:  * Adds a link to the session
  21:  * @param key       Key to the HashMap stored in the session
  22:  * @param session   HttpSession from which to extract the HashMap
  23:  * @param zipCode   zipCode of successful query
  24:  * @param location  location of successful query
  25:  */
  26: public static void addSuccessfulQueryToSession(String key, HttpSession session, String zipCode, String location) {
  27:   HashMap mapOfResults = Utils.getHashMapFromSession(key, session);
  28:   mapOfResults.put(location, zipCode);
  29: }

Putting it all together

Here is the implementation (WeatherServiceImpl.java) of the Weather Service. The Weather Service has two methods, one to get the current weather give a zip-code, and another to get the HashMap of successful queries so far from the session.

When a client makes a Weather Service call to get the current weather for a particular zip-code, the service implementation attempts to get the current from the weather.com XML data feed. If it is successful in getting the weather from the feed, the service implementation gets the session from the current request, gets the HashMap of successful queries from the session, puts the new query into the HashMap, and puts the HashMap back into the session.

When a client makes makes a call to get the list of successful queries so far, the service implementation gets the session from the current request, gets the HashMap from the session and returns the HashMap to the client.

   1: public class WeatherServiceImpl extends RemoteServiceServlet implements WeatherService {
   2:   public static final String partnerID = "";
   3:   public static final String licenseKey = "";
   4:   public static final String ALL_SUCCESSFUL_WEATHER_QUERIES_SO_FAR = "WeatherQueryHistory";
   5:
   6:
   7:   /**
   8:    * Returns all the successful weather queries so far
   9:    * @return  HashMap of successful weather queries so far
  10:    */
  11:   public HashMap getAllSuccessfulWeatherQueriesSoFar() {
  12:     return Utils.getHashMapFromSession(ALL_SUCCESSFUL_WEATHER_QUERIES_SO_FAR, getSession());
  13:   }
  14:
  15:
  16:   /**
  17:    * Get the current weather for the given zip code
  18:    * @param zipCode The zip code for the location where you want to know the weather
  19:    * @return        The current weather at the give zip code
  20:    */
  21:   public CurrentWeatherConditions getCurrentWeather(String zipCode) {
  22:     WeatherConfigurationIF config = new DefaultWeatherConfigurationBean(DefaultWeatherConfigurationBean.defaultWeatherServer,
  23:                                                                         partnerID, licenseKey);
  24:     weather_service.weatherprovider.WeatherGateway gateway = new WeatherGateway(config);
  25:     WeatherReport weatherreport = null;
  26:     CurrentWeatherConditions currentweather = null;
  27:
  28:     // Try and get the weather forecast
  29:     try {
  30:       // Get the forecast for the give zip code for one day
  31:       weatherreport = gateway.getFullForecast(zipCode, 1);
  32:
  33:       // If there is no weather report, print out an error message
  34:       if (weatherreport == null) {
  35:         System.out.printf("locationID [%s] is not valid or no xml data returned, weather is null\n\n", zipCode);
  36:       }
  37:       // If there is a weather report, get the current weather
  38:       else {
  39:         System.out.printf(":::: WeatherReport ::::\n%s\n::::\n", weatherreport);
  40:
  41:         // Create a GWT serializable representation of the current weather
  42:         currentweather = Utils.getCurrentWeatherFromReport(weatherreport);
  43:
  44:         // Save the link to the Session
  45:         Utils.addSuccessfulQueryToSession(ALL_SUCCESSFUL_WEATHER_QUERIES_SO_FAR,
  46:                                           getSession(),
  47:                                           zipCode,
  48:                                           currentweather.getLocation());
  49:       }
  50:     }
  51:     catch (IOException e) {
  52:       System.out.printf("---- Network connection problem or invalid server address, %s ----\n", e);
  53:     }
  54:     catch (WeatherError weatherError) {
  55:       System.out.printf("---- Exception reported from parsing weather/response, %s ----\n", weatherError);
  56:     }
  57:
  58:     return currentweather;
  59:   }
  60:
  61:
  62:   /**
  63:    * Returns the current session
  64:    *
  65:    * @return  The current Session
  66:    */
  67:   private HttpSession getSession() {
  68:     // Get the current request and then return its session
  69:     return this.getThreadLocalRequest().getSession();
  70:   }
  71: }

Weather app screenshot

weather

Downloads

All the source code provided on this site is distributed under the Apache Open Source License v2.0.

  1. You can download the full source code used to build the Weather Application here.
  2. You can download the WAR file to deploy the Weather Application here.

Comments are closed.