ServletContext
Lorsque le conteneur de servlets (comme Apache Tomcat ) démarre, il déploiera et chargera toutes ses applications Web. Lorsqu'une application Web est chargée, le conteneur de servlet crée ServletContext
une fois et la conserve dans la mémoire du serveur. L'application Web web.xml
et tous les web-fragment.xml
fichiers inclus sont analysés, et chacun <servlet>
, <filter>
et <listener>
trouvé (ou chaque classe annotée avec @WebServlet
, @WebFilter
et @WebListener
respectivement) est instancié une fois et également conservé dans la mémoire du serveur. Pour chaque filtre instancié, sa init()
méthode est invoquée avec un nouveau FilterConfig
.
Lorsque a Servlet
a une valeur <servlet><load-on-startup>
ou @WebServlet(loadOnStartup)
supérieure à 0
, sa init()
méthode est également invoquée lors du démarrage avec un nouveau ServletConfig
. Ces servlets sont initialisés dans le même ordre spécifié par cette valeur ( 1
est le 1er, le 2
2e, etc.). Si la même valeur est spécifiée pour plus d'un servlet, alors chacun de ces servlets est chargé dans le même ordre que dans le web.xml
, web-fragment.xml
ou @WebServlet
classloading. Dans le cas où la valeur "load-on-startup" est absente, la init()
méthode sera invoquée chaque fois que la requête HTTP atteindra ce servlet pour la toute première fois.
Lorsque le conteneur de servlet a terminé toutes les étapes d'initialisation décrites ci-dessus, alors le ServletContextListener#contextInitialized()
sera invoqué.
Lorsque le conteneur se ferme de servlet vers le bas, il décharge toutes les applications Web, appelle la destroy()
méthode de tous ses servlets et les filtres initialisées, et tous ServletContext
, Servlet
, Filter
et les Listener
cas sont saccagés. Enfin, le ServletContextListener#contextDestroyed()
sera invoqué.
HttpServletRequest et HttpServletResponse
Le conteneur de servlet est attaché à un serveur Web qui écoute les requêtes HTTP sur un certain numéro de port (le port 8080 est généralement utilisé pendant le développement et le port 80 en production). Lorsqu'un client (utilisateur , par exemple avec un navigateur Web ou par programmationURLConnection
) envoie une requête HTTP, le conteneur de servlet crée de nouveaux HttpServletRequest
et des HttpServletResponse
objets et les passe par une définition Filter
de la chaîne et, éventuellement, l' Servlet
instance.
Dans le cas des filtres , la doFilter()
méthode est invoquée. Lorsque le code du conteneur de servlet appelle chain.doFilter(request, response)
, la demande et la réponse continuent au filtre suivant, ou appuyez sur la servlet s'il n'y a plus de filtre.
Dans le cas des servlets , la service()
méthode est invoquée. Par défaut, cette méthode détermine la doXxx()
méthode à invoquer en fonction de laquelle request.getMethod()
. Si la méthode déterminée est absente du servlet, une erreur HTTP 405 est renvoyée dans la réponse.
L'objet de demande donne accès à toutes les informations sur la demande HTTP, telles que son URL, ses en-têtes, sa chaîne de requête et son corps. L'objet de réponse permet de contrôler et d'envoyer la réponse HTTP comme vous le souhaitez, par exemple, en vous permettant de définir les en-têtes et le corps (généralement avec du contenu HTML généré à partir d'un fichier JSP). Lorsque la réponse HTTP est validée et terminée, les objets de demande et de réponse sont recyclés et mis à disposition pour être réutilisés.
HttpSession
Lorsqu'un client visite la webapp pour la première fois et / ou HttpSession
est obtenu pour la première fois via request.getSession()
, le conteneur de servlet crée un nouvel HttpSession
objet, génère un ID long et unique (que vous pouvez obtenir session.getId()
) et le stocke dans le serveur Mémoire. Le conteneur de servlet définit également un Cookie
dans l'en- Set-Cookie
tête de la réponse HTTP avec JSESSIONID
comme nom et l'ID de session unique comme valeur.
Conformément à la spécification de cookie HTTP (un contrat auquel tout navigateur Web et serveur Web décent doit adhérer), le client (le navigateur Web) est tenu de renvoyer ce cookie dans les demandes suivantes dans l'en- Cookie
tête tant que le cookie est valide ( c'est-à-dire que l'ID unique doit faire référence à une session non expirée et que le domaine et le chemin sont corrects). En utilisant le moniteur de trafic HTTP intégré de votre navigateur, vous pouvez vérifier que le cookie est valide (appuyez sur F12 dans Chrome / Firefox 23+ / IE9 +, et vérifiez l' onglet Net / Réseau ). Le conteneur de servlet vérifiera l'en- Cookie
tête de chaque requête HTTP entrante pour la présence du cookie avec le nom JSESSIONID
et utilisera sa valeur (l'ID de session) pour obtenir l'associé HttpSession
de la mémoire du serveur.
Le HttpSession
reste en vie jusqu'à ce qu'il soit inactif (c'est-à-dire non utilisé dans une demande) pendant plus que la valeur de temporisation spécifiée dans <session-timeout>
, un paramètre dans web.xml
. La valeur du délai d'attente est par défaut de 30 minutes. Ainsi, lorsque le client ne visite pas l'application Web plus longtemps que la durée spécifiée, le conteneur de servlet met la session au rebut. Chaque demande ultérieure, même avec le cookie spécifié, n'aura plus accès à la même session; le conteneur de servlet créera une nouvelle session.
Côté client, le cookie de session reste actif aussi longtemps que l'instance de navigateur est en cours d'exécution. Ainsi, si le client ferme l'instance de navigateur (tous les onglets / fenêtres), la session est mise à la poubelle du côté du client. Dans une nouvelle instance de navigateur, le cookie associé à la session n'existerait pas, il ne serait donc plus envoyé. Cela entraîne la HttpSession
création d'un tout nouveau, avec un cookie de session entièrement nouveau utilisé.
En un mot
- La
ServletContext
vie aussi longtemps que dure l'application Web. Il est partagé entre toutes les demandes de toutes les sessions.
- La
HttpSession
vie dure aussi longtemps que le client interagit avec l'application Web avec la même instance de navigateur et que la session n'a pas expiré côté serveur. Il est partagé entre toutes les demandes d'une même session.
- Le
HttpServletRequest
et en HttpServletResponse
direct à partir du moment où le servlet reçoit une demande HTTP du client, jusqu'à ce que la réponse complète (la page Web) soit arrivée. Il n'est pas partagé ailleurs.
- Tous
Servlet
, Filter
et les Listener
instances vivent aussi longtemps que l'application Web vit. Ils sont partagés entre toutes les demandes dans toutes les sessions.
- Tout
attribute
qui est défini dans ServletContext
, HttpServletRequest
et HttpSession
vivra aussi longtemps que l'objet dans la vie de question. L'objet lui-même représente la «portée» dans les cadres de gestion de bean tels que JSF, CDI, Spring, etc. Ces cadres stockent leurs beans étendus en tant que attribute
sa portée de correspondance la plus proche.
Sécurité des fils
Cela dit, votre principale préoccupation est peut-être la sécurité des threads . Vous devez maintenant savoir que les servlets et les filtres sont partagés entre toutes les demandes. C'est la bonne chose à propos de Java, il est multithread et différents threads (lire: requêtes HTTP) peuvent utiliser la même instance. Il serait autrement trop cher à recréer, init()
et destroy()
eux pour chaque demande.
Vous devez également comprendre que vous ne devez jamais affecter de données de portée de demande ou de session en tant que variable d' instance d'un servlet ou d'un filtre. Il sera partagé entre toutes les autres demandes des autres sessions. Ce n'est pas thread-safe! L'exemple ci-dessous illustre ceci:
public class ExampleServlet extends HttpServlet {
private Object thisIsNOTThreadSafe;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Object thisIsThreadSafe;
thisIsNOTThreadSafe = request.getParameter("foo"); // BAD!! Shared among all requests!
thisIsThreadSafe = request.getParameter("foo"); // OK, this is thread safe.
}
}
Voir également:
PHPSESSID
cookie, ASP.NET avecASP.NET_SessionID
cookie, etc. C'est aussi pourquoi la réécriture d'URL avec;jsessionid=xxx
comme le font automatiquement certains frameworks JSP / Servlet MVC est mal vue. Assurez-vous simplement que l'ID de session n'est jamais exposé dans l'URL ou par d'autres moyens dans les pages Web afin que l'utilisateur final non averti ne soit pas attaqué.Séances
En bref: le serveur Web délivre un identifiant unique à chaque visiteur lors de sa première visite. Le visiteur doit rapporter cette pièce d'identité pour qu'il soit reconnu la prochaine fois. Cet identifiant permet également au serveur de séparer correctement les objets appartenant à une session et ceux d'une autre.
Instanciation de servlet
Si le chargement au démarrage est faux :
Si le chargement au démarrage est vrai :
Une fois qu'il est en mode service et sur le groove, le même servlet fonctionnera sur les demandes de tous les autres clients.
Pourquoi n'est-ce pas une bonne idée d'avoir une instance par client? Pensez-y: embaucherez-vous un pizzaiolo pour chaque commande reçue? Faites cela et vous seriez en faillite en un rien de temps.
Cela comporte cependant un petit risque. Rappelez-vous: ce gars célibataire détient toutes les informations de commande dans sa poche: donc si vous n'êtes pas prudent sur la sécurité des threads sur les servlets , il peut finir par donner le mauvais ordre à un certain client.
la source
to many requests at this moment. try again later
La session dans les servlets Java est identique à la session dans d'autres langages tels que PHP. Il est unique à l'utilisateur. Le serveur peut en assurer le suivi de différentes manières telles que les cookies, la réécriture d'URL, etc. Cet article de documentation Java l' explique dans le contexte des servlets Java et indique que la façon dont la session est maintenue est un détail d'implémentation laissé aux concepteurs du serveur. La spécification stipule uniquement qu'elle doit être maintenue comme unique pour un utilisateur sur plusieurs connexions au serveur. Consultez cet article d'Oracle pour plus d'informations sur vos deux questions.
Modifier Il y a un excellent tutoriel ici sur la façon de travailler avec la session à l' intérieur de servlets. Et voici un chapitre de Sun sur les servlets Java, ce qu'ils sont et comment les utiliser. Entre ces deux articles, vous devriez pouvoir répondre à toutes vos questions.
la source
ServletContext
objet. Cet objet a zéro, un ou plusieurs objets de session - une collection d'objets de session. Chaque session est identifiée par une sorte de chaîne d'identification, comme on le voit dans les dessins animés sur une autre réponse. Cet identifiant est suivi sur le client par cookie ou par réécriture d'URL. Chaque objet de session a ses propres variables.Lorsque le conteneur de servlet (comme Apache Tomcat) démarre, il lit le fichier web.xml (un seul par application) si quelque chose se passe mal ou affiche une erreur sur la console côté conteneur, sinon, il déploiera et chargera tout le Web en utilisant web.xml (ainsi nommé comme descripteur de déploiement).
Pendant la phase d'instanciation de la servlet, l'instance de servlet est prête mais elle ne peut pas répondre à la demande du client car elle manque avec deux informations:
1: informations de contexte
2: informations de configuration initiale
Le moteur de servlet crée un objet d'interface servletConfig encapsulant les informations manquantes ci-dessus dans ce moteur de servlet appelle init () de la servlet en fournissant des références d'objet servletConfig comme argument. Une fois init () complètement exécuté, le servlet est prêt à répondre à la demande du client.
Q) Pendant la durée de vie du servlet, combien de fois l'instanciation et l'initialisation se produisent-elles ??
A) une seule fois (pour chaque demande client, un nouveau thread est créé), une seule instance de la servlet sert un nombre quelconque de la demande client, c'est-à-dire qu'après avoir servi un serveur de demande client ne meurt pas. Il attend les autres demandes client, c'est-à-dire quelle limitation CGI (pour chaque demande client un nouveau processus est créé) est surmontée avec le servlet (le moteur de servlet interne crée le thread).
Q) Comment fonctionne le concept de session?
A) chaque fois que getSession () est appelée sur un objet HttpServletRequest
Étape 1 : l'objet de demande est évalué pour l'ID de session entrant.
Étape 2 : si l'ID n'est pas disponible, un nouvel objet HttpSession est créé et son ID de session correspondant est généré (c'est-à-dire de HashTable) L'ID de session est stocké dans l'objet de réponse httpservlet et la référence de l'objet HttpSession est renvoyée au servlet (doGet / doPost) .
Étape 3 : si aucun nouvel objet de session d'ID disponible n'est créé, l'ID de session est récupéré à partir de la demande d'objet, la recherche est effectuée dans la collection de sessions en utilisant l'ID de session comme clé.
Une fois la recherche réussie, l'ID de session est stocké dans HttpServletResponse et les références d'objet de session existantes sont renvoyées à doGet () ou doPost () de UserDefineservlet.
Remarque:
1) lorsque le contrôle quitte le code de servlet pour le client, n'oubliez pas que l'objet de session est détenu par le conteneur de servlet, c'est-à-dire le moteur de servlet
2) le multithreading est laissé aux développeurs de servlets pour la mise en œuvre, c'est-à-dire, ne gère pas les demandes multiples du client pour ne pas se soucier du code multithread
Forme courte:
Une servlet est créée au démarrage de l'application (elle est déployée sur le conteneur de servlet) ou lors de son premier accès (en fonction du paramètre de chargement au démarrage) lorsque la servlet est instanciée, la méthode init () de la servlet est appelée puis le servlet (sa seule et unique instance) gère toutes les requêtes (sa méthode service () étant appelée par plusieurs threads). C'est pourquoi il n'est pas conseillé d'y avoir de synchronisation, et vous devez éviter les variables d'instance du servlet lorsque l'application n'est pas déployée (le conteneur de servlet s'arrête), la méthode destroy () est appelée.
la source
Sessions - ce que Chris Thompson a dit.
Instanciation - une servlet est instanciée lorsque le conteneur reçoit la première demande mappée à la servlet (sauf si la servlet est configurée pour se charger au démarrage avec l'
<load-on-startup>
élément dedansweb.xml
). La même instance est utilisée pour traiter les demandes suivantes.la source
La spécification de servlet JSR-315 définit clairement le comportement du conteneur Web dans les méthodes de service (et doGet, doPost, doPut etc.) (2.3.3.1 Problèmes de multithreading, page 9):
la source
Comme il ressort clairement des explications ci-dessus, en implémentant le SingleThreadModel , un servlet peut être assuré de la sécurité des threads par le conteneur de servlet. L'implémentation du conteneur peut le faire de 2 manières:
1) Sérialisation des demandes (mise en file d'attente) vers une seule instance - cela est similaire à une servlet qui n'implémente PAS SingleThreadModel MAIS synchronisant les méthodes service / doXXX; OU
2) Création d'un pool d'instances - qui est une meilleure option et un compromis entre l'effort de démarrage / d'initialisation / le temps de la servlet par rapport aux paramètres restrictifs (mémoire / temps CPU) de l'environnement hébergeant la servlet.
la source
Non. Les servlets ne sont pas thread-safe
Cela permet d'accéder à plusieurs threads à la fois
si vous voulez rendre Servlet sûr pour les threads., U peut opter pour
Implement SingleThreadInterface(i)
qui est une interface vierge, il n'y a pasles méthodes
ou nous pouvons opter pour des méthodes de synchronisation
nous pouvons faire la méthode de service entière comme synchronisée en utilisant synchronisé
mot-clé devant la méthode
Exemple::
ou nous pouvons mettre le bloc du code dans le bloc synchronisé
Exemple::
Je pense que le bloc synchronisé est meilleur que de faire toute la méthode
Synchronisé
la source