Vermeiden von multiplen Threads bei refresh

aldi15

Grünschnabel
Hallo miteinander,
ich habe folgendes Problem: in einer JSP-Seite deklariere (und initialisiere) ich eine sessionweite Variable auf die ich auch von anderen JSPs aus Zugriff habe mit: session.setAttribute("MyClient", new ClientMainClass(SessionID));
Wenn ich nun irgendeine Aktion starte wie zB. ein Formular auslesen (request abschicken) etc. wird die ganze Seite refreshed. Damit wird leider diese Anweisung neu ausgeführt und ein neues Objekt erzeugt. Dies führt zu multiplen Objekten und damit zu multiplen Threads, die sich im Laufe der Anwendung gegenseitig in die Quere kommen (lesen und schreiben eine Datei gleichzeitig). In einem normalen Javaprogramm hätte ich die Variable wahrscheinlich als final deklariert, dann wäre es egal, wie oft der Code ausgeführt wird, aber hier? Wie kann ich es schaffen, daß beim Starten einer neuen Session nur einmal ein Objekt erzeugt wird und danach nicht mehr (auch nicht bei einem refresh)?
Danke und bis dann
Albrecht
 
Du bringst da einiges durcheinander: Erstens, final sorgt nicht dafür, dass ein objekt nur einmal erzeugt wird. Zweitens, Objekte erzeuge würde ich vorrangig in einem Servlet, nicht in der JSP (schlechter Stil). Was spricht dagegen in der Session nachzuschauen ob ein objekt da ist und nur ein neues zu erzeugen wenn das nicht der Fall ist?

Gruß
Ollie
 
Hallo Ollie,
tja, hmmm, es mag vielleicht schlechter Stil sein, aber ich wüsste nicht, wie ich das sonst machen sollte! Die JSP-Seite ist ja die Startseite, auf die der user kommt (View). Von da aus wird die Anwendungslogik gestartet. D.h. ich muss hier ein Objekt der Klasse (ich nutze kein Servlet sonder eine normale Java-Klasse), erzeugen, die die Nutzerinformationen verarbeitet. Wie soll das sonst gehen?
Inzwischen habe ich das auch schon hinbekommen, indem ich vorher tatsächlich das Objekt im Servlet abfrage:
Code:
if(session.getAttribute("MyClient")==null){
        session.setAttribute("MyClient", new ClientMainClass(SessionID));}
Ich dachte nicht, dass das geht, da ich ja quasi mit session.setAttribute gleichzeitig eine Deklaration und Initialisierung mache und ich mir nicht vorstellen konnte, dass man den Status eines Objekts abfragen kann, bevor man es überhaupt angelegt hat (Müsste Laufzeitfehler geben). Aber in JSP schent das zu gehen.
Danke
Albrecht
 
Hi Albrecht,

wieso soll das nicht gehen ? Die Attribute der Session werden auch nur in einer Map gespeichert. Es wird also kein Object in dem Sinne angelegt oder ein Status abgefragt. Gibt es den Key nicht, liefert die Methode null zurück.

Hättest du eine eigene Map und greifst genau so darauf zu --> map.get("MyClient") , kommst du zu dem gleichen Verhalten.

Gruß KK
 
Nur dass du nicht weißt, wie anders geht, heißt es ja noch lang nicht, dass es nicht anders geht. ;) Die meisten Webandwendungen machen auf der index.jsp einfach nur einen redirect auf eine URL hinter der dann die eigentliche Seite liegt, die zum Anfang angezeigt werden soll. Da kann ein Servlet dann natürlich leicht eingreifen.

Warum sollte man das nicht so tun, wie du es tust? Weil du damit das Separation of Concerns Paradigma verletzt und du, solltest du diesen Programmierstil im Übermaß praktizieren, sehr schnell zu völlig unwartbaren JSPs kommst. Bei einer Seite und einem kleinen Skriplet mag das nicht schlimm aussehen, aber lass das mal ein Stück größer werden.

Es schreibt dir ja auch keiner vor, wie du was zu machen hast. Solang du damit zurecht kommst - prima. Ich weise lediglich auf die Gefahren hin, die sich meiner Erfahrung nach aus solchen Ansätzen ergeben.

Wie karatekid schon geschrieben hat sind die Attribute der Session eine einfache map. Das Sessionobjekt selbst gibt es immer, dafür sorgt der Container. Du prüfst in der if-Bedingung ja nur, ob unter einem bestimmten Schlüssel ein bestimmter wert abgelegt ist. Und Map gibt halt null zurück, wenn der Schlüssel nicht existiert.

Was du allerdings hier nicht prüfst, ist, ob evtl schon ein Objekt von einem anderen Typ abgelegt sind. Schreibt irgendjemand aus versehen einen String in "MyClient", greift die Bedingung nicht und du hast irgendwas falsches in der property stehen. Ungünstig...

Gruß
Ollie
 
OK, ich verstehe. Tatsächlich könnte dieser "irgendjemand" ja nur ich selbst sein, aber ich verstehe natürlich deine Intention. Wenn mehrere am selben Projekt arbeiten, sollte man sich natürlich an die Konventionen halten, da es sonst eben zu den von dir beschriebenen Fehlern kommen kann.
Danke für die ausführliche Darstellung
Albrecht
 

Neue Beiträge

Zurück