# Richtiges Session Management mit Servlets



## Flot (21. Jan 2011)

Hallo,

ich habe eine Frage bezüglich des Session Management mit Servlets.

Innerhalb der Servlet Klasse ist es ja kein Problem die aktuelle Session zu bekommen.
Mit this.getThreadLocalRequest().getSession() erhält man wie erwartet seine Session.

Wie soll ich aber die Session innerhalb von anderen Klassen bekommen, ohne die Session durch alle Funktionen durchschleifen zu müssen?


```
public class GreetingServiceImpl extends RemoteServiceServlet{
     private ChatraumManager chatManager;
    
     public GreetingServiceImpl(){
		chatManager = new ChatraumManager();
     }
     //Derzeitige implementierung
     public void sendMsg(int raum_id, String nachricht) {
           String absender = this.getThreadLocalRequest().getSession().getId();
           chatManager.sendMsg(absender,raum_id, nachricht);
     }
     //Gewünschte Implementierung
     public void sendMsg(int raum_id, String nachricht) {
		chatManager.sendMsg(raum_id, nachricht);
     }
}
```
Es sollte sich in diesem Fall der ChatraumManager um das Setzen des Absenders kümmern und nicht das Servlet.
Meine Idee war es eine static CurrentUser Klasse zu schreiben, aber das funktioniert ja nicht, weil sich alle requests die selben Variablen teilen.

Um das ganze zu umschiffen würde mir nur noch eine Hash map mit Thread id und session einfallen,

ist aber meiner Meinung nach auch keine schöne Lösung, da ich dann in in jeder remoteService Funktion die eigene initSession() aufrufen müsste.

Bin für alle Tipps dankbar


----------



## Noctarius (21. Jan 2011)

Was stört dich daran die Session oder den Request durchzuschieben?


----------



## Flot (21. Jan 2011)

Ich müsste ja bei *jeder *Funktion die ich dann schreibe auch die Session übergeben.

Das kann ja irgend wie nicht schön sein, und wenn ich es nur bei den nötigen mache,

kann später keiner etwas erweitern, da man dann doch wieder die Userinformation braucht.

Oder ist es üblich, dass ich im ganzen Funktionsstack dahinter eine Variable mit ziehe?
Sachimpfwortfilter, Spamfilter, usw.


----------



## Noctarius (21. Jan 2011)

Alternativ ginge nur jedesmal eine eigene Instanz der Klasse mit der Business-Funktion zu instanzieren (bzw diese in einem ThreadLocal zu halten). Spontan wüsste ich sonst keinen Weg.


----------



## Flot (22. Jan 2011)

Hier mal meine Lösung, die an den jeweiligen Thread gebunden ist.

Das Servlet:

```
public class GreetingServiceImpl extends RemoteServiceServlet{
     private ChatraumManager chatManager;
    
     public GreetingServiceImpl(){
        chatManager = new ChatraumManager();
     }
     //Gewünschte Implementierung
     public void sendMsg(int raum_id, String nachricht) {
        initSession();
        chatManager.sendMsg(raum_id, nachricht);
     }
     private void initSession(){
	   MySessionHandler.initSession(this.perThreadRequest.get().getSession());
     }
}
```
Der Sessionhandler: Geändert: 22.01.2011 18:15

```
public class MySessionHandler {
	private static HashMap<Thread,HttpSession> sessions = new HashMap<Thread,HttpSession>();
	
	public synchronized static void initSession(HttpSession session){
		//Entfernen der toten Threads
		//notify wäre besser
		for(Thread t:sessions.keySet()){
			if(!t.isAlive()){
				sessions.remove(t);
			}
		}
    	MySessionHandler.sessions.put(Thread.currentThread(), session);
    }
	public synchronized static HttpSession getCurrentSession(){
    	return sessions.get(Thread.currentThread());
    }
}
```

Mit dieser Lösung kann man jetzt von überall aus MySessionHandler.getCurrentSession() aufrufen,
dafür muss man jetzt aber bei jeder RPC funktion initSession() aufrufen.

aber ca. 20x initSession() sollte ja noch immer besser sein als 200x die Session durch reichen zu müssen.

Muss jetzt nur noch herausfinden, wie ich threads richtig aus der Liste entferne, wenn sie fertig sind.

Und immer eigene Instanzen zu Instanzieren funktioniert auch nicht, da der ChatraumManager ja alle Chaträume kennen muss, um den andern Usern die Nachricht übermitteln zu können.

Spricht sonst noch etwas gegen meine Lösung, bzw. gibt es das wirklich nicht schon vorgefertigt?


----------

