$KK(Session Listener) $R(Objective) Using session listeners, write code to respond to an event when an object is added to a session, and write code to respond to an event when a session object migrates from one VM to another. $R\ Es gibt zwei Listener Interfaces, die Objekte beobachten. * Das Interface HttpSessionAttributListener beobachtet eine Session und es wird eine der Methoden attributeAdded, attributeReplaced bzw attributeRemoved ausgelöst, falls ein Objekt eine Session zugoerdnet, bzw entfernt wird. Hier ein Beispielcode: $S() public final class SessionListener implements HttpSessionAttributeListener { public void attributeAdded(HttpSessionBindingEvent event) { System.out.println("attributeAdded"); System.out.println(event.getSession().getId()); System.out.println(event.getName() + "', '" + event.getValue()); } public void attributeRemoved(HttpSessionBindingEvent event) { System.out.println("attributeRemoved"); System.out.println(event.getSession().getId()); System.out.println(event.getName() + "', '" + event.getValue()); } public void attributeReplaced(HttpSessionBindingEvent event) { System.out.println("attributeReplaced"); System.out.println(event.getSession().getId()); System.out.println(event.getName() + "', '" + event.getValue()); } } $S\ Die Listener Klasse muss in der Datei web.xml deklariert werden $S() ... packagesListener.SessionListener $S\ * Mit dem HttpSessionBindingListener werden einzelne Attribute beobachtet. Dieses Interface wird nicht in der Datei web.xml deklarieren Hier ein Code Beispiel: $S() public class CounterBean implements HttpSessionBindingListener { private int count = 1; public int getValue() { return count; } public void increment() { count++; } public void valueBound(HttpSessionBindingEvent event) { System.out.println("attributeBounded"); System.out.println(event.getSession().getId()); System.out.println(event.getName() + "', '" + event.getValue()); } public void valueUnbound(HttpSessionBindingEvent event) { System.out.println("attributeUnbounded"); System.out.println(event.getSession().getId()); System.out.println(event.getName() + "', '" + event.getValue()); } } $S\ In einer verteilten Umgebung kann eine Session von einer JVM zu einer anderen migrieren. Intern wird die alte Session deaktiviert, die neue aktiviert. Die Attribute der Session müssen serialisiert und zur neuen Session migriert werden. Ein HttpSessionActivationListener beobachtet ein Attribut, und führt die Methoden sessionWillPassivate() bzw. sessionWillActivate() aus kurz vor oder direkt nach der Migration aus. $S() public class CounterBean implements HttpSessionActivationListener { private int count = 1; public int getValue() { return count; } public void increment() { count++; } public void sessionWillPassivate(HttpSessionEvent se) { System.out.println("session is about to be passivated"); // save counter's value to persistent storage .... } public void sessionDidActivate(HttpSessionEvent se) { System.out.println("session has just been activated"); // retrieve counter's value from persistent storage .... } } $S\ $KK(Techniken zum Session Management) $R(Objective) Given a scenario, describe which session management mechanism the Web container could employ, how cookies might be used to manage sessions, how URL rewriting might be used to manage sessions, and write servlet code to perform URL rewriting. $R\ Http ist ein zustandsloses Protokoll. Es ist ohne Tricks nicht möglich bei 2 verschiedenen Anfragen an den Server zu entscheiden, ob diese Anfragen vom selben Clienten kommen. Der Trick allgemein ist, bei der ersten Anfrage dem Clienten eine Sessionnummer zu geben, bei jeder weiteren Anfrage muss der Client diese Sessionnummer dem Server zeigen. Es gibt folgende Möglichkeiten eine Sessionnummer zu vergeben, und weiterzuleiten. * Cookie * URL-Rewriting * SSL Sessions * speziell bei JSP ueber versteckte Formularfelder Cookies Cookies sind die einfachste und häufigste Methode, dem Clienten eine SessionId mitzugeben. Das Cookie muss den Namen JSESSIONID haben. Allerdings erlauben die meisten Browser dem Anwender das Speichern von Cookies abzuschalten. SSL Sessions Für den Austausch von sensiblen Daten sollte die Verschlüsselungstechnologie SSL (Secure Layer Socket) herangezogen werden, die von dem HTTPS-Protokoll verwendet wird. Sie bietet eingebaute Mechanismen, um eine Folge von Anfragen eindeutig einer Sitzung mit einem bestimmten Client zuzuordnen. Der Servlet-Container kann diese Daten verwenden, um eine Sitzung zu definieren und zu verwalten. URL Rewrite URL rewriting wird als Ersatz genommen, falls der Client Browser keine Cookies erlaubt. Die Idee ist einfach den sessionId an die URL anzuhängen. Der Name des Paramters heisst jsessionid. Beachte im Gegensatz zu den Cookies wird hier jessionid klein geschrieben. Wenn man eine URL erzeugt muss garantiert sein, dass auch dort die SessionId angehängt wird. Dazu bietet das Interface in HttpServletResponse 2 Methoden: * encodeURL(String) Diese Methode gibt eine URL zurück, an der die sessionId angehängt ist. * encodeRedirectURL(String) Dies wird statt der sendRedirect() Methode genommen, wenn also die URL an eine andere Adresse umgeleitet wird. Hier ein Code Beispiel: $S() public void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException { response.setContentType("text/html"); PrintWriter out = response.getWriter(); ... out.print("
"); } $S\ Im Zusammenhang mit Session Management sind noch solche Methoden interessant: $S() public interface HttpSession { public boolean isRequestedSessionIdFromCookie(); public boolean isRequestedSessionIdFromURL(); public boolean isRequestedSessionIdValid(); } $S\