2014-06-20 17 views
5

Ich arbeite an einer Java-Webanwendung, in der ich basierend auf der Benutzeranmelde-ID auf Datensätze aus der Datenbank zugreifen muss. Nach erfolgreicher Anmeldung habe ich die Anmeldedaten in der Sitzungsvariablen festgelegt.Zugriff auf Sitzungsvariablen außerhalb des Servlets

ich tun möchte, ist so etwas wie dieses

Select * from proj_recs wo user_id = Benutzer-ID (von Sitzung)

Im Moment ist Benutzername als Parameter bin vorbei, aber ich glaube, es ist nicht gut trainieren. Gibt es eine bessere Möglichkeit, auf Sitzungsvariablen außerhalb von Servlets zuzugreifen?

Servlets

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 
     // TODO Auto-generated method stub 

     User user = (User) request.getSession().getAttribute("userInfo"); 

     System.out.println(user); 

     if(user != null){ 
      Gson gson = new Gson(); 
      returnJsonResponse(response,gson.toJson(user)); 
      return; 
     } 
} 

In der Datenschichtpaket

public Accrual getAccruals(String accrualID,String userid) throws AccrualNotFoundException{ 

    String sql = Select * from db_acc where acc_id= accrualID and user_id=userid; 

} 

Das Problem ist, ich habe alle mit userid meine Methoden zu ändern. Gibt es eine Möglichkeit, Benutzerdetails in eine statische Klasse zu setzen und auf die Details zuzugreifen, wo immer ich in der Anwendung möchte, ohne die Methodensignatur zu ändern? Aber ich glaube, dass statische Klassen zwischen verschiedenen Benutzeranforderungen geteilt werden.

+0

Wo möchten Sie auf die Sitzungsvariablen zugreifen? Beim Kunden? JSP? – fajarkoe

+0

Können Sie mit einem Codebeispiel arbeiten? –

+0

In der Datenschicht der Anwendung – SRK

Antwort

2

Die Lösung, nach der Sie suchen, ist Thread Local (google it). Es ermöglicht den Zugriff auf Thread-spezifische Daten mit der statischen Methode.

Sie können lesen http://veerasundar.com/blog/2010/11/java-thread-local-how-to-use-and-code-sample/.Anhand von Beispielen aus dort, müssen Sie erstellen:

public class MyThreadLocal { 

    public static final ThreadLocal userThreadLocal = new ThreadLocal(); 

    public static void set(User user) { 
     userThreadLocal.set(user); 
    } 

    public static void unset() { 
     userThreadLocal.remove(); 
    } 

    public static User get() { 
     return userThreadLocal.get(); 
    } 
} 

in Servlets, dies tun:

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 
    User user = (User) request.getSession().getAttribute("userInfo"); 
    MyThreadLocal.set(user); 
    try { 
     // call data layer 
    } finally { 
     MyThreadLocal.unset(); 
    } 
} 

in Ihrer Datenschicht, können Sie den Benutzer abrufen, indem Sie diese:

public void dataLayerMethod(ExistingParameters parameters) { 
    User user = MyThreadLocal.get(); 
} 

Beachten Sie, dass Sie die Methodensignatur der Datenschicht nicht ändern müssen.

Thread Local ist zunächst etwas verwirrend, aber Sie werden sich sehr schnell vertraut machen, wenn Sie den Artikel gelesen haben.

0

Sie können immer die Benutzer-ID aus der Sitzung innerhalb des Servlets abrufen und diese an Ihre Datenschicht übergeben. Es ist sinnlos, die Sitzung direkt in der Datenschicht zu verwenden. Sie extrahieren Ihre Objekte und übergeben den Buck an die nächste Ebene. Die Verwendung von HTTP-spezifischen Objekten in der Datenschicht ist eigentlich eine schlechte Methode.

0

Bei strikter Trennung von Bedenken sollte die Datenschicht nichts mit der Sitzung oder Anfrage zu tun haben. Aber Sie benötigen den Benutzernamen (user_id von Ihrem Beispiel) in Service-oder Datenschicht. Am einfachsten ist es, es effektiv im Controller zu sammeln (Controller hat Zugriff auf Anfrage und Sitzung), es an die Service-Schicht weiterzuleiten und an die Datenschicht weiterzuleiten.

Eine Alternative (die von Sicherheits-Framework wie Spring Security oder Apache Shiro verwendet wird) besteht darin, sie zu Beginn der Anforderungsbehandlung im Thread-Speicher zu speichern und am Ende (in einem Filter) sorgfältig zu säubern. Dann kann eine statische Methode einer Dienstprogrammklasse sie an jeden Teil Ihrer Anwendung übergeben. Sie erhalten jedoch bei jeder Verwendung der Dienstprogrammklasse eine Abhängigkeit vom Framework. Um unnötige Abhängigkeiten zu reduzieren, können Sie Ihre eigene Holder-Klasse mit einer statischen Methode verwenden, die das Framework aufruft: Die Abhängigkeit ist auf die Inhaberklasse beschränkt.

Es gibt eine dritte Lösung, wenn Sie Spring verwenden. Sie können eine Session-Bean mit einem Proxy-Proxy einrichten, die Sie in jede Bean injizieren können, die Zugriff auf Ihre Variable benötigt. Dank AOP-Proxying haben Sie Zugriff auf die Daten der aktuellen Sitzung, sogar von einer Singleton-Bean.

In meinen eigenen Anwendungen verwende ich die erste Methode in einfachen Fällen (wenige Klassen) und die dritte Methode, wenn ich vermeiden möchte, immer wieder dieselben Parameter in vielen Methoden zu wiederholen.

1

Ich denke, u leicht

SecurityUtils.getSubject().getSession().getAttribute("userInfo");

so dass keine Notwendigkeit zu ändern Signatur verwenden können. Auf diese Weise können Sie shiros integriertes Dienstprogramm verwenden, anstatt sich auf Ihre eigenen Logiken und Wahrscheinlichkeiten zu verlassen.

public Accrual getAccruals(String accrualID) throws AccrualNotFoundException{ 
    User user = (User) SecurityUtils.getSubject().getSession().getAttribute("userInfo"); 
    String userid= user.getUserId(); 
    String sql = Select * from db_acc where acc_id= accrualID and user_id=userid; 

} 
Verwandte Themen