10.1 Session Status Overview
The "stateless" feature of the HTTP protocol brings a series of problems. Especially when shopping through online stores, it becomes a serious problem for the server to fail to remember previous transactions smoothly. It makes it difficult to implement applications like "shopping basket": when we add products to the basket, how can the server know what was originally in the basket? Even if the server saves context information, we still have problems with e-commerce applications. For example, when a user goes from the page where the product is selected (provided by a regular server) to the page where the credit card number and delivery address (provided by a secure server that supports SSL), how can the server remember what the user bought?
There are generally three solutions to this problem:
Cookies. HTTP cookies are used to store information about shopping sessions, where subsequent connections can view the current session and then extract full information about the session from some parts of the server. This is an excellent and most widely used method. However, even if the Servlet provides a high-level, easy-to-use cookie interface, there are still some cumbersome details to deal with:
Cookies that save session identifiers are separately found from other cookies.
Set an appropriate invalidation time for cookies (for example, sessions with interruption time of more than 24 hours should generally be reset).
Relevant session identifiers with corresponding information on the server side. (The actual saved information may be much more than the information saved to a cookie, and sensitive information such as credit card numbers should never be saved using cookies.)
Rewrite the URL. You can attach some data that identifies a session to the back of each URL, and the server can associate the session identity with the session data it saves. This is also a good way, and it also works when the browser does not support cookies or the user has disabled cookies. However, most of the problems faced by using cookies are also present, that is, server-side programs have to perform many simple but monotonous and verbose processing. In addition, you must also be careful to ensure that each URL is attached with necessary information (including indirect redirect URLs given by Location). If the user finishes the session and returns via bookmark, the session information will be lost.
Hide form field. The HTML form can contain the following input fields: <INPUT TYPE="HIDDEN" NAME="session" VALUE="...">. This means that when the form is submitted, the name and data of the hidden domain are also included in the GET or POST data, and we can use this mechanism to maintain the session information. However, this approach has a big drawback, which requires that all pages be generated dynamically, because the core of the whole problem is that each session must have a unique identifier.
Servlet provides us with a unique solution: the HttpSession API. The HttpSession API is an advanced session state tracking interface based on cookies or URL rewriting mechanism: if the browser supports cookies, cookies are used; if the browser does not support cookies or the cookie function is turned off, the URL rewriting method is automatically used. Servlet developers do not need to care about details, nor do they need to directly handle cookies or information attached to the URL. The API automatically provides Servlet developers with a place where they can easily store session information.
10.2 Session Status Tracking API
Using session information in a servlet is quite simple. The main operations include: viewing the session object associated with the current request, creating a new session object when necessary, viewing information related to a certain session, saving information in the session object, and releasing the session object when the session is completed or aborted.
10.2.1 View the currently requested session object
Viewing the currently requested session object is achieved by calling the getSession method of HttpServletRequest. If the getSession method returns null, you can create a new session object. But more often, we specify parameters to automatically create a session object when there is no ready-made session, that is, specifying the parameter of getSession to true. Therefore, the first step of accessing the current requesting session object is usually as follows:
HttpSession session = (true);
10.2.2 View session-related information
The HttpSession object lives on the server and is automatically associated with the sender of the request through background mechanisms such as cookies or URLs. The session object provides a built-in data structure in which any number of key-value pairs can be saved. In the Servlet API version 2.1 or earlier, the getValue("key") method is used to view previously saved data. getValue returns an Object, so you have to convert it to a more specific data type. If the specified key in the parameter does not exist, getValue returns null.
API version 2.2 recommends using getAttribute instead of getValue, not only because the names of getAttribute and setAttribute match more (the one that matches getValue is putValue instead of setValue), but also because setAttribute allows the use of an attached HttpSessionBindingListener to monitor values, but putValue cannot.
However, since there are currently only a few commercial Servlet engines that support 2.2, we still use getValue in the following example. This is a very typical example, assuming that ShoppingCart is a class that holds information about purchased items:
HttpSession session = (true);
ShoppingCart previousItems =
(ShoppingCart)("previousItems");
if (previousItems != null) {
doSomethingWith(previousItems);
} else {
previousItems = new ShoppingCart(...);
doSomethingElseWith(previousItems);
}
Most of the time we look for the value associated with a specific name, but we can also call getValueNames to get the names of all attributes. getValuesNames returns a String array. API version 2.2 recommends using getAttributeNames, not only because its name is better, but also because it returns an Enumeration, which is more consistent with other methods (such as getHeaders and getParameterNames of HttpServletRequest).
Although developers are often concerned about data that is saved to session objects, there are other information that is sometimes useful.
getID: This method returns the unique identity of the session. Sometimes this identifier is used as a key in a key-value pair, such as when only one value is saved in a session, or when the last session information is saved.
isNew: Returns true if the client (browser) has not been bound to the session, usually means that the session has just been created, rather than referring to the request from the client. For long-standing sessions, the return value is false.
getCreationTime: This method returns the time in milliseconds for establishing the session, starting from 1970.01.01 (GMT). To get the time value for printout, you can pass the value to the Date constructor, or the setTimeInMillis method of GregorianCalendar.
getLastAccessedTime: This method returns the time in milliseconds that the client last sent a request, starting from 1970.01.01 (GMT).
getMaxInactiveInterval: Returns the maximum time interval in seconds, if the interval between client requests does not exceed this value, the Servlet engine will keep the session active. A negative number means that the session will never time out.
10.2.3 Save data in session object
As mentioned in the previous section, the getValue method is used to read the information stored in the session (or, for the Servlet specification of version 2.2, use getAttribute). Save the data using the putValue (or setAttribute) method and specify the key and the corresponding value. Note that putValue will replace any existing value. Sometimes this is exactly what we need (referringPage in the example below), but sometimes we need to extract the original value and augment it (example below). The sample code is as follows:
HttpSession session = (true);
("referringPage", ("Referer"));
ShoppingCart previousItems =
(ShoppingCart)("previousItems");
if (previousItems == null) {
previousItems = new ShoppingCart(...);
}
String itemID = ("itemID");
((itemID));
("previousItems", previousItems);
10.3 Example: Display session information
The following example generates a web page and displays information about the current session in that page.
package hall;
import .*;
import .*;
import .*;
import .*;
import .*;
public class ShowSession extends HttpServlet {
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
HttpSession session = (true);
("text/html");
PrintWriter out = ();
String title = "Searching the Web";
String heading;
Integer accessCount = new Integer(0);;
if (()) {
heading = "Welcome, Newcomer";
} else {
heading = "Welcome Back";
Integer oldAccessCount =
// Use getAttribute instead of getValue in Servlet API 2.2
(Integer)("accessCount");
if (oldAccessCount != null) {
accessCount =
new Integer(() + 1);
}
}
// Use putAttribute in Servlet API 2.2
("accessCount", accessCount);
((title) +
"<BODY BGCOLOR=\"#FDF5E6\">\n" +
"<H1 ALIGN=\"CENTER\">" + heading + "</H1>\n" +
"<H2>Information on Your Session:</H2>\n" +
"<TABLE BORDER=1 ALIGN=CENTER>\n" +
"<TR BGCOLOR=\"#FFAD00\">\n" +
" <TH>Info Type<TH>Value\n" +
"<TR>\n" +
" <TD>ID\n" +
" <TD>" + () + "\n" +
"<TR>\n" +
" <TD>Creation Time\n" +
" <TD>" + new Date(()) + "\n" +
"<TR>\n" +
" <TD>Time of Last Access\n" +
" <TD>" + new Date(()) + "\n" +
"<TR>\n" +
" <TD>Number of Previous Accesses\n" +
" <TD>" + accessCount + "\n" +
"</TABLE>\n" +
"</BODY></HTML>");
}
public void doPost(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
The "stateless" feature of the HTTP protocol brings a series of problems. Especially when shopping through online stores, it becomes a serious problem for the server to fail to remember previous transactions smoothly. It makes it difficult to implement applications like "shopping basket": when we add products to the basket, how can the server know what was originally in the basket? Even if the server saves context information, we still have problems with e-commerce applications. For example, when a user goes from the page where the product is selected (provided by a regular server) to the page where the credit card number and delivery address (provided by a secure server that supports SSL), how can the server remember what the user bought?
There are generally three solutions to this problem:
Cookies. HTTP cookies are used to store information about shopping sessions, where subsequent connections can view the current session and then extract full information about the session from some parts of the server. This is an excellent and most widely used method. However, even if the Servlet provides a high-level, easy-to-use cookie interface, there are still some cumbersome details to deal with:
Cookies that save session identifiers are separately found from other cookies.
Set an appropriate invalidation time for cookies (for example, sessions with interruption time of more than 24 hours should generally be reset).
Relevant session identifiers with corresponding information on the server side. (The actual saved information may be much more than the information saved to a cookie, and sensitive information such as credit card numbers should never be saved using cookies.)
Rewrite the URL. You can attach some data that identifies a session to the back of each URL, and the server can associate the session identity with the session data it saves. This is also a good way, and it also works when the browser does not support cookies or the user has disabled cookies. However, most of the problems faced by using cookies are also present, that is, server-side programs have to perform many simple but monotonous and verbose processing. In addition, you must also be careful to ensure that each URL is attached with necessary information (including indirect redirect URLs given by Location). If the user finishes the session and returns via bookmark, the session information will be lost.
Hide form field. The HTML form can contain the following input fields: <INPUT TYPE="HIDDEN" NAME="session" VALUE="...">. This means that when the form is submitted, the name and data of the hidden domain are also included in the GET or POST data, and we can use this mechanism to maintain the session information. However, this approach has a big drawback, which requires that all pages be generated dynamically, because the core of the whole problem is that each session must have a unique identifier.
Servlet provides us with a unique solution: the HttpSession API. The HttpSession API is an advanced session state tracking interface based on cookies or URL rewriting mechanism: if the browser supports cookies, cookies are used; if the browser does not support cookies or the cookie function is turned off, the URL rewriting method is automatically used. Servlet developers do not need to care about details, nor do they need to directly handle cookies or information attached to the URL. The API automatically provides Servlet developers with a place where they can easily store session information.
10.2 Session Status Tracking API
Using session information in a servlet is quite simple. The main operations include: viewing the session object associated with the current request, creating a new session object when necessary, viewing information related to a certain session, saving information in the session object, and releasing the session object when the session is completed or aborted.
10.2.1 View the currently requested session object
Viewing the currently requested session object is achieved by calling the getSession method of HttpServletRequest. If the getSession method returns null, you can create a new session object. But more often, we specify parameters to automatically create a session object when there is no ready-made session, that is, specifying the parameter of getSession to true. Therefore, the first step of accessing the current requesting session object is usually as follows:
HttpSession session = (true);
10.2.2 View session-related information
The HttpSession object lives on the server and is automatically associated with the sender of the request through background mechanisms such as cookies or URLs. The session object provides a built-in data structure in which any number of key-value pairs can be saved. In the Servlet API version 2.1 or earlier, the getValue("key") method is used to view previously saved data. getValue returns an Object, so you have to convert it to a more specific data type. If the specified key in the parameter does not exist, getValue returns null.
API version 2.2 recommends using getAttribute instead of getValue, not only because the names of getAttribute and setAttribute match more (the one that matches getValue is putValue instead of setValue), but also because setAttribute allows the use of an attached HttpSessionBindingListener to monitor values, but putValue cannot.
However, since there are currently only a few commercial Servlet engines that support 2.2, we still use getValue in the following example. This is a very typical example, assuming that ShoppingCart is a class that holds information about purchased items:
HttpSession session = (true);
ShoppingCart previousItems =
(ShoppingCart)("previousItems");
if (previousItems != null) {
doSomethingWith(previousItems);
} else {
previousItems = new ShoppingCart(...);
doSomethingElseWith(previousItems);
}
Most of the time we look for the value associated with a specific name, but we can also call getValueNames to get the names of all attributes. getValuesNames returns a String array. API version 2.2 recommends using getAttributeNames, not only because its name is better, but also because it returns an Enumeration, which is more consistent with other methods (such as getHeaders and getParameterNames of HttpServletRequest).
Although developers are often concerned about data that is saved to session objects, there are other information that is sometimes useful.
getID: This method returns the unique identity of the session. Sometimes this identifier is used as a key in a key-value pair, such as when only one value is saved in a session, or when the last session information is saved.
isNew: Returns true if the client (browser) has not been bound to the session, usually means that the session has just been created, rather than referring to the request from the client. For long-standing sessions, the return value is false.
getCreationTime: This method returns the time in milliseconds for establishing the session, starting from 1970.01.01 (GMT). To get the time value for printout, you can pass the value to the Date constructor, or the setTimeInMillis method of GregorianCalendar.
getLastAccessedTime: This method returns the time in milliseconds that the client last sent a request, starting from 1970.01.01 (GMT).
getMaxInactiveInterval: Returns the maximum time interval in seconds, if the interval between client requests does not exceed this value, the Servlet engine will keep the session active. A negative number means that the session will never time out.
10.2.3 Save data in session object
As mentioned in the previous section, the getValue method is used to read the information stored in the session (or, for the Servlet specification of version 2.2, use getAttribute). Save the data using the putValue (or setAttribute) method and specify the key and the corresponding value. Note that putValue will replace any existing value. Sometimes this is exactly what we need (referringPage in the example below), but sometimes we need to extract the original value and augment it (example below). The sample code is as follows:
HttpSession session = (true);
("referringPage", ("Referer"));
ShoppingCart previousItems =
(ShoppingCart)("previousItems");
if (previousItems == null) {
previousItems = new ShoppingCart(...);
}
String itemID = ("itemID");
((itemID));
("previousItems", previousItems);
10.3 Example: Display session information
The following example generates a web page and displays information about the current session in that page.
package hall;
import .*;
import .*;
import .*;
import .*;
import .*;
public class ShowSession extends HttpServlet {
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
HttpSession session = (true);
("text/html");
PrintWriter out = ();
String title = "Searching the Web";
String heading;
Integer accessCount = new Integer(0);;
if (()) {
heading = "Welcome, Newcomer";
} else {
heading = "Welcome Back";
Integer oldAccessCount =
// Use getAttribute instead of getValue in Servlet API 2.2
(Integer)("accessCount");
if (oldAccessCount != null) {
accessCount =
new Integer(() + 1);
}
}
// Use putAttribute in Servlet API 2.2
("accessCount", accessCount);
((title) +
"<BODY BGCOLOR=\"#FDF5E6\">\n" +
"<H1 ALIGN=\"CENTER\">" + heading + "</H1>\n" +
"<H2>Information on Your Session:</H2>\n" +
"<TABLE BORDER=1 ALIGN=CENTER>\n" +
"<TR BGCOLOR=\"#FFAD00\">\n" +
" <TH>Info Type<TH>Value\n" +
"<TR>\n" +
" <TD>ID\n" +
" <TD>" + () + "\n" +
"<TR>\n" +
" <TD>Creation Time\n" +
" <TD>" + new Date(()) + "\n" +
"<TR>\n" +
" <TD>Time of Last Access\n" +
" <TD>" + new Date(()) + "\n" +
"<TR>\n" +
" <TD>Number of Previous Accesses\n" +
" <TD>" + accessCount + "\n" +
"</TABLE>\n" +
"</BODY></HTML>");
}
public void doPost(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}