2008-09-23 8 views
39

Je voudrais savoir s'il y a un moyen de partager une variable ou un objet entre deux Servlets ou plus, je veux dire un moyen "standard". Je suppose que ce n'est pas une bonne pratique, mais c'est un moyen plus facile de construire un prototype.Comment puis-je partager une variable ou un objet entre deux servlets ou plus?

Je ne sais pas si cela dépend des technologies utilisées, mais je vais utiliser Tomcat 5,5


Je veux partager un vecteur d'objets d'une classe simple (seulement les attributs publics, les chaînes, ints, etc.). Mon intention est d'avoir une donnée statique comme dans une base de données, de toute évidence elle sera perdue quand le Tomcat sera arrêté. (c'est juste pour les tests)

+0

Cela dépend en grande partie du type d'objet/de variable. Est-ce que la variable appartient à une classe, et vous voulez juste l'accès? Est-ce une constante? Un exemple serait bien. – Swati

+0

Je souhaite que cela aide :) –

Répondre

74

Je pense que ce que vous cherchez ici sont des données de demande, de session ou d'application.

Dans un servlet, vous pouvez ajouter un objet comme un attribut à l'objet de requête, objet de session ou d'un objet contexte de servlet:

protected void doGet(HttpServletRequest request, HttpServletResponse response) { 
    String shared = "shared"; 
    request.setAttribute("sharedId", shared); // add to request 
    request.getSession().setAttribute("sharedId", shared); // add to session 
    this.getServletConfig().getServletContext().setAttribute("sharedId", shared); // add to application context 
    request.getRequestDispatcher("/URLofOtherServlet").forward(request, response); 
} 

Si vous le mettez dans l'objet de la demande, il sera à la disposition du servlet est transmise à la demande jusqu'à ce que se termine:

request.getAttribute("sharedId"); 

Si vous le mettez dans la session, il sera disponible à tous les servlets aller de l'avant, mais la valeur sera liée à l'utilisateur:

request.getSession().getAttribute("sharedId"); 

Jusqu'à expiration de la session en fonction de l'inactivité de l'utilisateur.

est remis à zéro par vous:

request.getSession().invalidate(); 

Ou un servlet enlève du champ d'application:

request.getSession().removeAttribute("sharedId"); 

Si vous le mettez dans le contexte de servlet il sera disponible pendant que l'application est en cours d'exécution:

this.getServletConfig().getServletContext().getAttribute("sharedId"); 

Jusqu'à ce que vous retirez:

this.getServletConfig().getServletContext().removeAttribute("sharedId"); 
+0

Pouvez-vous étendre votre réponse à ServletContext? –

+1

Ou 'getServletContext()' au lieu de 'this.getServletConfig(). GetServletContext()' ... –

+0

@William Comment puis-je transmettre autre chose qu'une chaîne f.e. un objet d'une classe que je me suis créé? – Stanko

1

Ne pourriez-vous pas simplement placer l'objet dans la session HttpSession et y faire référence par son nom d'attribut dans chacune des servlets?

par exemple:

getSession().setAttribute("thing", object); 

... puis dans une autre servlet:

Object obj = getSession.getAttribute("thing"); 
+0

ne fait pas l'objet d'être sérialisable pour que cela fonctionne? – Jus12

7

En fonction du champ de l'utilisation prévue des données. Si les données ne sont utilisées que par utilisateur, comme les informations de connexion de l'utilisateur, le nombre d'accès aux pages, etc., utilisez l'objet de session (httpServletRequest.getSession(). Get/setAttribute (String [, Object])

Si les données sont identiques pour plusieurs utilisateurs (nombre total de hits de pages Web, threads de travail, etc.), utilisez les attributs ServletContext. servlet.getServletCongfig(). getServletContext(). get/setAttribute (String [, Object])). Cela ne fonctionnera que dans le même fichier de guerre/application web. Notez que ces données ne sont pas conservées entre les redémarrages.

+0

L'utilisation de ServletContext peut facilement vous causer des ennuis si vous ne faites pas attention. Par exemple, vous ne pouvez pas l'utiliser pour implémenter un nombre de hits de pages de la manière naïve: obtenir le compte de la page en cours à partir du contexte, l'incrémenter et définir la valeur au contexte. Le multithreading tue cette solution. – JavadocMD

+0

Meta critque - la question demande une fonctionnalité qu'un magasin de données de support devrait traiter de toute façon via des transactions. Les plaintes concernant ACID devraient entraîner l'utilisation d'un service de données ACID. ServletContext et Session violent tous les ACID d'une manière ou d'une autre. – shemnon

8

Mettez-le dans l'une des 3 portées différentes.

demande - dure vie de la demande

session - dure la vie de la session de l'utilisateur

application - dure jusqu'à applciation est arrêté

Vous pouvez accéder à tous ces champs d'application via la variable HttpServletRequest qui est transmis aux méthodes qui s'étendent de la HttpServlet class

2

Une autre option, partager des données entre les contextes ...

share-data-between-servlets-on-tomcat

<Context path="/myApp1" docBase="myApp1" crossContext="true"/> 
    <Context path="/myApp2" docBase="myApp2" crossContext="true"/> 

Sur myapp1:

ServletContext sc = getServletContext(); 
    sc.setAttribute("attribute", "value"); 

Sur myApp2:

ServletContext sc = getServletContext("/myApp1"); 
    String anwser = (String)sc.getAttribute("attribute"); 
0

Voilà comment je le fais avec la jetée.

https://stackoverflow.com/a/46968645/1287091

utilise le contexte du serveur, où un singleton est écrit lors du démarrage d'un serveur Jetty intégré et partagé entre tous les webapps pour la vie du serveur. Peut également être utilisé pour partager des objets/données entre les webapps en supposant qu'il n'y a qu'un seul écrivain dans le contexte - sinon vous devez faire attention à la concurrence.

Questions connexes