Question

Est-il possible d'accéder à un haricot de session avec état à l'intérieur d'un haricot sans état?

Mon problème est que j'ai un bean de session appelé utilisateur et je souhaite accéder aux informations d'utilisateur dans un bean sans état ...

J'essaye comme ceci:

Côté ejb:

@Stateless
public class OfferManagerBean implements OfferManagerLocal, OfferManager
{
    @Resource 
    private SessionContext context;
    @EJB
    private ro.project.ejb.interfaces.User user;
    public String getUsername()
    {
        user = (ro.project.ejb.interfaces.User) context.lookup("java:global/project/projectEJB/User!ro.project.ejb.interfaces.User");
        return user.getUsername();
}

Côté client

 User user = (User) ctx.lookup("java:global/project/projectEJB/User!ro.project.ejb.interfaces.User");
 user.setUsername("Alex");

 OfferManager offerManager = (OfferManager) ctx.lookup("java:global/project/projectEJB/OfferManagerBean!ro.project.ejb.interfaces.OfferManager");
 assertEquals(offerManager.getUsername(), "Alex");

Le résultat de ce cas de test est java.lang.AssertionError: expected:<null> but was:<Alex>

ça échoue .. il semble que je demande à la façon dont je demande le haricot avec état me renvoie une nouvelle instance ...

  1. Je sais pourquoi cela ne fonctionne pas. Parce que mon test échoue: p. J'obtiens une nouvelle instance ..
  2. Je veux vérifier certaines autorisations de l'utilisateur connecté dans EJB parce que je ne veux pas compter du côté client parce que je pourrais faire une erreur là-bas ou je dirai à d'autres développeurs de faire une interface graphique pour mon projet.
  3. Je ne veux pas utiliser Java ee Security beucause je ne sais pas comment faire la connexion dans une application RCP
  4. Ma principale question est: comment accéder à un bean de session (le même que le client possède) à l'intérieur d'un EJB .. Est-ce possible? Et comment?

Je demande presque la même chose que ce gars demande: Concept pour la session de connexion réutilisable dans les appels RMI EJB

Je veux faire ça mais pas avec Jaas ...

Merci d'avance

Était-ce utile?

La solution

Tu devrais jamais injecter un @Stateful Bean (SFSB) dans un @Stateless Bean (SLSB). Un SFSB vit aussi longtemps que son client vit (le client est l'instance où le SFSB est injecté, ce qui est dans ce cas le SLSB lui-même). Les SLSB sont cependant inventés d'être apatride Et la plupart des conteneurs les ont dans une piscine. Donc, chaque fois que le SLSB revient à la piscine après utilisation, il sera réutilisé entièrement ailleurs, mais il contient la même instance SFSB que lorsque le SLSB a été créé pour la première fois! Cela peut conduire à des résultats indésirables.

De plus, chaque fois que vous obtenez le SFSB de JNDI, vous obtiendrez un tout neuf Instance qui est différente de SLSBS ne pas partagé ailleurs. Le client du SFSB est alors l'instance de classe client actuelle où vous avez le SFSB de JNDI. Vous êtes censé garder cette instance vous-même et réutiliser la même instance jusqu'à ce que vous ayez terminé de effectuer la transaction dessus. L'une des voies est de la stocker dans la session HTTP vous-même ou dans une session Géré Géré du cadre MVC que vous utilisez.

L'exigence fonctionnelle n'est pas entièrement claire pour moi, il est donc difficile de donner une réponse appropriée à la résolution de votre problème particulier, mais j'ai l'impression que vous réellement Besoin de stocker l'utilisateur dans la session HTTP, pas dans un SFSB. L'erreur du débutant la plus courante concernant les haricots de session est à savoir qu'ils interprètent à tort la "session" dans le contexte EJB comme étant la session HTTP.

Voir aussi cette réponse connexe sur une question du même genre pour une explication plus approfondie: La demande JSF Scoped Bean continue de recréer de nouvelles haricots de session d'état à chaque demande? Selon l'historique de votre question, vous connaissez JSF, donc cette réponse devrait être facile à comprendre.

Autres conseils

En général, il est possible d'accéder à certains haricots de session d'état existants à l'intérieur du haricot sans état. Il peut être par exemple donné comme argument à la méthode commerciale du bean de session sans état.

Mais ce que vous essayez ne peut pas fonctionner. La raison est que les deux, Dependudy Injection (@EJB) et Lookup (ctx.lookup ...) sont garantis d'appeler NewInstance et, en conséquence, vous aurez une nouvelle instance.

Ceci est expliqué dans les spécifications avec les mots suivants:

La durée de vie d'une instance de haricot de session démarre lorsqu'un client obtient une référence à une instance de haricot de session d'État via l'injection de dépendance ou la recherche JNDI, ou lorsque le client invoque une méthode de création sur l'interface domestique du bean de session. Cela fait que le conteneur invoque la nouvelleInstance de la classe de bean de session pour créer une nouvelle instance de bean de session.

Au cas où les autres n'étaient pas déjà assez clairs: vous vous trompez! ;)

Je suis d'accord que cela pourrait être déroutant, mais la seule session dans les haricots de session EJB est conservée dans le haricot proxy que vous obtenez à partir du Context Initital.

Différents haricots que vous obtenez à partir de ce contexte ne partagent aucune sorte de session commune. Dans EJB, les haricots ne sont pas stockés dans une session EJB mais ce sont cette session.

En d'autres termes, l'InitialContext (CTX dans votre code) n'est pas l'équivalence EJB pour la HTTPSession.

Pire encore, c'est peut-être que dans votre code, l'utilisateur est un bean EJB. C'est faux.

Un utilisateur est un nom dans votre application. Ceux-ci sont représentés par des entités JPA ou des haricots Java «normaux» simples. Les EJB sont destinés à la mise en œuvre du verbes Dans votre application: services, DAO, référentiels, etc.

L'état des haricots de session d'État est censé conserver les données du modèle pendant un processus métier (pour la mise en cache, le verrouillage, les réservations, etc.). Dans aucune situation, cet état ne doit être les données du modèle.

Mon conseil: laissez votre «design» actuel. N'essayez pas de le réparer, n'essayez pas de le justifier. Lâchez-le, supprimez votre code, ne regardez pas en arrière. Lisez quelques bons livres sur l'EJB, puis recommencez.

Bonne chance!

Je ne valide pas si vous vous faites bien / mal dans l'utilisation de SFSB & SLSB. Mais ci-dessous est la réponse à votre problème

Option-1: Depuis votre servlet, effectuez la recherche JNDI pour SFSB. Cela devrait être une fois. Stockez la référence retournée de SFSB dans votre HTTPSession. Lorsque vous appelez la méthode SLSB qui a besoin de l'instance SFSB pour stocker les détails de l'utilisateur, passez l'objet de référence SFSB ci-dessus comme paramètre à la méthode SLSB. Ensuite, accédez-y à partir de la méthode SLSB et stockez les données utilisateur.

Problème avec l'option-1: vous liez en couple votre mécanisme de persistance (SFSB) à votre code d'interface utilisateur (puisque vous le stockez dans HTTPSession et passez-le). Demain, si vous voulez passer à un autre mécanisme de persistance comme un cache, vous devrez faire beaucoup de retouches. Encore une fois, si vous souhaitez exposer votre méthode SLSB en tant que service Web, vous ne pourrez pas le faire car vous ne pouvez pas XML-Iser la référence d'objet SFSB. En bref, une mauvaise option.

Option-2: Ayez un hashmap statique dans une classe dans le niveau des affaires. Supposons que vous avez des attributs de transaction uniques pour chaque transaction, quelque chose comme un identifiant. Lorsque vous démarrez la transaction, à partir de votre niveau commercial, créez le SFSB, stockez sa référence dans le hashmap statique avec ID comme clé. Lorsque vous appelez la méthode du service SLSB, passez cet ID (je suppose que chaque transaction peut avoir un ID unique). À partir de la méthode SLSB, utilisez l'ID pour rechercher la référence SFSB stockée dans le hashmap statique. Utilisez-le pour votre stockage. Dans cette option, votre interface utilisateur et SFSB ne sont pas couplées. Demain, si vous souhaitez chanter votre mécanisme de persistance, vous pouvez faire avec des clients qui impactaient les clients car vos modifications seront limitées dans le niveau de la Colombie-Britannique.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top