Matakuliah Tahun : Web Programming : 2009 Session tracking & Cookies Pertemuan 11 Objectives Applied Provide for session tracking by using both cookies and URL encoding. Provide for parameter passing by using URL rewriting or hidden fields. Test your web applications with cookies enabled and with cookies disabled. Write a utility class that includes a static method for getting a specific cookie from a user’s browser. Slide 3 Objectives (cont.) Knowledge Describe the way HTTP works without session tracking. Describe the way cookies are used for session tracking. Describe the way URL encoding is used for session tracking. Distinguish between persistent cookies and per-session cookies. Distinguish between the use of URL rewriting and the use of hidden fields as ways to implement parameter passing. Slide 4 Why session tracking is difficult with HTTP Client Browser Browser Browser Web server Web server Web server Server First HTTP Request: The browser requests a page. First HTTP Response: The server returns the requested page and drops the connection. Following HTTP Requests: The browser requests a page. The web server has no way to associate the browser with its previous request. Slide 5 How Java keeps track of sessions Client Browser Browser Browser jsessionid=E587B704A1... jsessionid=E587B704A1... Servlet engine Servlet engine Server Servlet engine First HTTP Request: The browser requests a JSP or servlet. The servlet engine creates a session object and assigns an ID for the session. First HTTP Response: The server returns the requested page and the ID for the session. Following HTTP Requests: The browser requests a JSP or servlet. The servlet engine uses the session ID to associate the browser with its session object. Slide 6 An introduction to session tracking HTTP is a stateless protocol. Once a browser makes a request, it drops the connection to the server. So to maintain state, a web application must use session tracking. By default, the servlet API uses a cookie to store a session ID in each browser. Then, the browser passes the cookie to the server with each request. To provide session tracking when cookies are disabled in the browser, you can use URL encoding to store the session ID in the URL for each page of an application. To store the data for each session, the server creates a session object. Slide 7 The Index page Slide 8 The Cart page Slide 9 A method of the request object Method getSession() Description Returns the HttpSession object associated with this request. If the request is not associated with a session, this method creates a new HttpSession object and returns it. Slide 10 Three methods of the session object Method setAttribute( String name, Object o) getAttribute(String name) removeAttribute(String name) Description Stores any object in the session as an attribute and specifies a name for the attribute. Returns the value of the specified attribute as an Object type. If no attribute exists for the specified name, this method returns a null value. Removes the specified attribute from this session. Slide 11 Examples of code that… Gets a session object HttpSession session = request.getSession(); Sets a String object as an attribute session.setAttribute("productCode", productCode); Sets a user-defined object as an attribute Cart cart = new Cart(productCode); session.setAttribute("cart", cart); Gets a String object String productCode = (String) session.getAttribute("productCode"); Gets a user-defined object Cart cart = (Cart) session.getAttribute("cart"); if (cart == null) cart = new Cart(); Removes an object session.removeAttribute("productCode"); Slide 12 How to set and get session attributes A session object is created when a browser makes the first request to a site. It is destroyed when the session ends. A session ends when a specified amount of time elapses without another request or when the user exits the browser. The session object is a built-in JSP object. As a result, you don’t need to create the session object when working with JSPs. Slide 13 More methods of the session object Method getAttributeNames() getId() isNew() Description Returns a java.util.Enumeration object that contains the names of all attributes in the HttpSession object. Returns a string for the unique Java session identifier that the servlet engine generates for each session. Returns a true value if the client does not yet know about the session or if the client chooses not to join the session. Slide 14 More methods of the session object (cont.) Method setMaxInactiveInterval( int seconds) invalidate() Description By default, the maximum inactive interval for the session is set to 1800 seconds (30 minutes). To increase or decrease this interval, supply a positive integer value. To create a session that won’t end until the user closes the browser, supply a negative integer such as –1. Invalidates the session and unbinds any objects that are bound to it. Slide 15 Examples A method that gets all the names of the attributes for a session Enumeration names = session.getAttributeNames(); while (names.hasMoreElements()) { System.out.println((String) names.nextElement()); } A method that gets the ID for a session String jSessionId = session.getId(); A method that sets the inactive interval for a session session.setMaxInactiveInterval(60*60*24); // one day session.setMaxInactiveInterval(-1); // until the browser is closed A method that invalidates the session and unbinds any objects session.invalidate(); Slide 16 An Internet Explorer dialog box with disabled cookies Slide 17 How to disable cookies for Internet Explorer 6.0 1. Pull down the Tools menu and select the Internet Options command. 2. Select the Privacy tab. 3. Use the slider control to set the security level to block cookies. How to disable local cookies for Internet Explorer 6.0 1. Pull down the Tools menu and select the Internet Options command. 2. Select the Security tab, the Local Intranet icon, and click on the Sites button. 3. Deselect the “Include all local (intranet) sites” check box. Slide 18 How to disable cookies for Mozilla Firefox 2.0 1. Pull down the Tools menu and select the Options command. 2. Click on the Security tab. 3. Deselect the “Accept cookies from sites” check box. Slide 19 A method of the response object Method encodeURL(String url) Description Returns a string for the specified URL. If necessary, this method encodes the session ID in the URL. If not, it returns the URL unchanged. How to encode a URL in a Form tag <form action="<%=response.encodeURL("cart")%>" method="post"> How to encode a URL in an A tag <a href="<%=response.encodeURL("cart?productCode=8601")%>"> Add To Cart </a> Slide 20 A URL after it has been encoded Slide 21 How to use URL encoding to track sessions without cookies If the user has disabled per-session cookies, you can use URL encoding to keep track of the ID for the session. To do that, you must convert any relevant HTML pages to JSPs, and you must encode all relevant URLs. When you encode a URL, the session ID is passed to the browser in the URL. Slide 22 An example that synchronizes access to the session object Cart cart; synchronized(session) { cart = (Cart) session.getAttribute("cart"); } Another example that synchronizes access to the session object synchronized(session) { session.setAttribute("cart", cart); } Slide 23 A web browser with three windows accessing the same session object Slide 24 How to provide thread-safe access to the session object Each servlet creates one session object that exists for multiple requests that come from a single client. If the client has one browser window open, access to the session object is thread-safe. If the client has multiple browser windows open, it’s possible (though highly unlikely) that two threads from the same client will access the session object at the same time. As a result, the session object isn’t completely thread-safe. Slide 25 Examples of cookies jsessionid=D1F15245171203E8670487F020544490 user_id=87 email=jsmith@hotmail.com userName=jsmith passwordCookie=opensesame Slide 26 Slide 26 How cookies work A cookie is a name/value pair that is stored in a browser. On the server, a web application creates a cookie and sends it to the browser. On the client, the browser saves the cookie and sends it back to the server every time it accesses a page from that server. Cookies can be set to persist within the user’s browser for up to 3 years. Some users disable cookies in their browsers. As a result, you can’t always count on all users having their cookies enabled. Browsers generally accept only 20 cookies from each site and 300 cookies total. In addition, they can limit each cookie to 4 kilobytes. A cookie can be associated with one or more subdomain names. Slide 27 Typical uses for cookies To allow users to skip login and registration forms that gather data like user name, password, address, or credit card data. To customize pages that display information like weather reports, sports scores, and stock quotations. To focus advertising like banner ads that target the user’s interests. Slide 28 Constructor of the Cookie class Constructor Cookie(String name, String value) Description Creates a cookie with the specified name and value. Slide 29 The methods of the Cookie class Method setMaxAge( int maxAgeInSeconds) setPath(String path) getName() getValue() Description To create a persistent cookie, set the cookie’s maximum age to a positive number. To create a persession cookie, set the cookie’s maximum age to –1. Then, the cookie will be deleted when the user exits the browser. To allow the entire application to access the cookie, set the cookie’s path to “/”. Returns a string for the name of the cookie. Returns a string that contains the value of the cookie. Slide 30 A method of the response object Method addCookie(Cookie c) Description Adds the specified cookie to the response. A method of the request object Method getCookies() Description Returns an array of Cookie objects that the client sent with this request. If no cookies were sent, this method returns a null value. Slide 31 Code that creates and sets a cookie Cookie userIdCookie = new Cookie("userIdCookie", userId); userIdCookie.setMaxAge(60*60*24*365*2); //set the age to 2 years userIdCookie.setPath("/"); // allow access by the entire application response.addCookie(userIdCookie); Code that gets the cookie Cookie[] cookies = request.getCookies(); String cookieName = "userIdCookie"; String cookieValue = ""; for (int i=0; i<cookies.length; i++) { Cookie cookie = cookies[i]; if (cookieName.equals(cookie.getName())) cookieValue = cookie.getValue(); } Slide 32 A JSP that shows all cookies for the current server Slide 33 JSP code that displays all cookies <% Cookie[] cookies = request.getCookies(); for (Cookie c : cookies) { %> <tr> <td align="right"><%= c.getName() %></td> <td><%= c.getValue() %></td> </tr> <% } %> Slide 34 Servlet code that deletes all persistent cookies Cookie[] cookies = request.getCookies(); for (int i=0; i<cookies.length; i++) { Cookie cookie = cookies[i]; cookie.setMaxAge(0); //delete the cookie cookie.setPath("/"); //allow the entire application to access it response.addCookie(cookie); } Slide 35 Four methods of the Cookie class setPath(String path) setDomain(String domainPattern) setSecure(boolean flag) setVersion(int version) Note All of these set methods have corresponding get methods. Slide 36 A utility class that gets the value of a cookie package util; import javax.servlet.http.*; public class CookieUtil { public static String getCookieValue( Cookie[] cookies, String cookieName) { String cookieValue = ""; Cookie cookie; if (cookies != null) { for (int i=0; i<cookies.length; i++) { cookie = cookies[i]; if (cookieName.equals(cookie.getName())) { cookieValue = cookie.getValue(); } } Slide 37 A utility class that gets the value of a cookie (cont.) } return cookieValue; } } Slide 38 Code that uses the CookieUtil class to get the value of a cookie Cookie[] cookies = request.getCookies(); String emailAddress = CookieUtil.getCookieValue(cookies, "emailCookie"); Slide 39 The syntax for URL rewriting url?paramName1=paramValue1&paramName2=paramValue2&... An A tag that adds a product code to a URL <a href="cart?productCode=8601">Add to cart</a> The link displayed in a browser The URL that displays when you click on the link Slide 40 More examples A Form tag that calls a JSP <form action="cart.jsp?productCode=jr01" method="post"> An A tag that uses a JSP expression for the product code <a href="cart?productCode=<%= productCode %>" > Add to cart</a> Slide 41 How to use URL rewriting You can use URL rewriting to pass parameters to a servlet or JSP. To do that, you add the parameters to the end of the URL. Two limitations of URL rewriting Most browsers limit the number of characters that can be passed by a URL to 2,000 characters. It’s difficult to include spaces and special characters such as the ? and & characters in parameter values. Slide 42 A Form tag that uses a hidden text field <form action="cart" method="post"> <input type="submit" value="Add To Cart"> <input type="hidden" name="productCode" value="8601"> </form> The form displayed in a browser The URL that displays when the button is clicked Slide 43 A Form tag that uses JSP expressions to set hidden field values <form action="cart" method="post"> <input type="hidden" name="productCode" value="<%=product.getCode()%>"> <input type=text size=2 name="quantity" value="<%=lineItem.getQuantity()%>"> <input type="submit" name="updateButton" value="Update"> </form> Slide 44 How to use hidden fields to pass parameters You can use hidden fields to pass parameters to a servlet or JSP. To do that, you code hidden fields within a Form tag. One limitation of hidden fields Because hidden fields are displayed in the source code for the page that’s returned to the browser, anyone can view the parameters by selecting the Source command from the View menu of the browser. As a result, hidden fields aren’t appropriate for secure data like passwords. Slide 45 The Index page Slide 46 The Register page Slide 47 The Downloads page Slide 48 The names of the jsp files index.jsp register.jsp 8601_download.jsp pf01_download.jsp pf02_download.jsp jr01_download.jsp The names of the servlet classes download.CheckUserServlet download.RegisterUserServlet The file structure for the mp3 files musicStore/sound/8601/*.mp3 musicStore/sound/pf01/*.mp3 musicStore/sound/pf02/*.mp3 musicStore/sound/jr01/*.mp3 Slide 49 The web.xml file <?xml version="1.0" encoding="UTF-8"?> <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> <servlet> <servlet-name>CheckUserServlet</servlet-name> <servlet-class>download.CheckUserServlet </servlet-class> </servlet> <servlet> <servlet-name>RegisterUserServlet</servlet-name> <servlet-class>download.RegisterUserServlet </servlet-class> </servlet> Slide 50 The web.xml file (cont.) <servlet-mapping> <servlet-name>CheckUserServlet</servlet-name> <url-pattern>/checkUser</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>RegisterUserServlet</servlet-name> <url-pattern>/registerUser</url-pattern> </servlet-mapping> <session-config> <session-timeout>30</session-timeout> </session-config> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app> Slide 51 The code for the index.jsp file <!doctype html public "-//W3C//DTD HTML 4.0 Transitional//EN"> <html> <head> <title>Murach's Java Servlets and JSP</title> </head> <body> <h1>List of albums</h1> <p> <a href= "<%=response.encodeURL("checkUser?productCode=8601")%>"> 86 (the band) - True Life Songs and Pictures </a><br> Slide 52 The code for the index.jsp file (cont.) <a href= "<%=response.encodeURL("checkUser?productCode=pf01")%>"> Paddlefoot - The first CD </a><br> <a href= "<%= response.encodeURL("checkUser?productCode=pf02")%>"> Paddlefoot - The second CD </a><br> <a href= "<%= response.encodeURL("checkUser?productCode=jr01")%>"> Joe Rut - Genuine Wood Grained Finish </a> </p> </body> </html> Slide 53 The code for the CheckUserServlet class package download; import java.io.*; import javax.servlet.*; import javax.servlet.http.*; import business.User; import data.UserIO; import util.CookieUtil; public class CheckUserServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException Slide 54 The code for the CheckUserServlet class (cont.) { String productCode = request.getParameter("productCode"); HttpSession session = request.getSession(); session.setAttribute("productCode", productCode); User user = (User) session.getAttribute("user"); String url = ""; // if the User object doesn't exist, // check for the email cookie if (user == null) { Cookie[] cookies = request.getCookies(); String emailAddress = CookieUtil.getCookieValue( cookies, "emailCookie"); Slide 55 The code for the CheckUserServlet class (cont.) // if the email cookie doesn't exist, // go to the registration page if (emailAddress == null || emailAddress.equals("")) { url = "/register.jsp"; } else { ServletContext sc = getServletContext(); String path = sc.getRealPath("WEB-INF/EmailList.txt"); user = UserIO.getUser(emailAddress, path); session.setAttribute("user", user); url = "/" + productCode + "_download.jsp"; } } Slide 56 The code for the CheckUserServlet class (cont.) // if the User object exists, // skip the registration page else { url = "/" + productCode + "_download.jsp"; } // forward to the view RequestDispatcher dispatcher = getServletContext().getRequestDispatcher(url); dispatcher.forward(request, response); } } Slide 57 The code for the register.jsp file <!doctype html public "-//W3C//DTD HTML 4.0 Transitional//EN"> <html> <head> <title>Murach's Java Servlets and JSP</title> </head> <body> <h1>Download registration</h1> <p>To register for our downloads, enter your name and email <br> address below. Then, click on the Submit button.</p> <form action="<%= response.encodeURL("registerUser")%>" method="post"> Slide 58 The code for the register.jsp file (cont.) <table cellspacing="5" border="0"> <tr> <td align="right">First name:</td> <td><input type="text" name="firstName"></td> </tr> <tr> <td align="right">Last name:</td> <td><input type="text" name="lastName"></td> </tr> <tr> <td align="right">Email address:</td> <td><input type="text" name="emailAddress"></td> </tr> <tr> <td></td> <td><input type="submit" value="Submit"></td> </tr> </table> </form> </body> </html> Slide 59 The code for the RegisterUserServlet class package download; import java.io.*; import javax.servlet.*; import javax.servlet.http.*; import business.User; import data.UserIO; public class RegisterUserServlet extends HttpServlet { public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { String firstName = request.getParameter("firstName"); String lastName = request.getParameter("lastName"); String emailAddress = request.getParameter("emailAddress"); Slide 60 The code for the RegisterUserServlet class (cont.) User user = new User(); user.setFirstName(firstName); user.setLastName(lastName); user.setEmailAddress(emailAddress); ServletContext sc = getServletContext(); String path = sc.getRealPath("WEB-INF/EmailList.txt"); UserIO.add(user, path); HttpSession session = request.getSession(); session.setAttribute("user", user); String productCode = (String) session.getAttribute("productCode"); Slide 61 The code for the RegisterUserServlet class (cont.) Cookie emailCookie = new Cookie( "emailCookie", emailAddress); //set its age to 2 years emailCookie.setMaxAge(60*60*24*365*2); //allow the entire application to access it emailCookie.setPath("/"); response.addCookie(emailCookie); String url = "/" + productCode + "_download.jsp"; RequestDispatcher dispatcher = getServletContext().getRequestDispatcher(url); dispatcher.forward(request, response); } } Slide 62 The code for the 8601_download.jsp file <html> <head> <title>Murach's Java Servlets and JSP</title> </head> <body> <% String productCode = (String) session.getAttribute("productCode"); %> <h1>Downloads</h1> <table cellpadding="5" border="1"> <tr><td colspan="2"><b>86 (the band) - True Life Songs and Pictures</b></td> </tr> <tr><td width="200"><b>Song title</b></td> <td width="150"><b>Audio Format</b></td> </tr> Slide 63 The code for the 8601_download.jsp file (cont.) <tr><td>You Are a Star</td> <td><a href= "/musicStore/sound/<%=productCode%>/star.mp3">MP3</a> </td> </tr> <tr><td>Don't Make No Difference</td> <td><a href= "/musicStore/sound/<%=productCode%>/no_difference.mp3"> MP3</a> </td> </tr> </table> <p><a href="<%= response.encodeURL("index.jsp")%>"> View list of albums</a>.</p> <p><a href="<%= response.encodeURL("view_cookies.jsp")%>"> View all cookies</a>.</p> </body> </html> Slide 64 The Download application This is one of the four JSPs for downloading songs from CDs. The others are similar. When a browser receives the URL for a sound file, it downloads and plays it. This JSP gets the product code from the session object and uses it in the URLs for the sound files. This isn’t necessary, though, because the URLs could be hard-coded. Another way to handle the downloads is to write one JSP that works for all of the CDs. To implement that, you can store the data for the downloadable songs in one file for each CD. Then, the download JSP can get the product code from the session object, read the related file, and load its data into the table. Slide 65