Sessions and Cookies
final static String COOKIE_NAME = "visitCounter";
// This method uses cookies to find out how many times the user
// has visited the servlet before:
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException {
response.setContentType("text/plain; charset=UTF-8"); // plain text (more)
response.setCharacterEncoding("UTF-8");
PrintWriter writer = response.getWriter();
// Finding the cookie (if it exists)
int visits = 0;
if (request.getCookies() != null) // may be null if no cookies (more)
for (Cookie c: request.getCookies())
if (c.getName().equals(COOKIE_NAME) && c.getValue().matches("[0-9]+"))
visits = Integer.parseInt(c.getValue());
// Print a message for the user
if (visits == 0)
writer.println("This is your first visit.");
else
writer.printf("This is visit number %d.\n", visits); // formatted printing (more)
// Set / Update the cookie (more)
Cookie c = new Cookie(COOKIE_NAME, Integer.toString(visits + 1));
c.setMaxAge(60*60*24*28); // valid for 28 days (more)
response.addCookie(c);
}
HttpSession allows you to store arbitrary objects for a user as named attributes. Sessions are managed by the web container, which associates a session id with every session and uses mechanisms such as cookies to store the session id in the client (more).
Sessions are typically short lived, and do not survive neither a browser-restart nor a server-restart (more).
The following example implements a visitor counter with HttpSessions:
final static String ATTRIBUTE_NAME = "visitCounter";
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException {
response.setContentType("text/plain; charset=UTF-8"); // plain text (more)
response.setCharacterEncoding("UTF-8");
PrintWriter writer = response.getWriter();
// Reading the session
int visits = 0;
HttpSession session = request.getSession(); // can create session (more)
if (session.getAttribute(ATTRIBUTE_NAME) != null) // not set in new sessions
if (c.getName().equals(COOKIE_NAME) && c.getValue().matches("[0-9]+"))
visits = (Integer) session.getAttribute(ATTRIBUTE_NAME);
// Print a message for the user
if (visits == 0)
writer.println("This is your first visit.");
else
writer.printf("This is visit number %d.\n", visits); // formatted printing (more)
// Update the session
session.setAttribute(ATTRIBUTE_NAME, visits + 1);
session.setMaxInactiveInterval(60*60*24); // valid for 24 hours max
}
Sessions in Distributed Servers (Clusters)
When you configure your web application to be distributable (thus you have not a single container, but a cluster of containers hosting your application), you must be sure that you store only serializable objects in the session (some containers also support EJB references). Distributable containers can move sessions across servers, and serialization allows the container to do this. Objects stored in a session can implement the HttpSessionActivationListener interface to be notified before and after such a migration.
See also How to Write Distributed Applications below.
Be Careful When Using HttpSession
HttpSession looks simple and easy to use. In practice, however, you should consider carefully what you store in a session. There are three pitfalls:
- Attribute values put into the session will be accessed by several threads simultanously, so proper synchronization and/or thread-safe objects are required.
- In general, you should store only the user's identity and configuration in the session. Using it for most other purposes, for example storing the state of a multi-page form in the session, is a very bad idea (more).
- When working with sessions, be careful about memory use. If you store large objects in your session and have many visitors, you may run out of heap memory. Be aware that people with disabled cookies create a new session with every hit, because they always look like a new visitor to the server.
Often using cookies is easier than using sessions. You may need to write a few more lines to use them, but they are easier to debug and implement correctly.

