IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Servlets/JSP Java Discussion :

ThreadLocal devient null dans mon application Web


Sujet :

Servlets/JSP Java

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    62
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 62
    Par défaut ThreadLocal devient null dans mon application Web
    Bonjour à tous, je développe une application Web s'appuyant les frameworks Hibernate, Acegi et Icefaces...

    J'utilise bien sur un système de logging pour s'authentifier...
    Hors j'ai besoin dans mon application de STOCKER l'object User qui s'est loggué.
    C'est pourquoi j'ai crée une classe :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    public class ThreadLocalUser {
    	    private static final ThreadLocal<User>  name = new ThreadLocal<User> ();
    		private static final ThreadLocal<LdapUserDetails> userDetailz = new ThreadLocal<LdapUserDetails>();
     
     
    	    private ThreadLocalUser() {
    	    }
     
    	    public static User getUser() {
    	        return (User) name.get();
    	    }
     
    	    public static void setUser(User user) {
    	        ThreadLocalUser.name.set(user);
    	    }
     
    	    public static LdapUserDetails getDetails() {
    	        return (LdapUserDetails) userDetailz.get();
    	    }
     
    	    public static void setDetails(LdapUserDetails details) {
    	        ThreadLocalUser.userDetailz.set(details);
    	    }
    	}
    J'initialise le ThreadLocal au moment de se logguer sans problème...

    Mais ensuite lorsque, l'application se charge ou lorsque je navigue dedans soudainement le ThreadLocal devient null et je n'ai plus accès au User...
    Quelqu'un pourrait-il m'éclairer??

  2. #2
    Membre chevronné
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    442
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 442
    Par défaut
    Un ThreadLocal n'est propagé que le long d'un seul Thread principal. Lorsque le Thread principal termine son exécution, le ThreadLocal est détruit par la même occasion.

    Chaque requête utilisateur (HttpServletRequest) représente un Thread différent, donc....

    Il faut que tu renseigne ton User à chaque fois, par exemple dans un Filter.

  3. #3
    Expert éminent
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Billets dans le blog
    1
    Par défaut
    Salut,


    Dans une application Web il serait plus propre d'utiliser le scope session pour stocker ces informations...

    a++

  4. #4
    Membre averti
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    62
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 62
    Par défaut
    Mon thread local est stocker dans un BEAN que je déclare dans un fichier xml Spring...
    C'est ce Bean qui récupère les informations lors du logging...et donc le User...
    Il faut donc que je le stocke dans un objet du faces-config.xml plutot??

  5. #5
    Membre chevronné
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    442
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 442
    Par défaut
    Celà ne changera rien à ton problème, à la fin de chaque requête HTTP ton ThreadLocal sera détruit.

    Pourquoi ne propages-tu pas User tout simplement plutôt que de passer par un ThreadLocal ? Comme le dit adiGuba, généralement on stocke User dans la session.

    Maintenant si tu veux vraiment passer par un ThreadLocal pour pouvoir appeler User à nimporte quel endroit, une solution que j'avais mise en place sur un projet était de passer par un filtre qui va "accrocher" User en tant que ThreadLocal avant d'exécuter chaque requête :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    public class UserFilter implements Filter
    {
      public void doFilter(ServletRequest request,
                           ServletResponse response, 
                           FilterChain chain) 
        throws IOException, ServletException
      {
        HttpServletRequest httpreq = (HttpServletRequest)request;
        HttpSession session = httpreq.getSession();
     
        if (session.getAttribute("user") == null)
        	session.setAttribute("user", new User("toto"));
     
        User user = (User)session.getAttribute("user");
        ThreadLocalUser.setUser(user);
     
        chain.doFilter(request, response);
      }
     
      public void init(FilterConfig config) throws ServletException {}
      public void destroy() {}
    }

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    62
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 62
    Par défaut
    Merci pour l'aide

    Mais je veux bien stocker le User dans la session si cela est plus simple et que cela marche...Mais je ne sais pas comment faire...
    Dans ce cas, on parle bien de la Session au sens HTTP?? Car Session peut avoir bcp de sens différents...(hibernate etc)
    Pourriez vous m'indiquez comment faire svp?

  7. #7
    Membre chevronné
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    442
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 442
    Par défaut
    Oui, il s'agit bien de la session HTTP.

    Mais là je vois que tu es en JSF et je ne suis pas un expert sur cette techno.

    Tu peux récupérer la session en faisant ça mais je ne pense pas que ce soit une bonne pratique en JSF :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    FacesContext context = FacesContext.getCurrentInstance();
    HttpSession session = (HttpSession)context.getExternalContext().getSession();
    Après ça dépend...

    comment ton User est-il créé ?

    comment est-il référencé dans faces-context ?

    pour qu'elle raison dois-tu le stocker ?

  8. #8
    Membre averti
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    62
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2006
    Messages : 62
    Par défaut
    Je le stocke car j'ai des préférences utilisateurs sur chaque onglet, qui permettent de ne pas afficher toutes les colonnes + l'ordre...

    Mais je viens de tester quelque chose et cela semble fonctionner...
    C'est en rapport avec le context Acegi en fait puisque jutilise LdapAuthoritiesPopulator pour le logging

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    	public static User getUser() {
     
    		return managementService
    				.getUserFromUserLogin(((LdapUserDetails) (SecurityContextHolder
    						.getContext().getAuthentication().getPrincipal()))
    						.getUsername());
    	}

    Cela semble bien marché...
    Merci pour votre aide, elle m'a bcp guidé

  9. #9
    Membre chevronné
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    442
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 442
    Par défaut
    Citation Envoyé par enjoy Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    	public static User getUser() {
    		...}


    Ta méthode est statique, tu es bien sûr que tes utilisateurs ne vont pas partager le même User ?

Discussions similaires

  1. Réponses: 3
    Dernier message: 20/08/2013, 10h12
  2. Créer un dossier dans mon application web J2EE
    Par gebtun dans le forum Général Java
    Réponses: 1
    Dernier message: 18/04/2013, 12h19
  3. [EJB3.1] Comment intégrer le conteneur d'EJB dans mon application web
    Par geforce dans le forum Java EE
    Réponses: 1
    Dernier message: 24/02/2013, 05h10
  4. Réponses: 5
    Dernier message: 23/11/2010, 12h02
  5. Réponses: 2
    Dernier message: 16/06/2007, 15h33

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo