$KK(Listener) $R(Objective) Describe the Web container life cycle event model for requests, sessions, and web applications; create and configure listener classes for each scope life cycle; create and configure scope attribute listener classes; and given a scenario, identify the proper attribute listener to use. $R\ $KKK(Überblick der Listener Klassen) Instanzen von Listener Klassen beobachten Objekte. Wenn sich am Status dieser Objekte etwas ändert werden Events ausgelöst. Listener können auf diese Events reagieren. Es können Listener Klassen definiert werden, die den ServletContext, eine Session, bzw. ein Request beobachten. Es werden Events ausgelöst wenn Attribute hinzugefügt, gelöscht oder geändert werden, bzw. wenn einer der Scopes initialisiert bzw zerstört wird bzw. eine Session migriert (bei verteilten Anwendungen kann die Session von einer JVM zu einer anderen verlagert werden). $T(caption,clll,15.17.34.34) Scope | Event | Listener Interface | Event Klasse || Servlet Context | Initialisierung und Zerstörung | ServletContextListener | ServletContextEvent || | Änderungen an Attributen | SevletContextAttributeListener | ServletContextAttributeEvent || HttpSession | Erzeugung und Zerstörung | HttpSessionListener | HttpSessionEvent || | Änderungen an Attributen | HttpSessionAttributeListener | HttpSessionBindingEvent || Servlet Request | Initialisierung und Zerstörung | ServletRequestListener | ServletRequestEvent || | Änderungen an Attributen | ServletRequestAttribute Listener | ServletRequestAttributeEvent || $T\ Zusätzlich gibt es noch die Listener HttpSessionActivationListener und HttpSessionBindingListener, die nicht die Session selbst sondern die Attribute innerhalb einer Session beobachten. $T(caption,clll,15.17.34.34) Scope | Event | Listener Interface | Event Klasse || Session - Attribut | Migration (Aktivierung und Deaktivierung) | HttpSessionActivationListener | HttpSessionEvent || | Hinzufügen oder Entfernen zu einer Session | HttpSessionBindingListener | HttpSessionBindingEvent || $T\ $KKK(Listener die den Lebenzyklus eines Scopes beobachten) ServletContextListener Direkt nachdem ein ServletContext instantiiert wurde und bevor die dazugehhörigen Servlets und Filter geladen wurden, wird werden alle Listener, die das ServletContextListener Interface erfüllen benachrichtigt und die Methode contextInitialized(ServletContextEvent e) ausgeführt. Wenn ein ServletContext zerstört wird, (geschieht i.a. nur beim Herunterfahren des ServletContainers) werden nachdem die ganzen Servlets und Filter innerhalb dieses ServletContext noch die Methode contextDestroyed(ServletContextEvent e) aufgerufen. Das Interface hat folgende Methoden: $S() public interface ServletContextListener extends java.util.EventListener { public void contextDestroyed(ServletContextEvent sce); public void contextInitialized(ServletContextEvent sce); $S\ Die Eventklasse ist folgendermassen aufgebaut: $S() public class ServletContextEvent extends java.util.EventObject { public ServletContext getServletContext(); } $S\ HttpSessionListener Ein HttpSessionListener reagiert darauf wenn eine Session erzeugt, bzw beendet wurde. Das Interface hat folgende Methoden: $S() public interface HttpSessionListener extends java.util.EventListener { public void sessionCreated(HttpSessionEvent e); public void sessionDestroyed(HttpSessionEvent e); } public class HttpSessionEvent extends java.util.EventObject { public HttpSession getSession(); } $S\ ServletRequestListener Eine Anfrage wird initialisiert bevor diese den ersten Filter vor dem Servlet betritt, und wird beendet, nachdem diese den letzten Filter verlässt. $S() public interface ServletRequestListener { requestInitialized(ServletRequestEvent e); requestDestroyed(ServletRequestEvent e); } public class ServletRequestEvent extends java.util.EventObject { public ServletRequest getServletRequest(); public ServletRequest getServletContext(); } $S\ Eintrag in web.xml Die Klassen der Listener Objekte, müssen in der Datei web.xml unter dem listener Element eingetragen sein. $S() myWebapp.myPackage.MySpecialServletContextListener $S\ Die Listener werden beim Hochfahren des Containers in der Reihenfolge registriert, in der sie in der web.xml Datei aufgelistet sind. Beim Herunterfahren wird die umgekehrte Reihenfolge der Dekleration genommen, wobei die HttpSessionListener den ServletContextListener den Vorzug gegeben wird. Der Servlet Container instantiiert selbständig die Listener Klassen. Die Listener Klassen dürfen deshalb kein Argument im Constructor besitzen. Beispiel: Session Counter Listener $S() public class SessionCounterListener implements HttpSessionListener{ private static final String COUNTER_ATTR = "session_counter"; public void sessionCreated(HttpSessionEvent hse){ Counter counter = getCounter(hse); counter.increment(); } public void sessionDestroyed(HttpSessionEvent hse){ Counter counter = getCounter(hse); counter.decrement(); } private Counter getCounter(HttpSessionEvent hse){ HttpSession session = hse.getSession(); ServletContext context = session.getServletContext(); return (Counter) context.getAttribute(COUNTER_ATTR); } $S\ $KKK(Listener die Änderungen in der Attributliste ihres Scopes beobachten) Für jeden Scope gibt es Listener, die darauf reagieren, wenn ein neues Attribut in den Scope hinzugefügt wird, ein Attribut durch ein anderes Attribut ersetzt oder ein Attribut aus dem Scope gelöscht werden. Je nach Scope heissen die Listener: * ServletContextAttributeListener * HttpSessionAttributeListener * ServletRequestAttributeListener Die Interfaces besitzen die Methoden: (Ersetze "scope" durch ServletContextAttribute bzw. HttpSessionBinding oder ServletRequestAttribute) * public void attributeAdded("scope"Event e) * public void attributeReplaced("scope"Event e) * public void attributeRemoved("scope"Event e) Die "scope" AttributeEvent Objekte kennen z.B folgende Methoden $S() public class ServletRequestAttributeEvent extends ServletRequestEvent { public String getName(); public String getValue(); } $S\ Auch verwendete Listener Klassen muessen im Deployment Descriptor web.xml bei den Listener Elemente registriert sein. Der Container instantiiert diese Klassen selbstsändig. Vorsicht Falle Beachte ein Listener bemerkt es nicht, wenn ein Attribut geändert wird. Im unteren Beispiel wird kein Event getriggert, obwohl sich der Wert des Zaehlers ändert. $S() Counter counter = servletRequest.getAttribute("Zaehler"); counter.increment(): $S\ Im folgenden Beispiel wird ein Event getriggert. Gibt es das Attribut "Zaehler" in dem RequestScope schon, so wird die Methode attributeReplaced(e) aufgerufen; ansonsten wird die Methode attributeAdded(e) aufgerufen $S() Counter counter = servletRequest.setAttribute("Zaehler",new Counter()); counter.increment(): $S\ $KKK(Listener für Session Attribute) HttpSessionActivationListener In einer verteilten Umgebung kann eine Session von einer JVM zu einer ander JVM migrieren. Die Session, die auf der alten Viruellen Maschinen läuft, wird deaktiviert. Danach wird die Session auf der neuen JVM übertragen und instantiert, und diese Session danach aktiviert. Mit Hilfe von HttpSessionActivationListener kann der Programmierer darauf reagieren. $S() public interface HttpSessionActivationListener extends java.util.EventListener { public void sessionDidActivate(HttpSessionEvent e); public void sessionWillPassivate(HttpSessionEvent e); } public class HttpSessionEvent extends EventObject { public HttpSession getSession(); } $S\ HttpSessionBindingListener Der HttpSessionBindingListener unterscheidet sich von den anderen Listener Klassen. Klassen, die das HttpSessionBindingListener entsprechen, sind i.a. Attribute einer HttpSession. Die andere Listener beobachten den entsprechenden Scope. Der HttpSessionBindingListener Interface ist beobachtet das Attribut einer Session selbst. $S() public interface HttpSessionBindingListener extends EventListener{ public void valueBound(HttpSessionBindingEvent event); public void valueUnbound(HttpSessionBindingEvent event); } $S\ $S() public class HttpSessionBindingEvent extends HttpSessionEvent { public HttpSession getSession () public String getName() { public Object getValue() { } $S\ Alle Attribute die das HttpSessionBindingListener Interface erfüllen, werden benachrichtigt, falls das Attribut an die Session gebunden, oder von der Session gelöst wird. Die Benachrichtigung findet auch statt, falls die Session migriert, und das Attribut von der "alten" Session gelöst, bzw. an die "neue" Session gebunden wird. Nicht jedes Attribut einer Session muss das HttpSessionBindingListener Interface erfüllen, auch gibt es für den ServletRequest und ServletContextScope keine entsprechenden Interfaces