2014-06-20 16 views
5

Pracuję nad aplikacją webową Java, w której muszę uzyskać dostęp do rekordów z bazy danych na podstawie identyfikatora logowania użytkownika. Ustawiam dane logowania w zmiennej sesji po pomyślnym zalogowaniu.Uzyskiwanie dostępu do zmiennych sesji poza serwletem

chcę zrobić coś jak ten

select * from proj_recs gdzie user_id = user_id (od sesji)

Teraz jestem przechodzącej użytkownika jako parametr, ale wierzę, że to nie jest dobry ćwiczyć. Czy istnieje lepszy sposób dostępu do zmiennych sesji poza serwletem?

Servlet

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; 
     } 
} 

W opakowaniu warstwa danych

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

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

} 

problem jest muszę modyfikować wszystkie moje metod z identyfikatora. Czy istnieje sposób, w jaki mogę ustawić dane użytkownika w jakiejś klasie statycznej i uzyskać dostęp do szczegółów tam, gdzie chcę w aplikacji bez modyfikowania sygnatury metody? Uważam jednak, że klasy statyczne są współdzielone między różnymi żądaniami użytkowników.

+0

Gdzie chcesz uzyskać dostęp do zmiennych sesji? U klienta? JSP? – fajarkoe

+0

Czy możesz opracować za pomocą próbki kodu? –

+0

W warstwie danych aplikacji – SRK

Odpowiedz

2

Rozwiązaniem, którego szukasz, jest Thread Local (google it). Umożliwia dostęp do danych specyficznych dla wątków za pomocą metody statycznej.

Możesz rozpocząć czytanie http://veerasundar.com/blog/2010/11/java-thread-local-how-to-use-and-code-sample/.Korzystanie z przykładów stamtąd, trzeba utworzyć:

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(); 
    } 
} 

w swoim serwletu, to zrobić:

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(); 
    } 
} 

w warstwie danych, można odzyskać użytkownika wykonując to:

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

Należy zauważyć, że nie trzeba zmieniać sygnatury metody warstwy danych.

Wątek Lokalny jest początkowo nieco mylący, ale szybko zapoznasz się z artykułem.

0

Zawsze można uzyskać identyfikator użytkownika z sesji wewnątrz serwletu i przekazać go do warstwy danych, nie ma sensu używanie sesji bezpośrednio w warstwie danych. Wyodrębniasz swoje obiekty i przekazujesz je do następnej warstwy. Używanie specyficznych obiektów HTTP w warstwie danych jest naprawdę złą praktyką.

0

Przy ścisłym rozdzielaniu obaw warstwa danych nie powinna mieć nic wspólnego z sesją lub żądaniem. Ale potrzebujesz nazwy użytkownika (user_id od ciebie przykład) w warstwie usługi lub danych. Najprostszym sposobem jest zbieranie go w kontrolerze (kontroler ma dostęp do żądania i sesji), przekazywanie go do warstwy usługi i przekazywanie do warstwy danych.

Alternatywą (używaną przez architekturę bezpieczeństwa, taką jak Spring Security lub Apache Shiro), jest przechowywanie jej w pamięci wątków na początku przetwarzania żądania i ostrożne czyszczenie go na końcu (w filtrze). Następnie statyczna metoda klasy narzędziowej może dać ją dowolnej części aplikacji. Ale dostajesz zależność od frameworka za każdym razem, gdy używasz klasy narzędziowej. Aby zmniejszyć niepotrzebne zależności, możesz mieć własną klasę Holder, statyczną metodą, która wywołuje jedną z ram: zależność jest ograniczona do klasy posiadacza.

Istnieje trzecie rozwiązanie, jeśli używasz Spring. Możesz mieć komponent o zasięgu z sesją, z pośrednikiem, który możesz wstrzyknąć w dowolny komponent bean, który potrzebuje dostępu do zmiennej. Dzięki aop proxying będziesz miał dostęp do danych z bieżącej sesji, nawet z pojedynczego komponentu bean.

W swoich własnych aplikacjach używam pierwszej metody w prostych przypadkach (kilka klas) i trzeciej metody, gdy chcę uniknąć powtarzania tych samych parametrów na wielu metodach.

1

Myślę, że u można łatwo używać

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

więc nie ma potrzeby, aby zmienić podpis. W ten sposób możesz użyć wbudowanego narzędzia Shiros zamiast polegać na własnych logikach i probabiliach.

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; 

} 
Powiązane problemy