1 / 66

Servlets Chapter 7

Learn how to track user sessions in servlets using techniques like user authentication and hidden form fields. This allows for personalized online experiences, like maintaining a shopping cart or anonymous session tracking.

anthonyy
Download Presentation

Servlets Chapter 7

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Servlets Chapter 7 Session Tracking

  2. http is stateless But web applications are not. We need to know information about order items, eg., in order to continue processing this client’s session. Consider the shopping cart: you order something, browse elsewhere, then return to pay. Or it is an online chat situation where you are a featured guest: Someone asks you a question and if you ask a question in return, you don’t know who/when the answer is returned. (Ajax and other technologies have mitigated this issue somewhat.) • • • •

  3. Sessions may be tracked with 1. User authentication 2. Hidden form fields 3. url rewriting 4. Persistent cookies

  4. getRemoteUser() • We can get the user’s name and even pass it between servlet’s. • We can use it to implement user authentication (discussed in chapter 8)

  5. Client introductions The cliet needs to introduce himself each time he interacts with the server. A unique identifier is needed. Servlets can do traditional CGI session tracking. And there is built in session tracking support as well. User authentication (log in) allows servlet to call getRemoteUser() method to see who this is. The browser sends login (name/pw) info each time it requests a page. This way, even different servlets could handle the shopping cart: For example: addItemsToCart(name,items(i)) And later: String items[]=getItemsFromCart(name); Chapter 8 (Security) explains how to protect pages with user authentication and this, along with getRemoteUser() is one solution to the problem. • • • • • •

  6. User authentication • If the user has submitted login information then the name/pw is passed each time the viewer views a new page. • We can add items to the user’s cart with code like addItems(name,items); • And another servlet can retrieve them with code like String []items=getItems(name);

  7. Hidden html form fields: Another way to track session • Hidden form fields enable us to implement anonymous session tracking. • Hidden fields are not displayed to the client on the browser but are returned to the server. • Hidden form fields provide constant form data but to the servlet retrieving the parameters, there is no difference.

  8. A form with hidden fields <FORM Method=GET Action="http://localhost:8080/servlet/ShoppingCart"> item1 <input type=text name="item"><p> item2<input type=text name="item"><p> item3<input type=text name="item"><p> item4<input type=text name="item"><p> <input type=hidden name="secret" value ="1234"><p> other user info <input type=text name="userinfo"><p> <input type =submit VALUE=" Place Order "> </form>

  9. Form in IE

  10. Hunter’s shopping cart viewer hidden • Uses hidden form fields to allow anonymous shopping until checkout time. • User can add more or check out at any time. • The currently selected cart items are (re-) written to the form as hidden fields each time it is presented to the client.

  11. servlet public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { res.setContentType("text/html"); PrintWriter out = res.getWriter(); out.println("<HEAD><TITLE>Current Shopping Cart Items</TITLE></HEAD>"); out.println("<BODY>"); // Cart items are passed in as the item parameter. String[] items = req.getParameterValues("item"); // Print the current cart items. out.println("You currently have the following items in your cart:<BR>"); if (items == null) { out.println("<B>None</B>"); } else { out.println("<UL>"); for (int i = 0; i < items.length; i++) { if(items[i].length()>0)out.println("<LI>" + items[i]); } out.println("</UL>");

  12. Servlet 2ndslide // Ask if the user wants to add more items or check out. // Include the current items as hidden fields so they'll be passed on. out.println("<FORM ACTION=\"/servlet/ShoppingCart\" METHOD=POST>"); if (items != null) { for (int i = 0; i < items.length; i++) { out.println("<INPUT TYPE=HIDDEN NAME=\"item\" VALUE=\"" + items[i] + "\">"); } } out.println("Would you like to<BR>"); out.println("<INPUT TYPE=SUBMIT VALUE=\" Add More Items \">"); out.println("<INPUT TYPE=SUBMIT VALUE=\" Check Out \">"); out.println("</FORM>"); out.println("</BODY></HTML>"); }

  13. The servlets to go to for submits don’t exist, as yet

  14. About this example • The items are hidden in the form returned to the user. • The links to a “checkout” servlet are not valid. • As more and more stuff is in the cart, it is tedious to write it all as hidden form data. A unique session ID is a better way to associate a client with the data. Session ids must be protected and generated carefully.

  15. Hidden fields • Hidden fields are simple • Supported by all browsers. • A session id can be a hidden form field. • Session id can only be maintained through dynamic form generation, not static pages.

  16. Saving session information by URL rewriting • In this method, local URLs (passing between pages on the same server) have some information glued to the end, retrievable as path info. • The extra info is usually limited to a session id or some parameters. • Servlets will have to be customized to look for and process this.

  17. URL rewriting All servers can handle extra path information but it may interfere with servlets that need true path information. Added parameters works on all servers, but parameter collision may occur. Several ways to add the information to the path. Passing session id 123 might look like #2-#4 below: http://someurl:someport/ShoppingCart http://someurl:someport/ShoppingCart/123 http://someurl:someport/ShoppingCart/sessionid=123 http://someurl:someport/ShoppingCartjsessionid=123 • • • • 1. 2. 3. 4.

  18. Saving session information by URL rewriting

  19. URL rewriting (select add more)

  20. URL rewriting (select help)

  21. Remarks • I didn’t really create an interface between the two servlets (ShoppingCart and ShoppingCartRewrite) to pass the items parameters or the mechanism to look up the items given the sessionid (like a Hashtable visible to both servlets) • I stubbed in a minimal Help servlet… Note that the Help servlet could use session info to provide help to a specific situation. • Mappings will need to be /theServelt/* so that session Id can be passed as pathInfo for ShoppingCartRewrite and Help

  22. ShoppingCartRewrite public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { res.setContentType("text/html"); PrintWriter out = res.getWriter(); out.println("<HEAD><TITLE>Current Shopping Cart Items</TITLE></HEAD>"); out.println("<BODY>"); // Get the current session ID, or generate one if necessary String sessionid = req.getPathInfo(); if (sessionid == null) { sessionid = generateSessionId(); } // Cart items are associated with the session ID String[] items = getItemsFromCart(sessionid); // Print the current cart items. out.println("You currently have the following items in your cart:<BR>"); if (items == null) { out.println("<B>None</B>"); } else { out.println("<UL>"); for (int i = 0; i < items.length; i++) { out.println("<LI>" + items[i]); } out.println("</UL>"); }

  23. ShoppingCartRewrite // Ask if the user wants to add more items or check out. // Include the session ID in the action URL. out.println("<FORM ACTION=\"http://csci345.oneonta.edu:8080/myexamples/ShoppingCart/" + sessionid + "\" METHOD=POST>"); out.println("Would you like to<BR>"); out.println("<INPUT TYPE=SUBMIT VALUE=\" Add More Items \">"); out.println("<INPUT TYPE=SUBMIT VALUE=\" Check Out \">"); out.println("</FORM>"); // Offer a help page. Include the session ID in the URL. out.println("For help, click <A HREF=\"http://csci345.oneonta.edu:8080/myexamples/Help/" + sessionid + "?topic=ShoppingCartRewrite\">here</A>"); out.println("</BODY></HTML>"); } private static String generateSessionId() { String uid = new java.rmi.server.UID().toString(); // guaranteed unique return java.net.URLEncoder.encode(uid); // encode any special chars } private static String[] getItemsFromCart(String sessionid) {//stubbed this in too String[]cart={"mo","larry","curly","shemp"}; return cart; } }

  24. Persistent Cookies • A cookie is information sent by a server to a browser which can later be read back from the browser. • A browser returns the cookie each time it returns to a given server subject to certain rules. • The cookie can uniquely identify a client and so can be used for session tracking. • Cookies are not part of the http standard but may be included in the next rewrite. They are part of the de facto toolkit.

  25. Persistent Cookies • The servlet cookie class is provided to manipulate cookies. • The constructor: public Cookie(String name,String value) builds a cookie. • Legal name/values for cookies appear in the Netscape cookie specification RFC 2109 • Cookie c=new Cookie(“id”,123456);//set cookie • Passing a cookie object to the addCookie method (of the response) sends a cookie to the client.

  26. Persistent Cookies • A servlet retrieves an array of cookies with request.getCookies() method. • Name/value pairs can be accessed from the entries in this array • but there is no method to get a value of a cookie given its name. • Other attributes like version, domain, max age and path can be set.

  27. Cookie methods If you wish to set an attribute on a cookie from the client you will have to add the cookie back to the response to effect the change. Most attributes (except name, value and version) on cookies will need to be reset each time. There are two versions, 0 and 1. setDomain specifies servers that should see the cookie. Default is to return a cookie only to the host that set them. The domain pattern begins with a dot and contains at least two dots. The pattern is matched only to domains that match one entry beyond the initial dot. So foo.com matches www.foo.com and upload.foo.com but not www.upload.foo.com setMaxAge specifies how long to keep the cookie (in seconds) before expiration. A negative value is the default, so cookies expire when the browser exits. A zero value is also deleted immediately. setPath sets URIs to which cookies can be sent. The default is the page that set the cookie and all pages in the same directory or under that directory. Path of / would mean any page on the server would get the cookie. setSecure (t/f) indicates if the cookie should only be sent over a secure channel. setComment sets a comment field. setValue sets a new cookie value • • • • • • • • •

  28. Cookie methods • setMaxAge() specifies how long to keep the cookie (in seconds) before expiration. A negative value is the default, so cookies expire when the browser exits. A zero value is also deleted immediately. • setPath() sets URIs to which cookies can be sent. The default is the page that set the cookie and all pages in the same directory or under that directory. Path of / would mean any page on the server would get the cookie. • setSecure (t/f) indicates if the cookie should only be sent over a secure channel. • setComment() sets a comment field. • setValue() sets a new cookie value

  29. Shopping revisited via persistent cookies

  30. Shopping with persistent cookies: after reload

  31. ShoppingCartWithCookie public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { res.setContentType("text/html"); PrintWriter out = res.getWriter(); boolean idfromcookie=false; int num=0; // Get the current session ID by searching the received cookies. String sessionid = null; String comment=null; Cookie[] cookies = req.getCookies(); if (cookies != null) { num=cookies.length; for (int i = 0; i < cookies.length; i++) { if (cookies[i].getName().equals("sessionid")) { sessionid = cookies[i].getValue(); idfromcookie=true; cookies[i].setMaxAge(30);//30 second cookie res.addCookie(cookies[i]); break; } } } // If the session ID wasn't sent, generate one. // Then be sure to send it to the client with the response. if (!idfromcookie) { sessionid = generateSessionId(); Cookie c = new Cookie("sessionid", sessionid); c.setMaxAge(30); res.addCookie(c); }//rest is the same a ShoppingCartSessionIdRewrite

  32. SessionTracking API • Servlet API has several classes and methods to handle short term session tracking. • Some servers support session tracking via cookies, URL rewriting, or a database or file that holds session info after shutdown. (These classes must be serializable.) • Text chapter 12 discusses distributed session tracking.

  33. SessionTracking API • Every site user is associated with a javax.servlet.http.HttpSession object that a servlet can use to store arbitrary information. • This object can hold an array of items from a shopping cart or a database connection. • The request.getSession(boolean create) retrieves the HttpSession object. It will create one if the parameter is set to true, if none exits. It will return null if there is none and create is set to false. (There is a no-argument version that has a flag set to true to create the session).

  34. SessionTracking API • getSession() must be called at least once before commiting the response. • HttpSession.setAttribute(String name, Object value) allows you to add data to the session. A getAttribute method allows retrieval of objects associated with the session. • HttpSession.getAttribut(String name) retrieves the attribute for a particular name.

  35. SessionTracking API • getAttributeNames() returns an enumeration of all objects bound to this session as Strings, or an empty enumeration. • Void method removeAttribute(name) allows you to remove an attribute with given name from association with the session. Servlet API before 2.2 used “value” instead of “attribute” and those methods are still supported but are deprecated.

  36. SessionInfo servlet (counts hits)

  37. Compiling the SessionTracker 'enum' is a keyword in jdk1.5+, and may not be used as an identifier • C:\Program Files\Java\jdk1.5.0_07\bin\SessionTracker.java:35: as of release 1.5, 'enum' is a keyword, and may not be used as an identifier (try -source 1.4 or lower to use 'enum' as an identifier) Enumeration enum = session.getAttributeNames(); ^ • • • •

  38. the SessionTracker servlet public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { res.setContentType("text/html"); PrintWriter out = res.getWriter(); // Get the current session object, create one if necessary HttpSession session = req.getSession(); // Increment the hit count for this page. The value is saved // in this client's session under the name "tracker.count". Integer count = (Integer)session.getAttribute("tracker.count"); if (count == null) count = new Integer(1); else count = new Integer(count.intValue() + 1); session.setAttribute("tracker.count", count); out.println("<HTML><HEAD><TITLE>SessionTracker</TITLE></HEAD>"); out.println("<BODY><H1>Session Tracking Demo</H1>"); // Display the hit count for this page out.println("You've visited this page " + count + ((count.intValue() == 1) ? " time." : " times.")); out.println("<P>"); out.println("<H2>Here is your session data:</H2>"); Enumeration list = session.getAttributeNames(); while (list.hasMoreElements()) { String name = (String) list.nextElement(); out.println(name + ": " + session.getAttribute(name) + "<BR>"); } out.println("</BODY></HTML>"); }

  39. More • I redid this servlet to keep adding stuff to the session, willy-nilly, but somewhat like a shopping cart might do

  40. A sample form

  41. After several items and several credit cards and addresses

  42. Here is internal info about the different session values

  43. The form uses post public void doGet(HttpServletRequest request, HttpServletResponse res) throws ServletException, IOException { res.setContentType("text/html"); PrintWriter out = res.getWriter(); // Get the current session object, create one if necessary HttpSession session = request.getSession(true); Enumeration paramNames = request.getParameterNames(); while(paramNames.hasMoreElements()) { String paramName = (String)paramNames.nextElement(); out.print("<TR><TD>" + paramName + "\n<TD>"); String[] paramValues = request.getParameterValues(paramName); if (paramValues.length == 1) { String paramValue = paramValues[0];//assumed there was just one of each name out.println(paramValue); String x=(String)session.getAttribute(paramName);//get any attribute with this name session.setAttribute(paramName,x+", "+paramValue);//glue more stuff to this attribute…array would be better }//if }//for out.println("<HTML><HEAD><TITLE>session info</TITLE></HEAD>"); out.println("<BODY><H1>Session Tracking Demo</H1>"); out.println("<P>"); out.println("<H2>Here is your session data:</H2>"); Enumeration list = session.getAttributeNames();//dump everything to view each time while (list.hasMoreElements()) { String name = (String) list.nextElement(); out.println(name + ": " + session.getAttribute(name) + "<BR>"); }//while out.println("</BODY></HTML>"); }//doGet public void doPost(HttpServletRequest request, HttpServletResponse res) throws ServletException, IOException { doGet(request, res);}

  44. Session lifecycle • Sessions expire automatically, or – on Tomcat, by default - after 30 minutes. • The servlet can invalidate a session at any time. • Any information saved in the user’s session object is lost when the session is invalidated. • Information needed beyond the timeout period should be saved in a database. • Methods for saving client information include providing a cookie that can last for years, requiring a login, or rewriting the URL to provide a “bookmark” as covered in the first part of this ppt. • Yahoo handles this via a login/pw and a persistent cookie. Even though the user is known via the cookie, Yahoo still requires a pw to read mail.

  45. Session lifecycle: timeout • In web.xml you can set session timeout: <web-app> … <session-config> <session-timeout> 60 <!– in minutes--> </session-timeout> </session-config> </web-app>

  46. Timeout • If timeout is set in session-config then the user is timed out after 60 minutes pass without any request being made. • The session object has a method setMaxInactiveInterval(int secs) to set session timeout. • Timeout value can be retrieved form the session object via getMaxInactiveInterval() • This method can also tell you the default timeout on a server if session-config hasn’t set a timeout.

  47. Original view of sessiontimer

  48. After reloading

  49. A compromise between security, convenience, and scalability • Server can destroy session-related objects when a session times out. • Security decreases as timeout period is extended. • Convenience increases with timeout length.

More Related