1 / 46

COMP 321

COMP 321. Week 9. Overview. Lab 7-1 “Preparing to Build Web Applications” Solution Session Management Cookies JSP. Lab 7-1 Solution. Session Management. HTTP is stateless – each request from the client looks like a new conversation

Download Presentation

COMP 321

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. COMP 321 Week 9

  2. Overview • Lab 7-1 “Preparing to Build Web Applications” Solution • Session Management • Cookies • JSP

  3. Lab 7-1 Solution

  4. Session Management • HTTP is stateless – each request from the client looks like a new conversation • Web applications need to maintain state across pages (think of browsing Amazon and putting books in your shopping cart) • How can we do this?

  5. Session Management (cont’d) • Stateful EJB • Works, but it’s complicated. Also, requires a full J2EE application server • Database • Also works, but could be slow and is overkill for many applications • HttpSession • This is a nice, lightweight solution. We assign an HttpSession object to each client connection, and use them to maintain conversational state

  6. Session Management (cont’d) • Browser displays form - What type of beer do you like? • Diane submits page with response - dark • Container stores response in Diane’s session, returns another page with another question - What price range? • Diane answers question, submits second page with response • Container stores this answer in session, continues…

  7. Session Management (cont’d) • How can the container remember which client is which? • IP Address? • This does not work because of NAT • HTTPS Security Context? • Would require HTTPS for each connection • Session ID • Container can send unique session ID to each client

  8. Session Management (cont’d) • Cookies are used to store the session ID • Cookies are a name-value pair that the browser stores under a web domain • When subsequent requests are sent to the domain, the cookie data is included: HTTP/1.1 200 OK Set-Cookie: JSESSIONID=0AAB6C8DE415 ... POST /select/selectBeerTaste2.do HTTP/1.1 Host: www.wickedlysmart.com User-Agent: Mozilla/5.0 Cookie: JSESSIONID=0AAB6C8DE415

  9. Session Management (cont’d) • How do we create a session in the servlet? Just ask for one. • How do we get the session object on a subsequent request? // Send a session cookie in the response HttpSession session = request.getSession(); // Get the session for this conversation HttpSession session = request.getSession();

  10. URL Rewriting • Can be used to maintain session state without cookies • Works by appending session information to the end of every link: http://www.wickedlysmart.com/BeerTest.do;jsessionid=0AAB6C8DE415 • Must be done on every page in the application - no static HTML allowed • Must use response.encodeURL() for every URL in the generated pages

  11. Session Expiration • Session times out • Timeout was set in deployment descriptor • Timeout was set by calling setMaxInactiveInterval() • invalidate() was called • Web application goes down

  12. Why Use Cookies? • They survive longer than the session! // Create a new cookie, and return as part of response Cookie cookie = newCookie("username", name); cookie.setMaxAge(30*60); // 30 minutes response.addCookie(cookie); // On next request, find cookie Cookie[] cookies = request.getCookies(); for(Cookie cookie : cookies) { if(cookie.getName().equals("username")) { String username = cookie.getValue(); out.println("Hello, " + username); break; } }

  13. Session Lifecycle Events • Lifecycle – HttpSessionListener • Session created • Session destroyed • Attributes – HttpSessionAttributeListener • Attribute added • Attribute replaced • Attribute removed • Migration – HttpSessionActivationListener • Session about to be passivated • Session has been activated

  14. Session Migration • What happens to ServletContext, ServletConfig, and HttpSession in a clustered (distributed) environment? • Most parts of the web application are duplicated on each VM, but session objects are unique • When a session is needed on a specific VM, it is moved to that VM

  15. Session Migration in Action • Request is sent to VM1, session #123 is created • Next request from same client goes to VM2, servlet asks for session #123 • VM2 sees that session 123 exists in VM1 • Session is passivated in VM1, moved to VM2, and activated there • Servlet execution in VM2 continues normally

  16. Session Listener Example <web-app ...> <listener> <listener-class>com.example.BeerSessionCounter</listener-class> </listener> </web-app> publicclassBeerSessionCounterimplementsHttpSessionListener { staticprivateintactiveSessions; publicstaticintgetActiveSessions() { returnactiveSessions;} publicvoidsessionCreated(HttpSessionEvent event) { activeSessions++; } publicvoidsessionDestroyed(HttpSessionEvent event) { activeSessions--; } }

  17. Attribute Listener Example // Deployment descriptor identical to session listener, except for class name publicclassBeerAttributeListener implementsHttpSessionAttributeListener{ publicvoidattributeAdded(HttpSessionBindingEvent event) { System.out.println("Attr added: " + event.getName() + ": " + event.getValue()); } publicvoidattributeRemoved(HttpSessionBindingEvent event) { System.out.println("Attr removed: " + event.getName() + ": " + event.getValue()); } publicvoidattributeReplaced(HttpSessionBindingEvent event) { System.out.println("Attr replaced: " + event.getName() + ": " + event.getValue()); } }

  18. Attribute Class Events publicclass Dog implementsHttpSessionBindingListener, HttpSessionActivationListener, Serializable { publicvoidvalueBound(HttpSessionBindingEvent event) { // Run some code now that I'm in a session } publicvoidvalueUnbound(HttpSessionBindingEvent event) { // Run some code now that I'm not part of a session } publicvoidsessionWillPassivate(HttpSessionEvent event) { // Save my non-serializable fields somehow } publicvoidsessionDidActivate(HttpSessionEvent event) { // Restore whatever I did in sessionWillPassivate } }

  19. JSP • Avoids ugly HTML embedded in Java code • Helps to separate presentation from implementation logic • Causes a servlet class to be generated and compiled automatically

  20. A Simple JSP Example <html> <body> The page count is: <% out.println(Counter.getCount()); %> </body> </html> package foo; publicclassCounter { privatestaticintcount; publicstaticsynchronizedintgetCount() { count++; returncount; } }

  21. A Simple JSP Example <html> <body> The page count is: <% out.println(Counter.getCount()); %> </body> </html> package foo; publicclassCounter { privatestaticintcount; publicstaticsynchronizedintgetCount() { count++; returncount; } } This causes an error! Why?

  22. A Simple JSP Example <!-- We need to import the package Counter lives in... --> <%@ page import="foo.*" %> <html> <body> The page count is: <% <!-- ...or use a fully scoped name --> out.println(foo.Counter.getCount()); %> </body> </html>

  23. A Simple JSP Example <!-- We need to import the package Counter lives in... --> <%@ page import="foo.*" %> <html> <body> The page count is: <% <!-- ...or use a fully scoped name --> out.println(foo.Counter.getCount()); %> </body> </html> But wait! I thought we were trying to eliminate all of the calls to println?

  24. A Simple JSP Example <%@ page import="foo.*" %> <html> <body> The page count is: <%= Counter.getCount() %> <!-- Notice there's no ; up there --> </body> </html>

  25. JSP Expressions • Which of these are valid? <%= 27 %> <%= ((Math.random() + 5) * 2); %> <%= “27” %> <%= Math.random() %> <%= String s = “foo” %> <%= new String[3] %> <% = 42 * 20 %> <%= 5 > 3 %> <%= false %> <%= new Counter() %>

  26. JSP Expressions • Which of these are valid? <%= 27 %> <%= ((Math.random() + 5) * 2); %> Can’t have semicolon <%= “27” %> <%= Math.random() %> <%= String s = “foo” %> Can’t have variable declaration <%= new String[3] %> <% = 42 * 20 %> Can’t have space between the % and the = <%= 5 > 3 %> <%= false %> <%= new Counter() %>

  27. A Simple JSP Example <%@ page import="foo.*" %> <html> <body> The page count is: <%= Counter.getCount() %> <!-- Notice there's no ; up there --> </body> </html> If this is creating a Java class, can't we get rid of Counter?

  28. A Simple JSP Example <html> <body> <%intcount = 0; %> The page count is: <%= ++count %> </body> </html> Will this work? What code will be generated?

  29. A Simple JSP Example <html> <body> <%intcount = 0; %> The page count is: <%= ++count %> </body> </html> publicvoid_jspService(HttpServletRequest request, HttpServletResponse response) throwsIOException, ServletException { PrintWriter out = response.getWriter(); response.setContentType("text/html"); out.write("<html><body>"); intcount = 0; out.write("The page count is now:"); out.print(++count); out.write("</body></html>"); }

  30. A Simple JSP Example <html> <body> <%!intcount = 0; %> The page count is: <%= ++count %> </body> </html>

  31. A Simple JSP Example <html> <body> <%!intcount = 0; %> The page count is: <%= ++count %> </body> </html> intcount = 0; publicvoid_jspService(HttpServletRequest request, HttpServletResponse response) throwsIOException, ServletException { PrintWriter out = response.getWriter(); response.setContentType("text/html"); out.write("<html><body>"); out.write("The page count is now:"); out.print(++count); out.write("</body></html>"); }

  32. Implicit Objects • JspWriter out • HttpServletRequest request • HttpServletResponse response • HttpSession session • ServletContext application • ServletConfig config • Throwable exception • PageContext page context • Object page

  33. Be the Container <!-- What output is produced? --> <html><body> Test scriptlets... <%inty = 5 + x; %> <%intx = 2; %> </body></html>

  34. Be the Container <!-- What output is produced? --> <html><body> Test scriptlets... <%inty = 5 + x; %> <%intx = 2; %> </body></html> Compile Error!

  35. Be the Container <!-- What output is produced? --> <%@ page import="java.util.*" %> <html><body> Test scriptlets... <% ArrayList list = newArrayList(); list.add("foo"); %> <%= list.get(0) %> </body></html>

  36. Be the Container <!-- What output is produced? --> <%@ page import="java.util.*" %> <html><body> Test scriptlets... <% ArrayList list = newArrayList(); list.add("foo"); %> <%= list.get(0) %> </body></html> Test scriptlets... foo

  37. Be the Container <!-- What output is produced? --> <html><body> Test scriptlets... <%!intx = 42; %> <%intx = 22; %> <%= x %> </body></html>

  38. Be the Container <!-- What output is produced? --> <html><body> Test scriptlets... <%!intx = 42; %> <%intx = 22; %> <%= x %> </body></html> Test scriptlets... 22

  39. JSP Comments <!-- HTML comment --> This is included in the HTML sent to the browser, and then ignored. <%-- JSP comment --%> This is ignored by the compiler, and never makes it into the servlet class.

  40. Generated Servlet API • jspInit() – called from the servlet's init() method. Can be overridden. • jspDestroy() – called from the servlet's destroy() method. Can be overridden. • _jspService() – called from the servlet's service() method. Can't be overridden.

  41. JSP Lifecycle • JSP is deployed in a web app • Container reads DD, but doesn’t do anything yet • Client requests JSP • Container translates JSP to a servlet, compiles it, and loads the servlet • Servlet instance is created, and jspInit() is executed • Container creates thread to handle request, and calls _jspService() method. • The rest of the request is handled like an ordinary servlet request

  42. JSP Attributes • Application application.setAttribute("foo", barObj); • Request request.setAttribute("foo", barObj); • Session session.setAttribute("foo", barObj); • Page pageContext.setAttribute("foo", barObj);

  43. JSP Attributes <!-- PageContext can be used to get/set attributes for all scopes --> <!-- Get page-scoped attribute --> <%= pageContext.getAttribute("foo") %> <!-- Get request-scoped attribute --> <%= pageContext.getAttribute("foo", PageContext.REQUEST_SCOPE) %> <!-- Get session-scoped attribute --> <%= pageContext.getAttribute("foo", PageContext.SESSION_SCOPE) %> <!-- Get an application-scoped attribute --> <%= pageContext.getAttribute("foo", PageContext.APPLICATION_SCOPE) %> <!-- Find an attribute in most-specific scope --> <%= pageContext.findAttribute("foo") %>

  44. Eliminating Java in JSPs • This is the ultimate goal – presentation and implementation should be completely separate • Allows designers to edit JSPs without fear of breaking things, and vice versa

  45. EL Sneak Preview <!-- Instead of... --> Please contact: <%= application.getAttribute("mail") %> <!-- ...we use --> Please contact: ${applicationScope.mail} <!– We can disable scripting elements in the DD: --> <web-app ...> ... <jsp-config> <jsp-property-group> <url-pattern>*.jsp</url-pattern> <scripting-invalid>true</scripting-invalid> </jsp-property-group> </jsp-config> ... </web-app>

  46. Progress Check • Due next week: • Lab 8-1 Servlets

More Related