2014-06-20 22 views
5

Sto lavorando a una webapp java in cui ho bisogno di accedere ai record dal database in base all'ID di accesso dell'utente. Impostare i dettagli di accesso nella variabile di sessione dopo il login riuscito.Accesso alle variabili di sessione al di fuori del servlet

che voglio fare è qualcosa di simile

Select * from proj_recs dove user_id = id_utente (dalla sessione)

In questo momento sto passando nome utente come parametro, ma credo che non è una buona pratica. Esiste un modo migliore per accedere alle variabili di sessione al di fuori del servlet?

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

Nel pacchetto dati strato

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

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

} 

Il problema è che ho di modificare tutti i miei metodi con userid. C'è un modo per impostare i dettagli utente in qualche classe statica e accedere ai dettagli dove voglio nell'applicazione senza modificare la firma del metodo? Ma credo che le classi statiche siano condivise tra le diverse richieste degli utenti.

+0

Dove si desidera accedere alle variabili di sessione? Al cliente? JSP? – fajarkoe

+0

Potresti elaborare usando un esempio di codice? –

+0

Nel livello dati dell'applicazione – SRK

risposta

2

La soluzione che stai cercando è Thread Local (google it). Ti consente di accedere ai dati specifici del thread utilizzando il metodo statico.

È possibile iniziare a leggere http://veerasundar.com/blog/2010/11/java-thread-local-how-to-use-and-code-sample/.Utilizzando esempi da lì, è necessario creare:

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

nel vostro servlet, fare questo:

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

nel vostro livello di dati, è possibile recuperare l'utente in questo modo:

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

Si noti che non è necessario modificare la firma del metodo del livello dati.

Thread Local è un po 'confuso all'inizio, ma ti sarà familiare molto rapidamente una volta letto l'articolo.

0

È sempre possibile ottenere l'ID utente dalla sessione all'interno del servlet e passarlo al livello dati, non è possibile utilizzare la sessione direttamente nel livello dati. Estrai i tuoi oggetti e passa il dollaro al livello successivo. L'utilizzo di oggetti specifici HTTP nel livello dati è in realtà una cattiva pratica.

0

Con una rigorosa separazione delle preoccupazioni, il livello dati non dovrebbe avere nulla a che fare con la sessione o la richiesta. Ma è necessario il nome utente (user_id dell'esempio) in servizio o livello dati. Il più semplice è effettivamente raccoglierlo nel controller (il controllore ha accesso a richiesta e sessione), passarlo al livello di servizio e inoltrarlo al livello dati.

Un'alternativa (utilizzata da framework di sicurezza come Spring Security o Apache Shiro) è quella di archiviarla nella memoria thread all'inizio del trattamento della richiesta e pulirla accuratamente alla fine (in un filtro). Quindi un metodo statico di una classe di utilità può darlo a qualsiasi parte della tua applicazione. Ma si ottiene una dipendenza dal framework ogni volta che si utilizza la classe di utilità. Per ridurre le dipendenze non necessarie, è possibile avere una propria classe Holder, con un metodo statico che chiama quello del framework: la dipendenza è limitata alla classe del titolare.

C'è una terza soluzione se usi Spring. Puoi avere un bean con scope di sessione, con proxy aop, che puoi iniettare in qualsiasi bean che ha bisogno di accedere alla tua variabile. Grazie al proxy aop potrai accedere ai dati dalla sessione corrente, anche da un bean singleton.

Nelle mie app, utilizzo il primo metodo in casi semplici (poche classi) e il terzo metodo quando voglio evitare di ripetere più volte gli stessi parametri in molti metodi.

1

penso che la u può usare facilmente

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

quindi nessun bisogno di cambiare la firma. In questo modo è possibile utilizzare l'utilità incorporata di shiros anziché affidarsi alle proprie logiche e alle proprie probabilità.

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; 

} 
Problemi correlati