© 2009 Marty Hall

The Web Application Life-Cycle Events Framework
Originals of Slides and Source Code for Examples: http://courses.coreservlets.com/Course-Materials/msajsp.html
Customized Java EE Training: http://courses.coreservlets.com/
Servlets, JSP, Struts, JSF/MyFaces/Facelets, Ajax, GWT, Spring, Hibernate/JPA, Java 5 & 6. Developed and taught by well-known author and developer. At public venues or onsite at your location.

© 2009 Marty Hall

For live Java training, please see training courses at http //co rses coreser lets com/ Ser http://courses.coreservlets.com/. Servlets, lets JSP JSP, Str Struts, ts JSF, Ajax, GWT, Java 5, Java 6, Spring, Hibernate, JPA, and customized combinations of topics. p
Taught by the author of Core Servlets and JSP, More Servlets and JSP, and this tutorial tutorial. Available at public venues, or customized versions can be held on-site at your Customized Java EE Training: http://courses.coreservlets.com/ Servlets, JSP, Struts, JSF/MyFaces/Facelets, Ajax, GWT, Spring, Hibernate/JPA, Java 5 & 6. organization. Contact hall@coreservlets.com for details. Developed and taught by well-known author and developer. At public venues or onsite at your location.

Agenda
• Reason for listeners • Monitoring creation and destruction of the servlet context • Detecting D t ti changes h i in servlet l t context t t attributes • Recognizing session creation and destruction • Watching for changes in session attributes g activities • Combining
5

Life-Cycle Events Framework
• Motivation 1: Respond to events in the overall ll application li i life lif cycle. l
– Notice when certain attributes are removed from the servlet context. context

• Motivation 2: Perform tasks more general y one servlet or JSP p page g has than any responsibility for.
– Insert application-wide data into the servlet context b f before any servlets l t or JSP pages are accessed d – Keep track of certain session attributes, regardless of which servlet or JSP p page g added the attributes

• New with servlets 2.3.
6

– Note: this section has not been updated to 2.4 or 2.5!

– Provide empty bodies for the other methods in the interface. the Web application) is initialized and destroyed. – These listeners are notified when the servlet context (i. Implement the appropriate interface. • Session attribute listeners.e. removed from. d invalidated. Override the methods needed to respond to the events of interest. – These listeners are notified when attributes are added to. 7 General Implementation Strategy 1. to removed from. • Servlet context attribute listeners. • Session listeners. – These listeners are notified when session objects are created. or HttpSessionAttributeListener.. or replaced p in the servlet context. – Six objects that you are likely to use in event-handling methods: 8 • The servlet context • The name of f the servlet context attribute that changed • The value of the servlet context attribute that changed • The session object The name of the session attribute that changed . or replaced in any session. listeners – These listeners are notified when attributes are added to. objects. S l C A ib Li HttpSessionListener. – U Use S ServletContextListener. l C Li ServletContextAttributeListener. i lid d or timed i d out.Available Listeners • Servlet context listeners. 2. 3 Access the important Web application objects 3.

– Thi This process i is application li i specific. 9 Monitoring Creation and Destruction of the Servlet Context • The ServletContextListener class responds to the h initialization i i i li i and d destruction d i of f the h servlet context.xml) or of a tag library descriptor file. – These events correspond to the creation and shutdown of the Web application itself. P id any needed d d initialization i iti li ti parameters. – You do d this hi with i h the h listener and d listener-class elements of the general Web application deployment descriptor (web. ifi but b there h are some common themes. store data for later access (setAttribute). you are most likely to read initialization parameters (getInitParameter). (setAttribute) and read previously stored data (getAttribute). • ServletContextListener is most commonly y used to – Set up application-wide resources like database connection ti pools l – Read the initial values of application-wide data that will be used by y multiple p servlets and JSP p pages. Use these objects.General Implementation Strategy (Continued) 4. with the servlet context. 5.xml element to provide the names and values of these initialization parameters. g 10 . Declare the listener. 6 Provide 6. For example. t – Servlet context listeners commonly read context initialization parameters to use as the basis of data that is made available to all servlets and JSP pages. You use the context-param web.

D d – contextInitialized is triggered when the Web application is first loaded and the servlet context is created. <context-param> <param-name>name</param-name> <param value>value</param value> <param-value>value</param-value> </context-param> 12 . Obtain a reference to the servlet context. Use the servlet context. log 5.Specific Implementation Strategy: Servlet Context Listeners 1.g. – The ServletContextEvent class has a getServletContext method th t t th l t t t 11 Specific Implementation Strategy: Servlet Context Listeners (Continued) 4. – contextDestroyed is triggered when the Web application is being shut down and the servlet context is about to be destroyed. – – – Read initialization parameters: getInitParameter Store data:setAttribute Make log file entries: log. – Th The contextInitialized I i i li d and d contextDestroyed D d methods h d each h take k a ServletContextEvent as an argument. O id contextInitialized I i i li d and d contextDestroyed. 2 Override 2.g. by reading context init params) • Storing that data in an easily accessible location .Listener</listener-class> </listener> 6 Provide needed initialization parameters 6.. <listener> <listener-class>package. Most common task: • Releasing resources (e. Implement the ServletContextListener interface. Declare the listener. parameters. Most common tasks: • Creating application-wide data (e. closing connections). 3.

String defaultValue) { String initialValue = context. context. if (initialValue != null) { context. "formerCompanyName". ""). String initParamName.Example: Web Site for Company with Changing Name public class InitialCompanyNameListener implements ServletContextListener { private static final String DEFAULT_NAME = "MISSING-COMPANY-NAME". initialValue).setAttribute(initParamName. } } … } 14 . } public bli void id contextDestroyed(ServletContextEvent t tD t d(S l tC t tE t event) t) {} 13 Servlet Context Listener Example (Continued) private void setInitialAttribute(ServletContext context.getInitParameter(initParamName). DEFAULT_NAME). "companyName" companyName . } else { context setAttribute(initParamName defaultValue).getServletContext(). public void contextInitialized(ServletContextEvent event) { ServletContext context = event.setAttribute(initParamName. setInitialAttribute(context. setInitialAttribute(context.

0" encoding="ISO-8859-1"?> <!DOCTYPE …> > <web-app> <context-param> <param-name>companyName</param-name> <param-value>not-dot-com.InitialCompanyNameListener </listener-class> </listener> </web-app> 16 .listeners.Servlet Context Listener: web xml web.com</param-value> </context-param> … 15 Servlet Context Listener: web xml (Continued) web.xml … <listener> <listener-class> moreservlets.com</param-value> </context-param> <context-param> p <param-name>formerCompanyName</param-name> <param-value>hot-dot-com.xml <?xml version="1.

jsp"><%= companyName %> history</A> <LI><A HREF="invest.getFormerCompanyName(application).getCompanyName(application).jsp">investing in <%= companyName %></A> <LI><A HREF="contact.jsp">contacting <%= companyName %></A> </UL> … 17 Servlet Context Listener: Results 18 .Servlet Context Listener: Using Results in JSP Technology <% String companyName = InitialCompanyNameListener.jsp ><% companyName %> products</A> <LI><A HREF="services. … %> <TITLE><% compan <TITLE><%= companyName Name %></TITLE> … <TABLE BORDER=5 ALIGN="CENTER"> <TR><TH CLASS="TITLE"> <%= companyName %><BR> <%= formerCompanyDescription %> … <UL> <LI><A HREF="products.jsp"><%= HREF products.jsp"><%= companyName %> services</A> <LI><A HREF="history. String formerCompanyName = InitialCompanyNameListener.

you need to automatically update the value of resource B. The old existing value is obtained via event. what if the value of resource B depends p on the value of resource A? If resource A changes. – 3. attributeReplaced is triggered when a new value is assigned to an g name. ib Add d attributeReplaced. getValue. and getServletContext . attributeRemoved is triggered when a servlet context attribute is removed altogether.getAttribute. • But what if you want to be notified whenever these resources change? – For example. 19 Implementation Strategy: Servlet Context Attribute Listeners 1. – – attributeAdded is triggered gg when a new attribute name is first added to the servlet context. and servlet context. Obtain references to the attribute name.Detecting Changes in Servlet Context Attributes • ServletContextListener – Lets you set up initial values of resources and store references to them in the servlet context.getValue and the new value is obtained via context. – 20 Call the following methods of the event object: getName. Implement ServletContextAttributeListener 2 Override 2. p . O id attributeAdded. – Handling this situation is the job of servlet context attribute listeners. ib R l d and d attributeRemoved. attribute value. attributeAdded is not triggered gg in this case.

Use the objects. store new or changed attributes (setAttribute) and make entries in the log file (log). <listener> <listener-class> somePackage. The servlet context is usually used to read previously stored attributes (getAttribute). (setAttribute). (log) Use the listener and listener listener-class class elements to list the fully qualified name of the listener class.Implementation Strategy: Servlet Context Attribute Listeners (Continued) 4. – You normally compare attribute name to a stored name to see if it is the one you are monitoring. Declare the listener.SomeListener </listener-class> </listener> 5. – 21 Example: Updating Former Company Name public class ChangedCompanyNameListener implements ServletContextAttributeListener { public void attributeAdded (ServletContextAttributeEvent event) {} public void attributeRemoved (ServletContextAttributeEvent event) {} 22 . The attribute value is used in an application-specific application specific manner.

listeners. context.0" encoding="ISO-8859-1"?> <!DOCTYPE …> > <web-app> <listener> <listener-class> moreservlets.ChangedCompanyNameListener </listener class> </listener-class> </listener> 24 . ServletContext context = event.Example: Updating Former Company Name (Continued) public void attributeReplaced (ServletContextAttributeEvent event) { if (event.getValue().getName(). } } 23 Example: Updating Former Company Name (Continued) <?xml version="1.equals("companyName")) { String oldName = (String)event.getServletContext(). oldName).setAttribute("formerCompanyName".

RedirectorServlet </servlet-class> </servlet> 25 Example: Updating Former Company Name (Continued) <servlet-mapping> <servlet-name> l t ChangeCompanyName </servlet-name> <url-pattern> /admin/ChangeCompanyName </url pattern> </url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>Redirector</servlet-name> <url-pattern>/servlet/*</url-pattern> </servlet-mapping> 26 .ChangeCompanyName </servlet-class> </servlet> <servlet> <servlet-name>Redirector</servlet-name> <servlet-class> moreservlets RedirectorServlet moreservlets.Example: Updating Former Company Name (Continued) <servlet> <servlet name> <servlet-name> ChangeCompanyName </servlet-name> <servlet-class> moreservlets.

jsp </form-login-page> <form-error-page> /admin/login-error.jsp / p g </form-error-page> </form-login-config> </login-config> 28 .Example: Updating Former Company Name (Continued) <security-constraint> <web-resource-collection> <web-resource-name>Admin</web-resource-name> <url pattern>/admin/*</url pattern> <url-pattern>/admin/*</url-pattern> </web-resource-collection> <auth-constraint> <role-name>ceo</role-name> l / l </auth-constraint> </security-constraint> 27 Example: Updating Former Company Name (Continued) <login-config> <login config> <auth-method>FORM</auth-method> <form-login-config> <form-login-page> /admin/login.

Example: Updating Former Company Name (Results) 29 Example: Updating Former Company Name (Results) 30 .

xml to declare Requires listeners • Listener not purely associated with tag library . a tag that uses servlet context attributes put there by a ServletContextListener – You'd like to include the listener with the tag library • Make it easy to reuse tag library in multiple Web apps • Generic G i approach h – – – – 32 Put tag library and listener classes in a JAR file Drop JAR file in WEB-INF/lib Put TLD file in WEB-INF q y you to modify y WEB-INF/web.g..Example: Updating Former Company Name (Results) 31 Packaging Listeners with Tag Libraries • Tag libraries provide encapsulation of logic – But what if tag depends on a listener? • E.

jsp"> contacting <msajsp:companyName/></A> </UL> 34 .Packaging Listeners with Tag Libraries • New JSP 1.jsp">investing in <msajsp:companyName/></A> <LI><A HREF="contact. l d d the th server automatically t ti ll looks for . bug – Defeats the purpose 33 • If you have to modify web.tld files in WEB-INF and its subdirectories • Not counting classes and lib directories • Approach to bundling listeners • Tomcat 4.0.xml to the TLD file y – Put TLD file in the WEB-INF hierarchy – Tomcat 4.xml.0 problem – Move listener element from web.jsp"><msajsp:companyName/> HREF "products jsp"><msajsp:companyName/> products</A> <LI><A HREF="services.xml web xml file contains taglib entries that gives an alias for the location of the TLD files. why not just declare listeners? Packaging Listeners with Tag Libraries: Example <%@ taglib uri="/company-name-taglib.x automatically detects TLD files only when the web. Works on other servers and Tomcat 4.jsp"><msajsp:companyName/> history</A> <LI><A HREF="invest.jsp"><msajsp:companyName/> services</A> <LI><A HREF="history.tld" prefix="msajsp" p j p %> Learn more about <B><msajsp:companyName/></B> <msajsp:formerCompanyName fullDescription="true"/> <UL> <LI><A HREF="products.1 and later – this is an implementation bug.2 Behavior – Wh When W Web b application li ti is i loaded.

0 40 … <web-app> b … <taglib> <taglib-uri> /company-name-taglib.tld </taglib-location> </taglib> … </web-app> 36 .xml web xml for Tomcat 4.tld </taglib uri> </taglib-uri> <taglib-location> /WEB-INF/company-name-taglib.listeners.InitialCompanyNameListener </listener-class> </listener> <listener> <listener-class> moreservlets.tags.ChangedCompanyNameListener </listener-class> </listener> <tag> <name>companyName</name> <tag-class>moreservlets.listeners.Packaging Listeners with Tag Libraries: Example TLD File <taglib>… <listener> <listener-class> moreservlets.CompanyNameTag </tag-class> <body-content>empty</body-content> <description>The current company name </description> </tag> … </taglib> 35 Packaging Listeners with Tag Libraries: web.

38 . you occasionally also want a reference to the servlet context. Multithreaded access is possible. 2 Override 2. – Each of the two HttpSessionListener methods takes an HttpSessionEvent as an argument. You almost always want this reference. – 3. first obtain the session object and then call getServletContext on it.Recognizing Session Creation and Destruction • The previous listeners monitor Webapplication-wide li i id data. y This destruction could be due to an explicit call to the invalidate method or because the elapsed time since the last client access exceeds the session timeout. d – What if you want to monitor user-specific data? • Session usage can be one of the main memory drains on your server – How do you monitor how many sessions are in use? • The answer to both is the same – Use session listeners! 37 Using HttpSessionListener 1. sessionDestroyed y is triggered gg when a a session is destroyed. Implement the HttpSessionListener interface. i D d – – sessionCreated is triggered when a new session is created. If so. Synchronize if necessary. O id sessionCreated i C d and d sessionDestroyed. The HttpSessionEvent class has a getSession method that provides access to the session object. Obtain a reference to the session and possibly to the servlet context.

– In web. – Wait! What about g getAttribute? Nope. so getAttribute is pointless. private int maxSessionCount = 0.Using HttpSessionListener • Use the objects. (currentSessionCount e tSess o Cou t > maxSessionCount) a Sess o Cou t) { if (cu maxSessionCount = currentSessionCount. so calling getAttribute is also pointless there. use listener and listenerclass to list fully qualified name of listener class. So. li t Example: Tracking Active Sessions public class SessionCounter implements HttpSessionListener { private int totalSessionCount = 0.SomeListener</listener-class> </listener> 39 • Declare D l th the listener. all attributes are removed before sessionDestroyed is called. <listener> <listener-class>package. sessionDestroyed is mostly reserved for listeners that are simply keeping track of the number of sessions in use. . currentSessionCount++. Do this in sessionCreated if you want to guarantee that all sessions have a certain attribute.xml or the TLD file. If you want to clean up attributes that are left in sessions that time out. there is nothing in the session yet. private int currentSessionCount = 0. } } 40 . public void sessionCreated(HttpSessionEvent event) { totalSessionCount++. p In sessionCreated. } (context == null) ) { if ( storeInServletContext(event). out you use the attributeRemoved method of HttpSessionAttributeListener. In addition. – One of the only methods you usually call on the session is setAttribute. as below. private ServletContext context = null.

jsp"> j p <FRAME SRC="test.jsp"> <FRAME FRAME SRC="test.*" COLS="*.*.*.jsp"> <FRAME SRC="test.jsp"><FRAME j p SRC="test.jsp"><FRAME SRC="test.jsp"> <FRAME SRC="test.jsp"> SRC "t t j " <NOFRAMES><BODY> This example requires a frame-capable browser browser. context = session. </BODY></NOFRAMES> </FRAMESET> 42 .*"> <FRAME SRC="test. context. p private ate void o d storeInServletContext(HttpSessionEvent sto e Se etCo te t( ttpSess o e t event) { HttpSession session = event.Example: Tracking Active Sessions (Continued) public void sessionDestroyed(HttpSessionEvent event){ currentSessionCount--.jsp"><FRAME SRC="test. } … // Register self in the servlet context so that // servlets and JSP pages can access the session // counts.*.jsp"> <FRAME SRC="test.getSession().*.jsp"><FRAME SRC="test.getServletContext().jsp"><FRAME SRC="test.jsp"><FRAME SRC "t t j " FRAME SRC="test.jsp"> <FRAME SRC="test.jsp"> <FRAME SRC="test.jsp"><FRAME SRC="test. this). then use frame-based page that accesses lots of pages at once: <FRAMESET ROWS="*. } 41 } Problem: How to Test Session Usage? • Disable cookies.setAttribute("sessionCounter".jsp"><FRAME SRC="test.

44 .Example: Tracking Active Sessions (Results) 43 Watching for Changes in Session Attributes • HttpSessionListener uses: – Lets you detect when a session is created or destroyed. • Solution: – HttpSessionAttributeListener interface. this listener does not let you clean up attributes that are in destroyed y sessions. • HttpSessionListener deficiencies: – Si Since session i attributes ib are removed d before b f session i destruction.

value. 4. If you want access to the servlet context. and getSession (the HttpSession object). – – attributeAdded is triggered gg when a new attribute name is first added to a session. – The HttpSessionAttributeListener methods take an HttpSessionBindingEvent as args. 46 . HttpSessionBindingEvent has three useful methods: getName (name of attribute that was changed). – Use listener and listener-class in web.xml as before. The attribute value is used in an application-specific manner. The old existing value is obtained via event. Declare the listener. – The e attribute a bu e name a e is s usually usua y co compared pa ed to o a stored s o ed name a e to o see if it is the one you are monitoring. getValue (value of changed attribute—new value for attributeAdded and previous value for attributeReplaced and attributeRemoved). O id attributeAdded. attributeReplaced is triggered when a new value is assigned to an g name. ib Add d attributeReplaced. attribute value session. 5. attributeAdded is not triggered gg in this case. Use the objects.getAttribute.Using HttpSessionAttributeListener 1. i d – 45 Using HttpSessionAttributeListener 3. attributeRemoved is triggered when a session attribute is removed altogether. The session is usually used to read previously stored attributes (getAttribute) or to store new or changed attributes (setAttribute) (setAttribute). This removal can be due to an explicit programmer call to removeAttribute. context first obtain the session and then call getServletContext on it. ib R l d and d attributeRemoved.getValue and the new value is obtained via session. but is more commonly due to the system removing all attributes of sessions that are about to be deleted b because th their i timeout ti t expired. session and servlet context context. Obtain references to the attribute name. Implement HttpSessionAttributeListener. 2 Override 2.

public void attributeAdded(HttpSessionBindingEvent event){ checkAttribute(event orderAttributeName. orderAttributeName itemName. checkAttribute(event. checkAttribute(event. itemName. " finalized purchase of a "). private String itemName = "yacht". 47 Example: Monitoring Yacht Orders (Continued) /** * * * * */ Checks for initial ordering and final purchase of yacht. Records "Customer Customer ordered a yacht yacht" if the orderedItem attribute matches "yacht". Records "Customer finalized purchase of a yacht" if the purchasedItem attribute matches "yacht".Example: Monitoring Yacht Orders public class YachtWatcher implements HttpSessionAttributeListener { private String orderAttributeName = "orderedItem". purchaseAttributeName. itemName " ordered a "). } 48 . private String purchaseAttributeName = "purchasedItem".

public void attributeReplaced (HttpSessionBindingEvent event) { checkAttribute(event orderAttributeName. itemName. ). orderAttributeName itemName.Example: Monitoring Yacht Orders (Continued) /** Checks for order cancellation: was an order for "yacht" * cancelled? Records "Customer Customer cancelled an order for * a yacht" if the orderedItem attribute matches "yacht". " cancelled an order for a "). */ public void attributeRemoved(HttpSessionBindingEvent event) { checkAttribute(event. } 49 Example: Monitoring Yacht Orders (Continued) /** * * * */ Checks for item replacement: was "yacht" replaced by some other item? Records "Customer Customer changed to a new item instead of a yacht" if the orderedItem attribute matches "yacht". checkAttribute(event. itemName " changed to a new item instead of a "). orderAttributeName. } 50 .

etCo te t(). 2001-11-07 11:53:05 Customer finalized purchase of a yacht. event String orderAttributeName. if (currentAttributeName.getSession(). String currentItemName = (String)event. 2001-11-07 11:53:35 Customer ordered a yacht.equals(orderAttributeName) && currentItemName.getSe event. 2001-11-07 11:52:37 Customer cancelled an order for a yacht. 2001-11-07 11:54:27 Customer changed to a new item instead of a yacht.Example: Monitoring Yacht Orders (Continued) private void checkAttribute (HttpSessionBindingEvent event. String keyItemName. 2001-11-07 11:54:20 Customer changed to a new item instead of a yacht.equals(keyItemName)) { ServletContext context = e e t. 2001 11 07 11:54:42 2001-11-07 11 54 42 Customer C t cancelled ll d an order d for f a yacht. 2001-11-07 11:53:50 Customer cancelled an order for a yacht.getSess o (). } } } 51 Example: Monitoring Yacht Orders (Results) Log File 2001-11-07 11:50:59 Customer ordered a yacht. 2001-11-07 11:54:47 Customer changed to a new item instead of a yacht. String message) { String currentAttributeName = event. 52 . ht 2001-11-07 11:54:44 Customer ordered a yacht."). context.getValue().getServletContext(). 2001-11-07 11:51:06 Customer changed to a new item instead of a yacht.log("Customer" + message + keyItemName + ".getName().

53 Using Multiple Cooperating Listeners (Results) 54 . example you want to monitor purchases of the current daily special – ServletContextListener to set up application application-wide wide information about the session attributes that store daily specials – ServletContextAttributeListener S l tC t tAtt ib t Li t to t monitor it changes h to t the attributes that store the information – HttpSessionAttributeListener p to keep p a running g count of orders for the daily special.Using Multiple Cooperating Listeners • Some tasks cannot be accomplished with any one listener li type – A combination is required • For example.

Using Multiple Cooperating Listeners (Results Continued) 55 Summary • Available listeners – Servlet context listeners. or timed out. listeners • Notified when context attributes are added/removed/replaced – Session S i li listeners. – Servlet context attribute listeners. • Notified when servlet context is initialized and destroyed. invalidated. access the d d bj h h h bj h . • Notified when session attributes are added/removed/replaced • Steps 56 – Implement interface. t • Notified when sessions are created. – Session attribute listeners. override methods.

coreservlets. Hibernate/JPA. Developed and taught by well-known author and developer.© 2009 Marty Hall Questions? Customized Java EE Training: http://courses. JSP. At public venues or onsite at your location.com/ Servlets. Spring. Java 5 & 6. . Ajax. Struts. JSF/MyFaces/Facelets. GWT.

Sign up to vote on this title
UsefulNot useful