- Introduction to Servlets
- Core HTTP Servlet API
- Sessions
- Session Handling: URL Rewriting
- Session Handling: Cookies
- Session Handling: HttpSession API
- Summary
- Q&A
- Workshop
- Quiz
- Exercises
Session Handling: HttpSession API
The Servlet API simplifies session handling to a great extent by wrapping all the session-handling functionality in the HttpSession API. State maintenance between the client browser and the servlet is done by the server's setting a cookie in the client browser. But unlike the plain cookie method of session handling, where all the session data was stored in the cookie as name-value strings, the onus of maintaining the session is undertaken by the WebLogic Server. The server maintains a mapping of session identifiers generated for different clients and the data stored for each session. Since this data is stored on the server side and only the identifier is passed back and forth between the client browser and the WebLogic Server as a cookie, this method is also an example of server-side session handling.
The HttpSession API provides the following methods:
Retrieving a reference to sessionAn instance of an HttpSession object can be retrieved using the getSession() method of the HttpServletRequest object.
Checking validity of a sessionTo check whether a session is new or not, the HttpSession object provides an isNew() method. This method returns a Boolean true or false value depending on whether the session is new or not.
Setting data in a sessionThe setAttribute() method of the HttpSession object is used by the servlet to store data in the session. The method accepts two parameters: a parameter name as a key and the Java object to be stored.
Retrieving data from a sessionThe getAttribute() method of the HttpSession object is used to retrieve the data from the session. This method accepts the name of the parameter whose value is to be retrieved as a parameter and returns a java.lang.Object. The return value is required to be typecast to the appropriate type in the servlet.
The primary advantage of using the HttpSession API is that this allows storing not just text strings but entire Java objects in the session. All the session-handling functionality of creating a session, checking the validity of a session, retrieving the data stored for a session, and terminating a session is wrapped in the HttpSession API and performed by the WebLogic Server.
Using the previous techniques for session handling, you could store only text data in the session. What if you needed to store entire domain objects of your application, such as a BookOrder or UserProfile, in your session? With the previous techniques, you would have to convert the data in the attributes into text strings and then use them. With the HttpSession API, you can store your domain objects as they are without the overhead of converting back and forth between Java objects and text strings.
There are no significant disadvantages of using the HttpSession API. The only limitation is that this technique uses cookies for storing the session identifier.
Sample Program
Now you will look at a sample program (Listing 3.4) that implements this session- handling technique. Figure 3.17 shows the sequence diagram for the program.
Figure 3.17 Sequence diagram for session handling using HttpSession.
Listing 3.4 BookShoppingServlet.java
/****************************************************************************** * Class Name:BookShoppingServlet * Extends:HttpServlet * Description:Shopping Cart Application Using HttpSession, * @author Mandar S. Chitnis, Lakshmi AM. @version 1.1 * Copyright (c) by Sams Publishing. All Rights Reserved. ******************************************************************************/ package com.sams.learnweblogic7.servlets; //import the utils package import com.sams.learnweblogic7.utils.*; //importing standard servlet packages import javax.servlet.*; import javax.servlet.http.*; //import io,util, and math packages import java.io.*; import java.util.*; import java.math.*; public class BookShoppingServlet extends HttpServlet { Book book1; Book book2; Book book3; PrintWriter out; private static final int DEFAULT_ZERO_VALUE = 0; private static final String EXAMPLE_TYPE = "Shopping Cart Using Http Session"; ... public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException{ res.setContentType("text/html"); out = res.getWriter(); writeHeaderZone(out, EXAMPLE_TYPE); doSessionUsingHttpSession(out, req, res); writeFooterZone(out); }//end of doPost public void doSessionUsingHttpSession(PrintWriter outputObject, HttpServletRequest req, HttpServletResponse res){ Hashtable shoppingCartHash = null; HttpSession session = req.getSession(true); if(session.isNew()){ //create an empty shopping cart hashtable, //with zero quantity for each book id shoppingCartHash = new Hashtable(); shoppingCartHash.put(book1.getBookId(), new Integer(DEFAULT_ZERO_VALUE)); shoppingCartHash.put(book2.getBookId(), new Integer(DEFAULT_ZERO_VALUE)); shoppingCartHash.put(book3.getBookId(), new Integer(DEFAULT_ZERO_VALUE)); } else { shoppingCartHash = (Hashtable)session.getAttribute("shoppingCartHash"); } String clickedButton = (req.getParameter("buttonName") == null)?"":req.getParameter("buttonName"); if(clickedButton.equals("view")) { outputObject.println("<FORM name=\"viewcart\" -action=\"/ShoppingApp/BookShoppingServlet\" method=\"get\">"); outputObject.println("<B><font face = \"Verdana\" color=\"blue\" -size=-2><p align = \"right\">Shopping Cart using Http Session</p></font></B>"); int book1Qty = Utility.getDefaultValue(((Integer)shoppingCartHash.get(book1. getBookId())).toString(),DEFAULT_ZERO_VALUE); int book2Qty = Utility.getDefaultValue(((Integer)shoppingCartHash.get(book2. getBookId())).toString(),DEFAULT_ZERO_VALUE); int book3Qty = Utility.getDefaultValue(((Integer)shoppingCartHash.get(book3. getBookId())).toString(),DEFAULT_ZERO_VALUE); writeViewCartZone(outputObject, book1Qty, book2Qty, book3Qty); outputObject.println("<p align =\"center\"><INPUT type=\"submit\" name=\"buttonName\" value=\"Empty Shopping Cart\"></p>"); outputObject.println("</FORM>"); } else if(clickedButton.equals("add") || clickedButton.equals("")) { updateShoppingCartHash(req, session, shoppingCartHash,outputObject); outputObject.println("<FORM name=\"addcart\" -action=\"/ShoppingApp/BookShoppingServlet\"
method=\"post\">"); outputObject.println("<B><font face = \"Verdana\" color=\"blue\" -size=-2><p align = \"right\">Shopping Cart using Http Session</p></font></B>"); writeBookListZone(outputObject); outputObject.println("<CENTER><TABLE width = 100%><TR>"); outputObject.println("<TD><INPUT type=\"submit\" name=\"buttonName\" value=\"add\"></TD>"); outputObject.println("<TD><INPUT type=\"submit\" name=\"buttonName\" value=\"view\"></TD>"); outputObject.println("</TR></TABLE></CENTER>"); outputObject.println("</FORM>"); } else if(clickedButton.equals("Empty Shopping Cart")){ weblogic.servlet.security.ServletAuthentication.invalidateAll(req); outputObject.println("<FORM name=\"addcart\" -action=\"/ShoppingApp/BookShoppingServlet\" method=\"post\">"); outputObject.println("<B><font face = \"Verdana\" color=\"blue\" -size=-2><p align = \"right\">Shopping Cart using Hidden Variables</p></font></B>"); writeBookListZone(outputObject); outputObject.println("<CENTER><TABLE width = 100%><TR>"); outputObject.println("<TD><INPUT type=\"submit\" name=\"buttonName\" value=\"add\"></TD>"); outputObject.println("<TD><INPUT type=\"submit\" name=\"buttonName\" value=\"view\"></TD>"); outputObject.println("</TR></TABLE></CENTER>"); outputObject.println("</FORM>"); } } public void updateShoppingCartHash(HttpServletRequest req,HttpSession session, Hashtable shoppingCartHash, PrintWriter outputObject){ int Book1Qty = Utility.getDefaultValue(((Integer)shoppingCartHash.get(book1. getBookId())).toString(),DEFAULT_ZERO_VALUE)+Utility.getDefaultValue (req.getParameter("book1_qty"),DEFAULT_ZERO_VALUE); int Book2Qty = Utility.getDefaultValue(((Integer)shoppingCartHash.get(book2. getBookId())).toString(),DEFAULT_ZERO_VALUE)+Utility.getDefaultValue (req.getParameter("book2_qty"),DEFAULT_ZERO_VALUE); int Book3Qty = Utility.getDefaultValue(((Integer)shoppingCartHash.get(book3. getBookId())).toString(),DEFAULT_ZERO_VALUE)+Utility.getDefaultValue (req.getParameter("book3_qty"),DEFAULT_ZERO_VALUE); shoppingCartHash.put(book1.getBookId(), new Integer(Book1Qty)); shoppingCartHash.put(book2.getBookId(), new Integer(Book2Qty)); shoppingCartHash.put(book3.getBookId(), new Integer(Book3Qty)); session.setAttribute("shoppingCartHash", shoppingCartHash); } ... }//end of BookShoppingServlet
In this final session-handling technique, you will add the doSessionUsingHttpSession() method to your BookShoppingServlet. Your shopping cart is also now changed to a proper data structure, the hash table. The contents of the shopping cart will be stored in this hash table.
Since you will be using the servlet API for session handling, the doSessionUsingHttpSession() method first retrieves the HttpSession object from the request object using the getSession() method:
HttpSession session = req.getSession(true);
The next step is to determine whether the session is a new session. This is done by the following call:
if(session.isNew()){ //create an empty shopping cart hashtable, //with zero quantity for each book id shoppingCartHash = new Hashtable(); shoppingCartHash.put(book1.getBookId(), new Integer(DEFAULT_ZERO_VALUE)); shoppingCartHash.put(book2.getBookId(), new Integer(DEFAULT_ZERO_VALUE)); shoppingCartHash.put(book3.getBookId(), new Integer(DEFAULT_ZERO_VALUE)); }
If the session is a new session, you have to set the shopping cart with empty values. If not, treat this as an existing session and retrieve your shopping cart hash table from the session:
else { shoppingCartHash = (Hashtable)session.getAttribute ("shoppingCartHash"); }
Next, you need to determine whether the user action is "Add To Cart" or "View Cart." For this you retrieve the value of the buttonName parameter from the request. This is similar to what was done in the previous session-handling techniques.
For the Add To Cart function, you need to retrieve the contents of the shopping cart as well as the new user selections. This is done by calling the updateShoppingCartHash() method.
Once you have retrieved your shopping cart contents for each book, retrieve the user selections for each book and update your shopping cart hash table with the updated values for each book:
int Book1Qty = Utility.getDefaultValue(((Integer)shoppingCartHash.get(book1. getBookId())).toString(),DEFAULT_ZERO_VALUE)+Utility.getDefaultValue (req.getParameter("book1_qty"),DEFAULT_ZERO_VALUE);
The preceding piece of code calculates the new book quantity for book1, which is the sum of the existing contents of the shopping cart in the shoppingCartHash hash table for book1 and the new user selection retrieved from the getParameter("book1_qty") call. The getDefaultValue() utility method performs the conversion from String data to a primitive int data type, as seen in the explanation of the Utility class earlier. Do similar calculations for the other books in your store.
These updated values will be set in your shopping cart hash table, and the shopping cart is saved in the user's session:
session.setAttribute("shoppingCartHash", shoppingCartHash);
Finally, send back the book-listing page to the browser.
For the View Cart function, you need to retrieve the contents of the shopping cart stored in the browser. This is done by the call
int book1Qty = Utility.getDefaultValue(((Integer)shoppingCartHash.get(book1. getBookId())).toString(),DEFAULT_ZERO_VALUE);
This is similar to the retrieval of shopping contents for the Add To Cart function. The only difference is that there will be no new user selections and hence no updates required to the cookie. You will perform similar actions for the rest of the books in your store.
Finally, you will generate the View Cart page using the writeViewCartZone() method with the retrieved shopping cart data as parameters.
Functionality to enable the user to empty the shopping cart is provided in this servlet. The emptying function is kicked off when the user clicks the Back To Cart button. Since this session-handling technique uses cookies, you need to destroy the cookies that you created for the user in this session and in the session that was created between the WebLogic Server and the browser application. This ensures that the entire session is wiped out. This is done by the call
weblogic.servlet.security.ServletAuthentication.invalidateAll(req);
The invalidateAll() call destroys the entire authentication session between the browser and the WebLogic Server. You will be looking at the security and authentication features of WebLogic Server on Day 19, "Using WebLogic Tools."
Compile the Program
Since you are not adding any new classes nor changing the deployment location of the application, the compiling of the servlet program is similar to compiling the hidden-variables session-handling method.
Deploy the Program
Since HttpSession support is a part of the Java Servlet API specification that WebLogic Server supports, there are no settings required in the web.xml or weblogic.xml file.
TIP
WebLogic Server allows you to define timeout values for a user session. Setting these values enables the WebLogic Server to free up resources tied to a user's session for servlets. There are two places where this session timeout value can be specified. The default session timeout value is specified in the weblogic.xml file. A range between 1 and 3600 seconds can be set for this parameter:
<session-descriptor> <session-param> <session-param> <param-name>TimeOutSecs</param-name> <param-value>3600</param-value> </session-param> </session-descriptor>
This setting can be overridden by putting the following setting in your application-specific deployment descriptor file web.xml:
<session-config> <session-timeout>minutes</session-timeout> <session-config>
Since this value is in minutes, the maximum value that can be set is Integer.MAX_VALUE/60. The default value for this is 2, which denotes that the TimeOutSecs value set in the weblogic.xml file should be used. If you need to disable the session timeout for your application, set this value to 1.
Execute the Program
The book-listing page is invoked from the browser by calling the following URL:
http://localhost:7001/ShoppingApp/BookShoppingServlet