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). Sessions are by far the simplest to use, but you should be aware that no one method provides a perfect mechanism, and your servlet may need to be written to support more than one technique.

Using Session Objects

Sessions identify page requests that originate from the same browser during a specified period of time.

Conveniently, sessions are shared by all the servlets in an application accessed by a client.

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 Method Information
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

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).

You can use HttpSession.isNew() to determine if a session has been created. The following shows the use of getSession() to return a 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 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 1,800 seconds (30 minutes). A servlet can control the period of time between client requests before the servlet container will invalidate this session with setMaxInactiveInterval(int seconds). Setting a negative time ensures the session will never timeout.

A call to the 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 are fields on a HTML page that are not seen by the user. To the server, there is no difference between a hidden field and a non-hidden field. 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 advantages over other session tracking methods:

  • They are supported by all the popular browsers.

  • They require no special server support.

  • They can be used with anonymous clients.

The major disadvantage is they only work for a sequence of dynamically generated forms, and the technique fails if there is an error before the data is permanently stored somewhere.

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.

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

  • Not available if the user changes his or her workstation or browser

Within a single organization, remember that many users can share machines, such as public access terminals, including part-time or shift workers.

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. You need to be aware that 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 its size.

The cookie information is sent as part of the HTTP response header. If the browser accepts cookies, it will store the cookie in the file system 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 after setting the response content type but 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 from the protocol name up to the query string).

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 simple. 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. This is yet another good reason for not putting sensitive information in your cookie.

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

The following code can be used to retrieve a cookie:

Cookie cookie = null;
Cookie cookies[] = req.getCookies();
if (cookies != null) {
    int numCookies=cookies.length;
    for(int i = 0; i < numCookies; i++) {
        cookie = cookies[i];
        if (cookie.getName().equals(userID)) {
            String 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("/Servlets/HTMLPage")+"'>");

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

<FORM action='http://localhost:8000/Servlets/HTMLPage;jsessionid=99B484920067B3'>

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
13.59.227.82