150 likes | 547 Views
Session Tracking Impose state on stateless http Associate request with a user
E N D
Session Tracking • Impose state on stateless http • Associate request with a user • By using Cookies. A Cookie is a string (in this case that string is the session ID) which is sent to a client to start a session. If the client wants to continue the session it sends back the Cookie with subsequent requests. This is the most common way to implement session tracking.
Session Tracking • By rewriting URLs. All links and redirections which are created by a Servlet have to be encoded to include the session ID. This is a less elegant solution (both, for Servlet implementors and users) because the session cannot be maintained by requesting a well-known URL or selecting a URL which was created in a different (or no) session. It also does not allow the use of static pages. All HTML pages which are sent within a session have to be created dynamically.
7:protected void doGet(HttpServletRequest req, HttpServletResponse res) 8:throws ServletException, IOException 9: { 10: res.setContentType("text/html"); 11: PrintWriter out = res.getWriter(); 12: out.print("<HTML><HEAD><TITLE>Online Shop</TITLE>"+ 13: "</HEAD><BODY><FORM METHOD=POST>"+ 14: "<INPUT TYPE=SUBMIT NAME=foo VALUE="+ 15: "\"Put a FOO into the shopping cart\">"+ 16: "<INPUT TYPE=SUBMIT NAME=bar VALUE="+ 17: "\"Put a BAR into the shopping cart\">"+ 18: "<INPUT TYPE=SUBMIT NAME=see VALUE="+ 19: "\"See the shopping cart contents\">"+ 20: "<INPUT TYPE=SUBMIT NAME=buy VALUE="+ 21: "\"Buy the shopping cart contents\">"+ 22: "</FORM></BODY></HTML>"); 23: out.close(); 24: }
Cookies • Get Session object. • Two counters, one for the FOOs and one for the BARs in the shopping cart. • retrieve the values for "foo" and "bar" from the session • All buttons have different names and we can find out which button was used to submit the form by checking which name has a non-null value.A new FOO or BAR item can be put into the shopping cart by simply incrementing the counter in the array. • When the user chooses to buy the contents of the shopping cart we call session.invalidate() to delete the session on the server side and tell the client to remove the session ID Cookie.
26:protected void doPost(HttpServletRequest req, HttpServletResponse res) 27:throws ServletException, IOException 28: { 29: String msg; 30: 31: HttpSession session = req.getSession(true); 32:if(session.isNew()) 33: { 34: session.putValue("foo", new int[] { 0 }); 35: session.putValue("bar", new int[] { 0 }); 36: } 37: 38:int[] foo = (int[])session.getValue("foo"); 39:int[] bar = (int[])session.getValue("bar"); 40: 41:if(req.getParameter("foo") != null) 42: { 43: foo[0]++; 44: msg = "Bought a FOO. You now have "+foo[0]+"."; 45: } 46:else if(req.getParameter("bar") != null) 47: { 48: bar[0]++; 49: msg = "Bought a BAR. You now have "+bar[0]+"."; 50: } 51:else if(req.getParameter("buy") != null) 52: { 53: session.invalidate(); 54: msg = "Your order for "+foo[0]+" FOOs and "+bar[0]+ 55: " BARs has been accepted. Your shopping cart is empty now."; 56: } 57:else 58: { 59: msg = "You have "+foo[0]+" FOOs and "+bar[0]+ 60: " BARs in your shopping cart."; 61: }
62: 63: res.setContentType("text/html"); 64: res.setHeader("pragma", "no-cache"); 65: PrintWriter out = res.getWriter(); 66: out.print("<HTML><HEAD><TITLE>Shopping Cart</TITLE></HEAD><BODY>"); 67: out.print(msg); 68: out.print("<HR><A HREF=\""); 69: out.print(req.getRequestURI()); 70: out.print("\">Back to the shop</A></BODY></HTML>"); 71: out.close(); 72: }
Adding URL Rewriting protected void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { HttpSession session = req.getSession(false);//Keep session alive but don’t create a new one res.setContentType("text/html"); res.setHeader("pragma", "no-cache");//response on cacheable PrintWriter out = res.getWriter(); out.print("<HTML><HEAD><TITLE>Online Shop</TITLE>"+ "</HEAD><BODY><FORM METHOD=POST ACTION="+ out.print(res.encodeUrl(req.getRequestURI()));//encoded session id out.print("><INPUT TYPE=SUBMIT NAME=foo VALUE="+ "\"Put a FOO into the shopping cart\">"+ "<INPUT TYPE=SUBMIT NAME=bar VALUE="+ "\"Put a BAR into the shopping cart\">"+ "<INPUT TYPE=SUBMIT NAME=see VALUE="+ "\"See the shopping cart contents\">"+ "<INPUT TYPE=SUBMIT NAME=buy VALUE="+ "\"Buy the shopping cart contents\">"+ "</FORM></BODY></HTML>"); out.close(); } out.print(res.encodeUrl(req.getRequestURI())) added to doPost;
Binary Data import java.io.*; 2:import javax.servlet.*; 3:import javax.servlet.http.*; 4: 5:public class XpmServlet extends HttpServlet 6: { 7:protected void doGet(HttpServletRequest req, 8: HttpServletResponse res) 9:throws ServletException, IOException 10: { 11: String color = req.getParameter("color"); 12: if(color == null) color = "FFFFFF"; 13: 14: res.setContentType("image/x-pixmap"); 15: res.setHeader("pragma", "no-cache"); 16: 17: ServletOutputStream out = res.getOutputStream(); 18: out.print("/* XPM */\n"+ 19: "static char * hello_xpm[] = {\n"+ 20: "\"17 13 2 1\",\n"+ 21: "\" \tc #000000\",\n"+ 22: "\"X\tc #"+color+"\",\n"+ 23: "\"XXXXX XXXXX\",\n"+ 24: "\" XXXXX XXXXX \",\n"+ 25: "\" XXXXX XXXXX \",\n"+ 26: "\" XXXXX XXXXX \",\n"+ 27: "\" XXXXXXXXX \",\n"+ 28: "\" XXXXXXX \",\n"+ 29: "\" XXXXX \",\n"+ 30: "\" XXXXXXX \",\n"+ 31: "\" XXXXXXXXX \",\n"+ 32: "\" XXXXX XXXXX \",\n"+ 33: "\" XXXXX XXXXX \",\n"+ 34: "\" XXXXX XXXXX \",\n"+ 35: "\"XXXXX XXXXX\"};\n"); 36: out.close(); 37: } 38: }
Servlet Environment • Inter-Servlet Communications • A Servlet can get a list of all other Servlets in the Servlet Context by calling getServletNames on the ServletContext object. • A Servlet for a known name (probably obtained through getServletNames) is returned by getServlet. • ClassLoader Restrictions
Classloader • A server uses a new ClassLoader each time it reloads a servlet. • This has the interesting side effect that, when the MyServlet class is reloaded, it is actually a different version of MyServlet than the version used by other classes. • Thus, although the returned class type is MyServlet and it's being cast to the type MyServlet, the cast is between different types (from two different class loaders) and the cast has to throw a ClassCastException. • The same type mismatch can occur if the class performing the cast is reloaded. Why? Because its new ClassLoader won't find MyServlet using the primordial class loader and will load its own copy of MyServlet. • MyServlet servlet = (MyServlet)getServletContext().getServlet("MyServlet");
public class FooServlet extends HttpServlet 2: { 3:protected void doGet(HttpServletRequest req, 4: HttpServletResponse res) 5:throws ServletException, IOException 6: { 7: ... 8: ServletContext context = getServletConfig().getServletContext(); 9: BarInterface bar = (BarInterface)context.getServlet("BarServlet"); 10: bar.bar(); 11: .. 12: } 13: 14: ... 15: }
1:public interface BarInterface 2: { 3:public void bar(); 4: } 1:public class BarServlet extends HttpServlet implements BarInterface 2: { 3:public void bar() 4: { 5: System.err.println(""bar() called""); 6: } 7: 8: ... 9: }
Active Server Resources • A Servlet can make a request to an active resource on the web server just like a client can (by requesting a URL). • The Servlet API supports a more direct way of accessing server resources from within a Servlet.
public class PresentationServlet extends HttpServlet { private static class ItemNotFoundException extends Exception { ItemNotFoundException() { super("Item not found"); } } protected void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { String item = req.getParameter("item"); if(item == null) { req.setAttibute("exception", new ItemNotFoundException()); getServletContext() .getRequestDispatcher("/servlet/ErrorServlet") .forward(req, res); } else { res.setContentType("text/html"); PrintWriter out = res.getWriter(); out.print("<HTML><HEAD><TITLE>Item " + item + "</TITLE>"+ "</HEAD><BODY>Item " + item + ":<P>"); getServletContext() .getRequestDispatcher("/servlet/ItemServlet?item="+item) .include(req, res); out.print("</BODY></HTML>"); } } }
The ServletContext class has several methods for accessing the shared objects: • public void setAttribute(String name, Object object) adds a new object or replaces an old object by the specified name. The attribute name should follow the same naming convention as a package name (e.g. a Servlet com.foo.fooservlet.FooServlet could have an attribute com.foo.fooservlet.bar). • Just like a custom ServletRequest attribute, an object which is stored as a ServletContext attribute should also be serializable to allow attributes to be shared by Servlets which are running in different JVMs on different machines in a load-balancing server environment. • public Object getAttribute(String name) returns the named object or null if the attribute does not exist. • In addition to the user-defined attributes there may also be predefined attributes which are specific to the Servlet engine and provide additional information about a Servlet(Context)'s environment. • public Enumeration getAttributeNames() returns an Enumeration of the names of all available attributes. • public void removeAttribute(String name) removes the attribute with the specified name if it exists.