{"id":175,"date":"2020-10-23T09:25:22","date_gmt":"2020-10-23T07:25:22","guid":{"rendered":"https:\/\/www.schoenberg-solutions.de\/arndtblog\/?p=175"},"modified":"2023-02-03T13:35:24","modified_gmt":"2023-02-03T12:35:24","slug":"nur-ein-tab-browser-in-einer-jee-jsf-server-sitzung","status":"publish","type":"post","link":"https:\/\/www.schoenberg-solutions.de\/arndtblog\/?p=175","title":{"rendered":"Nur ein Tab \/ Browser in einer JEE \/ JSF Server Sitzung"},"content":{"rendered":"\n<p>Nur ein Tab \/ Browser in einer Server Sitzung Ein h\u00e4ufiges Problem in webbasierten Serveranwendungen ist es, dass nicht gekl\u00e4rt werden kann, ob der Nutzer mehrere Tabs ge\u00f6ffnet hat und ggf. die Sitzungsdaten eines Vorgangs mit mehreren Tabs gleichzeitig ver\u00e4ndert. Beim Zugriff von verschiedenen Browsern oder im privaten Fenster sind die Sitzungen auf dem Server getrennt und es kann mit Sperren auf den Businesobjekten gearbeitet werden. Um sicher zu gehen, dass ein Nutzer nicht mit mehreren Fenstern \/ Tabs in einer Sitzung arbeitet, muss Java Script zur Hilfe genommen werden. In Kombination mit den Remote Commands von JSF \/ Primefaces hat man das Handwerkszeug, um sicherzustellen, dass der Nutzer nur einen Tab je Sitzung verwendet. Um dies zu realisieren, werden zwei Attribute in einer JSF Session Bean ben\u00f6tigt. Das eine Attribut ist eine eindeutige Nummer f\u00fcr den aktuell g\u00fcltigen Tab. Das andere ein Flag, dass Kennzeichnet, ob der Tab geschlossen wurde. Da bei einem Reload einer Seite der Tab geschlossen (unload) wird und danach sich direkt wierder \u00f6ffnet, ist ein Java Skript Listener f\u00fcr \u201ebeforeunload\u201c nicht ausreichend. Das Vorgehen: Beim Erzeugen des Tabs wird eine eindeutige Nummer erzeugt und im \u201esessionStorage\u201c des Browser abgelegt.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>function defineTabId() {\n    var iSessionTabId = sessionStorage.getItem(\"onlyOneTabId\");\n    if (iSessionTabId == null) {\n        iSessionTabId = Math.floor(Math.random() * 1000000);\n        sessionStorage.setItem(\"onlyOneTabId\", iSessionTabId);\n    } \n    console.log(\"iSessionTabId: \" + sessionStorage.getItem(\"onlyOneTabId\"));\n}<\/code><\/pre>\n\n\n\n<p>Des Weiteren wird diese Nummer an den Server \u00fcber ein Remote Command \u00fcbermittelt (in onload der Seite). Wenn f\u00fcr die Sitzung noch kein Tab \u00fcbergeben wurde, wird die Nummer gespeichert und der Request ist OK. Entspricht die Nummer der aktuellen Nummer ist der Request ebenfalls. Nur bei Abweichungen wird \u00fcber einen Redirect zu einer Fehlerseite gesprungen. F\u00fcr das Schlie\u00dfen von Fenstern wird eine JavaScript Funktion registriert (window.addEventListener(&#8218;beforeunload&#8216; \u2026) die wiederum ein Remote Command aufruft, das der Serversitzung mitteilt, dass der Tab geschlossen wurde.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>window.addEventListener('beforeunload', function () {    \n    call the remote command here\n    \/\/ Cancel the event\n    \/\/ e.preventDefault(); \/\/ If you prevent default behavior in Mozilla Firefox prompt will always be shown\n    \/\/ kein return value, sonst zeigt Chrome immer ein PupUp\n    \/\/ e.returnValue = null;\n});<\/code><\/pre>\n\n\n\n<p>Das Schlie\u00dfen wird \u00fcber ein Remote Command, das den Status im Server \u00e4ndert, gesendet. Ist das geschlossen Flag auf dem Server f\u00fcr die Sitzung gesetzt, wird der n\u00e4chste Request ohne Vergleich der Nummer zugelassen. Bei einem normalen Seitenwechsel, ist der Folgerequest im selben Tab und somit bleibt die ID unver\u00e4ndert. Wenn der Nutzer aber den Tab schlie\u00dft und in einem zweiten Tab des gleichen Browser die Anwendung wieder startet, wird eine Nummer generiert. Somit wird das vom Nutzer erwartete Verhalten beim Schlie\u00dfen eines Tabs realisiert.<\/p>\n\n\n\n<p>Anmerkung: Seit 2023 sollte man besser eine L\u00f6sung mit @ClientWindowScoped aus Jakarta 10 JF anstreben.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Nur ein Tab \/ Browser in einer Server Sitzung Ein h\u00e4ufiges Problem in webbasierten Serveranwendungen ist es, dass nicht gekl\u00e4rt werden kann, ob der Nutzer mehrere Tabs ge\u00f6ffnet hat und ggf. die Sitzungsdaten eines Vorgangs mit mehreren Tabs gleichzeitig ver\u00e4ndert. Beim Zugriff von verschiedenen Browsern oder im privaten Fenster sind die Sitzungen auf dem Server [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4],"tags":[],"class_list":["post-175","post","type-post","status-publish","format-standard","hentry","category-jee"],"_links":{"self":[{"href":"https:\/\/www.schoenberg-solutions.de\/arndtblog\/index.php?rest_route=\/wp\/v2\/posts\/175","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.schoenberg-solutions.de\/arndtblog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.schoenberg-solutions.de\/arndtblog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.schoenberg-solutions.de\/arndtblog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.schoenberg-solutions.de\/arndtblog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=175"}],"version-history":[{"count":3,"href":"https:\/\/www.schoenberg-solutions.de\/arndtblog\/index.php?rest_route=\/wp\/v2\/posts\/175\/revisions"}],"predecessor-version":[{"id":198,"href":"https:\/\/www.schoenberg-solutions.de\/arndtblog\/index.php?rest_route=\/wp\/v2\/posts\/175\/revisions\/198"}],"wp:attachment":[{"href":"https:\/\/www.schoenberg-solutions.de\/arndtblog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=175"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.schoenberg-solutions.de\/arndtblog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=175"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.schoenberg-solutions.de\/arndtblog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=175"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}