JSR 168 Portlet SessionTimeout hinauszögern

The_S

Top Contributor
Guten Morgen zusammen,

ich habe ein JSR 168 Portlet. Dieses Portlet wird von externen Kunden verwendet. In diesem Portlet werden ohne Submit sehr, sehr, sehr viele Daten eingegeben. Würde man vom Kunden zwischendurch ein Submit verlangen, würde das seinen Arbeitsfluss sehr beeinträchtigen. Deshalb muss das auch so bleiben. Problem ist nun, dass auf diesem (WebSphere) Portal-Server ein SessionTimeout von 2 Stunden eingerichtet ist, der auch nicht verändert werden darf (auf dem Server laufen natürlich noch andere Anwendungen). Die Zeit, bis der User alles fertig eingegeben hat, übersteigt die 2 Stunden aber locker, was natürlich zu Problemen mit dem Timeout führt. Ich würde dem Server deshalb gerne bspw. alle 10 Minuten via JS im Hintergrund Bescheid geben "Hey, der User arbeitet noch, und hier hast du schon mal die Daten, die er bis jetzt eingegeben hat. Setz doch bitte den SessionTimeout zurück. Danke!". Habe mir auch schon meine Gedanken dazu gemacht, bin aber noch nicht wirklich auf eine saubere Lösung gestoßen. Deshalb hoffe ich an dieser Stelle auf Tipps von euch :) .

Danke!
 

F.S.WhiTeY

Bekanntes Mitglied
Moin,

ich hatte mir darüber auch schon mal meine Gedanken gemacht. Ich hatte auch eine Idee, weiss nur nicht ob sie Praktikabel ist und sich so umsetzen lässt.

Ich wollte die Sessiondaten einfach Persistieren. Nicht das die Session an sich Persistent sein sollte, nur die Daten die nicht verloren gehen sollten. Dann könnte der User nachdem er sich wieder eingeloggt hat da weiter machen wo er aufgehört hat. Eine zwischengeschobene seite Könnte den User dann sogar wieder auf die View zurückschieben auf der er Aufgehört hat.

Es gibt ja, zumindest bei Spring Security, eine Exception wenn die Session abgelaufen ist. Sowas in der Art wie
Code:
ViewExperiedException
. Wenn man die Catchen könnte und im
Code:
finally
die persistierung durchführt könnte das klappen.

Damit hat man Idelnden Usern schon mal geholfen.

Angafangen etwas in der Art umzusetzen habe ich noch nicht und ich kann auch nur auf mein J2EE wissen zurückgreifen. Die eigenheiten von Portlets und WebSphere kenn ich leider garnicht ;)
Daher kenn ich den Aufbau der Session auch nicht. Ich hab mal ein wenig gegoogled und gelesen, steige aber durch den Aufbau des Sessionservices noch nicht ganz durch ( nicht verwundelich nach nur 10 Minuten).

Da du dich damit Sicherlich auskennen wirst, möchte ich deinen "Push" ansatz noch ein wenig verfolgen und auf die JS lösung eingehen ohne den Hintergrund des restlichen Aufbaues dabei zu verfolgen.

Ich denke das ich da recht spartanisch ran gehen würde. Der 10 Minutenansatz verträgt sich Meiner Meinung nach nicht mit dem Idele-Prinziep, daher würde ich endweder bei jeder Eingabe oder bei jeder Xten Eingabe ein
Code:
ValueChangeEvent
schmeißen und im ActionListener dann die Session "resetten".
Das erzeugt natürlich ein paar Requests mehr und sorgt damit für einen gewissen "Overhead". Ob dieser zu vernachlässigen ist kann ich nicht sagen, das musst du dir beantworten.

Zusammen mit dem Idle-Ansatz hättest du dann eine Komplettlösung. Das sind natürlich alles nur Ideen und ich hoffe du kannst dir einen Teilansatz aus diesem Post ziehen.

Eine Anmerkung habe ich allerdings noch. Wenn der User sehr lange, sehr viel eingibt und du zwischendurch schon "persistierst" wie sind dann eventuell nachträglich erfolgende Änderungen zu behandeln?


LG

David
 

The_S

Top Contributor
Danke für deine Antwort!

Ich wollte die Sessiondaten einfach Persistieren. Nicht das die Session an sich Persistent sein sollte, nur die Daten die nicht verloren gehen sollten. Dann könnte der User nachdem er sich wieder eingeloggt hat da weiter machen wo er aufgehört hat. Eine zwischengeschobene seite Könnte den User dann sogar wieder auf die View zurückschieben auf der er Aufgehört hat.

Es gibt ja, zumindest bei Spring Security, eine Exception wenn die Session abgelaufen ist. Sowas in der Art wie
Code:
ViewExperiedException
. Wenn man die Catchen könnte und im
Code:
finally
die persistierung durchführt könnte das klappen.

Hm, habe mich damit noch nicht beschäftigt, aber ich wüsste jetzt spontan nicht, wie ich auf das Ablaufen der Portal Session reagieren könnte. Evtl. mit nem HTTPSessionListener, aber das müsste ich mal genauer untersuchen.

Ich denke das ich da recht spartanisch ran gehen würde. Der 10 Minutenansatz verträgt sich Meiner Meinung nach nicht mit dem Idele-Prinziep, daher würde ich endweder bei jeder Eingabe oder bei jeder Xten Eingabe ein ValueChangeEvent schmeißen und im ActionListener dann die Session "resetten".
Das erzeugt natürlich ein paar Requests mehr und sorgt damit für einen gewissen "Overhead". Ob dieser zu vernachlässigen ist kann ich nicht sagen, das musst du dir beantworten.

Also konkret geht es darum, dass der Kunde zig Tausend Lieferscheine einscannt. Er hat einen Stapel Lieferscheine vor sich liegen und zieht einen nach dem anderen durch den Scanner. Der Scanner schreibt die Lieferscheinnummer dann automatisch mit Zeilenumbruch in ein Textfeld. Für einen Lieferschein braucht er ca. eine Sekunde. Da ist ein Wegschreiben nach jedem neuen Scannvorgang einfach nur sehr schwer möglich. Deshalb die größere Menge nach bspw. 10 Minuten.

Generell geht es mir vor allem um die Frage nach dem besten Weg, wie die Daten asynchron an das Portlet geschickt werden und der SessionTimeout verhindert wird. Das heißt ich suche nach konkreten Vorschlägen und nicht allgemeinen Ansätzen. Aber trotzdem vielen Dank für deine Hilfe, auch wenn du mit Portlets noch nichts zu tun hattest :).

Eine Anmerkung habe ich allerdings noch. Wenn der User sehr lange, sehr viel eingibt und du zwischendurch schon "persistierst" wie sind dann eventuell nachträglich erfolgende Änderungen zu behandeln?

Änderungsmöglichkeiten gibts keine. Der User scannt ein und der aktuelle Lieferschein wird via JavaScript in einem separaten, nicht editierbaren Bereich geschrieben. Aber das konntest du ohne den konkreten Anwendungsfall ja nicht wissen.
 

F.S.WhiTeY

Bekanntes Mitglied
Ok nun wird es wirklich deutlicher :D

Ich muss noch mal ein wenig grübeln aber eine Sache kann ich dir schon mal vor die Füße schmeißen:

HTML:
setInterval(function()
           {    
            
            $.ajax({
               //Mit ajax aufrufen was immer du magst
             })
            }, 3000); //3000ms 
        });
 

The_S

Top Contributor
Ok nun wird es wirklich deutlicher :D

Ich muss noch mal ein wenig grübeln aber eine Sache kann ich dir schon mal vor die Füße schmeißen:

HTML:
setInterval(function()
           {    
            
            $.ajax({
               //Mit ajax aufrufen was immer du magst
             })
            }, 3000); //3000ms 
        });

Und wieder was gefunden, ich hoffe ich Spame dich nun nicht mit unnützem Zeug voll aber mich interessiert das Problem im allgemeinen ja auch ;)

Session Timeout und Heartbeat Ralph's Blog

Wäre das was ?

Nö, du spamst nicht. Ich freue mich über jegliche Hilfe :) . Das Problem ist bei mir weniger der JavaScript-Teil (also das asynchrone und wiederholte Aufrufen), sondern vielmehr wie ich am Saubersten die Daten zum Portlet transferiere und damit als positiven Nebeneffekt den Timeout zurücksetze. Natürlich könnte ich mir einfach die renderURL bzw. actionURL des Portlets generieren lassen und mit einem XMLHttpRequest-Objekt abschicken. Aber zum einen erscheint mir das unsauber, und zum anderen funktioniert der Quick-And-Dirty Proof of Concept zwar bestens im Chrome, der IE beschwert sich aber, dass er die URL nicht finden konnte. Total banane :p . Sorry, falls das nicht so eindeutig rübergekommen ist.
 

F.S.WhiTeY

Bekanntes Mitglied
Moin,

ich verstehe zwar was dein Problem ist aber ich denke nicht das ich mich so schnell einlesen kann :D

Ich bin zwar nicht ohne Wissen um EJB und JSP aber ich hab beim lesen in den letzten Tagen schon gemerkt das Portlets da so ihre Eigenheiten haben.
Wenn du so ein Problem mit Spring oder JSF hättest wäre ich sofort in der Lage gewehsen dir eine Lösung vorzuschlagen. Allerdings muss ich hier dann abwinken. Mir fehlt einfach die Zeit mich da nun so rein zu arbeiten. Außerdem bist du wahrscheinlich schon fertig befor ich den Stand habe da anzusetzen ;)

Zumal du ja unter JSR 168 arbeitest und ich eigentlich nur mit aktuelleren dingen vertraut bin (Eher JSR 286 mit EJB 3.x)

Mich würde deine Lösung allerdings schon interessieren. Wäre nett, wenn du mal ein schnippsel Code hier lassen könntest? Mich würde einfach interessieren wie das in der Technologie aussehen würde um mir mal die Unterschiede zu verdeutlichen. JSF macht es einem da ja sehr einfach :)

LG
 

The_S

Top Contributor
Ja, kein Problem. Danke dass du dir bis dahin Zeit genommen hast. Prinzipiell kann man sich über die Portlet-Tags wie
Java:
<portlet:renderURL />
die request-URLs generieren lassen und diese dann via Ajax aufrufen. Eine wirklich schöne Lösung habe ich aber wie gesagt noch nicht. Kann auch sein, dass sich das demnächst erledigt und wir für diese Anwendung eine andere Technologie verwenden. Also keine Garantie, dass hier eine Lösung von mir gepostet wird ;) .
 

Ähnliche Java Themen

Neue Themen


Oben