Die Session-Verwaltung
Allgemein
Mehrere BenutzerInnen (oder allgemeiner Prinzipale) können gleichzeitig Sitzungen mit dem MyCoRe-Softwaresystem eröffnen. Während einer Sitzung werden in der Regel nicht nur eine, sondern mehrere Anfragen bearbeitet. Es ist daher sinnvoll, kontextspezifische Informationen wie die UserID, die gewünschte Sprache usw. für die Dauer der Sitzung mitzuführen. Da das MyCoRe-System mit mehreren gleichzeitigen Sitzungen konfrontiert werden kann, die zudem über verschiedene Zugangswege etabliert sein können (z.B. Servlets, Kommandozeilenschnittstelle oder Webservices), muss das System einen allgemein verwendbaren Kontextwechsel ermöglichen.
Bei der Bearbeitung einer Anfrage oder Transaktion muss nicht jede einzelne Methode oder Klasse Kenntnis über die Kontextinformationen besitzen. Daher ist es sinnvoll, die Übergabe des Kontextes als Parameter von Methode zu Methode bzw. von Klasse zu Klasse zu vermeiden. Eine Möglichkeit, dies zu bewerkstelligen ist der Einsatz von sog. Thread Singletons oder thread-local Variablen. Die Idee dabei ist, den Thread der den Request bearbeitet als Repräsentation des Request selbst anzusehen. Dazu müssen die Kontextinformationen allerdings an den Thread angebunden werden, was seit Java 1.2 mit Hilfe der Klassen java.lang.ThreadLocal bzw. java.lang.InheritableThreadLocal möglich ist. Jeder Thread hat dabei seine eigene unabhängig initialisierte Kopie der Variable. Die set() und get() Methoden der Klasse ThreadLocal setzen bzw. geben die Variable zurück, die zum gerade ausgeführten Thread gehört. Die Klassen der Sessionverwaltung von MyCoRe sind auf Basis dieser Technologie implementiert (siehe Abbildung 1.5).

Abbildung 1.5: Die Klassen der Sessionverwaltung
Klienten der Sessionverwaltung sind alle Klassen, die Kontextinformationen lesen oder modifizieren wollen, wie zum Beispiel MCRCommandLineInterface und MCRServlet. Kontextinformationen werden als Instanzen der Klasse MCRSession abgelegt. Diese Klasse bietet Methoden zum Setzen und Lesen der Informationen, wie z.B. der UserID der aktuellen Benutzerin, der gewünschten Sprache usw.
Die Klasse MCRSession besitzt einen statischen Cache, realisiert durch die Klasse MCRCache. Bei der Konstruktion einer Instanz von MCRSession wird zunächst über die Methode buildSessionID() eine eindeutige Id erzeugt und diese als Schlüssel zusammen mit dem Session-Objekt selbst im Cache abgelegt. Auf diese Weise hat man über die statische Methode getSession() Zugriff auf die zu einer bestimmten SessionID gehörende Instanz.
Damit die Instanzen von MCRSession als thread-local Variablen an den aktuellen Thread angebunden werden können, werden sie nicht direkt, sondern über die statische Methode getCurrentSession() der Klasse MCRSessionMgr erzeugt und später gelesen. Beim ersten Aufruf von getCurrentSession() in einem Thread wird über die von java.lang.ThreadLocal erbende, statische innere Klasse ThreadLocalSession gewährleistet, dass eine eindeutige Instanz von MCRSession erzeugt und als thread-local Variable abgelegt wird. Der Zugriff auf die thread-local Variablen eines Threads kann nur über die Klasse ThreadLocal (bzw. InheritableThreadLocal) erfolgen. Auf diese Weise ist sichergestellt, dass bei nachfolgenden Aufrufen von getCurrentSession() genau die zum aktuellen Thread gehörende Referenz auf die Instanz von MCRSession zurückgegeben wird.
Mit der statischen Methode MCRSessionMgr.setCurrentSession() ist es möglich, ein bereits vorhandenes Session-Objekt explizit als thread-local Variable an den aktuellen Thread zu binden. Dies ist z.B. In einer Servlet-Umgebung notwendig, wenn die Kontextinformationen in einem Session-Objekt über eine http-Session mitgeführt werden. (Aktuelle Servlet-Engines verwenden in der Regel zwar Thread-Pools für die Bearbeitung der Requests, aber es ist in keiner Weise sichergestellt, dass aufeinanderfolgende Requests mit dem selben Kontext wieder den selben Thread zugewiesen bekommen. Daher muss der Kontext in einer http-Session gespeichert werden.)
Die Methode MCRSessionMgr.releaseCurrentSession() sorgt dafür, dass das thread-local Session-Objekt eines Threads durch ein neues, leeres Objekt ersetzt wird. Dies ist in Thread-Pool-Umgebungen wichtig, weil es sonst möglich bzw. sogar wahrscheinlich ist, dass Kontextinformationen an einem Thread angebunden sind, dieser Thread aber bei seiner Wiederverwendung in einem ganz anderen Kontext arbeitet. Code-Beispiele zur Verwendung der Session-Verwaltung finden sich in org.mycore.frontend.servlets.MCRServlet.doGetPost().
Variablenwerte in der Session speichern
Sie können über den Webclient (Browser) Werte in der aktuellen Session speichern. Sie können so über einen Link (URL, HTTP GET) oder das Absenden eines Formulars (HTTP POST) einen Wert an den Server senden, der dann in der Session abgelegt wird. Dazu muss die folgende Syntax für den HTTP Request Parameter verwendet werden:
XSL.<name>.SESSION=<wert>
z.B.
http://.../seite.xml?XSL.mode.SESSION=active
In der MCRSession wird so z.B. der Variablenwert mode=active abgelegt. Sie können dann in Java-Code über
MCRSessionMgr.getCurrentSession().get(“mode“)
darauf zugreifen, oder in einem beliebigen Stylesheet diese Variable verwenden. Dazu muss sie im Kopf des Stylesheets deklariert werden:
<xsl:param name=“mode“ />


