Retaining Client and State Information

All but very simple Web applications are likely to require that information of some kind about the client be retained between different page requests. As has been stated, HTTP is stateless and does not provide a mechanism to ascertain that a series of requests have come from the same client.

There are a number of ways of retaining information about clients, such as hidden fields, cookies, and sessions (all described in this section). HTTP sessions are by far the simplest to use and are the recommended approach for Web Applications. Other techniques such as using HTTP cookies or hidden form fields belong to older, non servlet, technologies such as CGI scripts.

Using Session Objects

Sessions identify page requests that originate from the same browser during a specified period of time. Conveniently, a session is shared by all the servlets in an application accessed by an individual client. Servlet containers can implement sessions using one of three techniques:

  • Cookies The server sends a cookie called JSESSIONID with the HTTP response. If the browser disables cookies, then servlet URL Rewriting must be used (see section “URL Rewriting”)

  • SSL Secure Sockets Layer has a built-in mechanism allowing multiple requests from a client to be unambiguously identified as being part of a session.

  • URL Rewriting Appends extra information to a URL to identify the session (see section “URL Rewriting”).

Regardless of the session tracking technique used, the javax.servlet.http.HttpSession object identifies a session and is obtained using the HttpServletRequest.getSession() method. The HttpSession object contains the information shown in Table 12.5. This information can be used to identify the session.

Table 12.5. Information Accessed Through HttpSession Objects
Access MethodInformation
getId()Unique session identifier
getLastAccessedTime() The last time the client sent a request associated with this session
getCreationTime()The time when this session was created
getMaxInactiveInterval()The maximum time interval, in seconds, that the servlet container will keep this session open between client accesses
getAttribute()Objects bound to this session
setAttribute()Binds new objects to this session
invalidate()Invalidates the session allowing the Servlet container to reclaim resources allocated to the session.

Behind the scenes, most Web servers implement session tracking using cookies. Information is stored in the cookie to associate a session identifier with a user. The explicit use of cookies to do the same thing is described later in this section.

Creating a Session

To create a session, the servlet must first get a HttpSession object for a user. The HttpServletRequest.getSession() method returns a user's current session. If there is no current session, it will create one before returning it.

You must call getSession() before any output is written to the response (that is, before accessing the PrintWriter, not just before sending any HTML or other data to the client), otherwise the cookie identifying the session may not be sent back to the client.

You can use HttpSession.isNew() to determine if a session has been created. The following shows the use of getSession() to return an HttpSession object:

public void doGet (HttpServletRequest req, HttpServletResponse res)
      throws ServletException, IOException {
  HttpSession session = req.getSession();
  out = res.getWriter();
  if (session.isNew()) {
   /* new session created ok */
  }
}

After a session is created, you can start associating objects with the session. The following code could be used in a shopping cart application. It checks to see if the user already has a shopping cart in this session. If no cart exists, one is created.

HttpSession session = request.getSession();
ShoppingCart cart = (ShoppingCart)session.getAttribute("candystore.cart");
if (cart == null) {
  cart = new ShoppingCart();
  session.setAttribute("candystore.cart", cart);
}

Invalidating a Session

A session can either be manually invalidated or allowed to timeout. The default timeout period is defined in the Web.xml deployment descriptor or through the administrative interface to the Web server. A servlet can control the period of time between client requests, before the servlet container will invalidate this session, with HttpSession.setMaxInactiveInterval(int seconds). Setting a negative time ensures the session will never timeout.

A call to the HttpSession.invalidate() method also invalidates a session and unbinds any objects bound to it. This is a useful thing to do if the user logs out of your application.

Hidden Form Fields

Another way of supporting session tracking is to use hidden form fields. These fields on an HTML page are not seen by the user. To the server, there is no difference between a hidden field and a non-hidden field, but in the browser, hidden fields are not displayed.

The following is an example of a hidden field that could be used to record that the user had read the terms and conditions:

<INPUT TYPE="hidden" NAME="terms" VALUE="true">

Hidden fields have several disadvantages over HTTP sessions:

  • They only work for a sequence of dynamically generated forms.

  • They fail if there is an error before the data is permanently stored somewhere.

  • They may be modified by rogue users attempting to hack into your application.

  • They may expose sensitive or confidential data to other users of the client workstation.

CAUTION

The user can modify the values stored in hidden fields, so they are not secure. Do not use hidden fields to hold data that will cause a problem if it is compromised.


Cookies

The HttpSession interface and hidden fields provide a simple way to track information during a single session, but they both have the drawback that they cannot be used to retain information across multiple browser sessions. To do this, you must create and manage your own data using cookies. You may also need to use cookies if you are writing servlets to interoperate with other Web technologies (such as CGI scripts).

CAUTION

Any use of cookies comes with a major health warning. As you will see, they are easy to forge and, because they are not always handled consistently, they are inherently unreliable.


You need to be aware that, as a security precaution, a browser can be set up to reject cookies. In this case, you will need to use an additional and alternative method (hidden fields or URL rewriting) to track sessions. Also, cookies should not be used when the information is important or sensitive. Cookies are associated with a browser and can be stored as text in the file system on the client's host. Consequently, cookies

  • Are not secure because they are easy to edit or replace

  • Potentially can be viewed by other users of the same workstation

  • Can allow a user to impersonate another user

  • Are not available if the user changes his or her workstation or browser

Remember that many users may share some machines, such as Internet café public access terminals.

A cookie has a name and a single value, both of which are strings. It may also have optional attributes, such as a comment, path and domain qualifiers, a maximum age, and a version number. Browsers vary as to how they handle cookie attributes, so use them with caution. The browser may also have a limit on the number of cookies it will handle at any one time and may set a limit on the size of the value for a cookie.

The cookie information is sent as part of the HTTP response header. If the browser accepts cookies, it will store the cookie on the client.

Creating a Cookie

You can use a javax.servlet.http.Cookie object to store information that will remain persistent across multiple HTTP connections.

CAUTION

Cookies can be deleted (sometimes automatically by the browser), so your code should never rely on a cookie being available.


The servlet sends cookies to the browser by using the HttpServletResponse.addCookie(Cookie) method.

Because the cookie is sent as part of the HTTP response header, you must add the cookie before sending the body of the response. This means a call to res.addCookie(cookie) must be made before sending any HTML or other data to the client.

The following code creates a new cookie with a unique identifier (code not shown). In this code fragment, the cookie value is initially left blank and set later using Cookie.setValue() to store the URL of the page visited by the user (getRequestURI() returns a string containing the URL).

String userID = new UniqueID();
Cookie cookie = new Cookie (userID, null);

String cvalue = getRequestURI();
cookie.setValue(cvalue);
res.addCookie(cookie);

By default, a cookie lives only as long as the browser session, so you need to use the cookie.setMaxAge(interval) method to change the life expectancy of a cookie. A positive interval sets the number of seconds a cookie will live, which enables you to create cookies that will survive beyond the browser session. A negative interval causes the cookie to be destroyed when the browser exits. An interval of zero immediately deletes the cookie.

Retrieving Cookie Data

Creating a cookie was simple. Retrieving one is not quite as straightforward. Unfortunately, there is no way to retrieve a cookie by name. Instead, you must retrieve all the cookies and then find the one that interests you.

To find the value of a cookie, you use the Cookie.getValue() method.

The following code can be used to retrieve a cookie with the same name as a userID String variable:

Cookie cookie = null;
Cookie cookies[] = req.getCookies();
String cvalue = null;
if (cookies != null) {
  int numCookies=cookies.length;
  for(int i = 0; i < numCookies; i++) {
    cookie = cookies[i];
    if (cookie.getName().equals(userID)) {
      cvalue = cookie.getValue();
      break;
    }
  }
}

URL Rewriting

Not all browsers support cookies, and even those that do can be set up to reject cookies. To get around this problem, your servlet can be set up to use URL rewriting as an alternative way of tracking sessions.

With URL rewriting, the server adds extra information dynamically to the URL. Usually, this information is the session ID (a unique ID associated with a HttpSession object when it is created).

You can use the HttpServletResponse.encodeURL() method to encode the session ID within the response as an added parameter. For example

out.println("<FORM action='"+res.encodeURL("/examples/htmlpage")+"'>");

adds the session ID to the form's action URL as follows:

<FORM action='http://localhost:8000/examples/htmlpage;jsessionid=99484920067B3'>

When the client will not accept a cookie, the server to track sessions will use URL rewriting. To ensure that your servlets support servers that use URL rewriting to track sessions, you must pass all URLs used in your servlet through the encodeURL() method.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.16.79.65