ServletContext
Wenn der Servlet-Container (wie Apache Tomcat ) gestartet wird, werden alle Webanwendungen bereitgestellt und geladen. Wenn eine Webanwendung geladen wird, erstellt der Servlet-Container die ServletContext
einmalige Anwendung und speichert sie im Speicher des Servers. Der Web - App web.xml
und alle enthaltenen web-fragment.xml
Dateien wird analysiert, und jeder <servlet>
, <filter>
und <listener>
gefunden (oder jede Klasse kommentierte mit @WebServlet
, @WebFilter
und@WebListener
jeweils) instanziiert einmal und auch in der Server-Speicher gehalten. Für jeden instanziierten Filter wird seine init()
Methode mit einem neuen aufgerufen FilterConfig
.
Wenn a Servlet
einen <servlet><load-on-startup>
oder @WebServlet(loadOnStartup)
Wert größer als hat 0
, wird seine init()
Methode auch beim Start mit einem neuen aufgerufen ServletConfig
. Diese Servlets werden in derselben Reihenfolge initialisiert, die durch diesen Wert angegeben wird ( 1
ist 1., 2
ist 2. usw.). Wenn für mehr als ein Servlet derselbe Wert angegeben wird, wird jedes dieser Servlets in derselben Reihenfolge geladen, in der sie im web.xml
, angezeigt werden.web-fragment.xml
oder @WebServlet
Classloading. init()
Wenn der Wert "Load-on-Startup" nicht vorhanden ist, wird die Methode immer dann aufgerufen, wenn die HTTP-Anforderung das Servlet zum ersten Mal trifft.
Wenn der Servlet-Container mit allen oben beschriebenen Initialisierungsschritten fertig ist, wird der ServletContextListener#contextInitialized()
wird der aufgerufen.
Wenn die Servlet - Container heruntergefahren wurde , es alle Webanwendungen leert, ruft die destroy()
Methode aller seiner initialisiert Servlets und Filter, und alle ServletContext
, Servlet
, Filter
undListener
Instanzen im Papierkorb sind. Schließlich ServletContextListener#contextDestroyed()
wird das aufgerufen.
HttpServletRequest und HttpServletResponse
Der Servlet-Container ist an einen Webserver angeschlossen, der auf HTTP-Anforderungen an einer bestimmten Portnummer wartet (Port 8080 wird normalerweise während der Entwicklung und Port 80 in der Produktion verwendet). Wenn ein Client (zB Benutzer mit einem Web - Browser oder mit programmatischURLConnection
) einer HTTP - Anforderung sendet, erstellt die Servlet - Container neu HttpServletRequest
und HttpServletResponse
Objekte und leitet sie durch definierte jeder Filter
in der Kette und schließlich dieServlet
Instanz.
Bei Filtern ist diedoFilter()
Methode aufgerufen. Wenn der Code des Servlet-Containers aufgerufen wird chain.doFilter(request, response)
, fahren die Anforderung und die Antwort mit dem nächsten Filter fort oder treffen das Servlet, wenn keine Filter mehr vorhanden sind.
Bei Servlets wird die service()
Methode aufgerufen. Standardmäßig bestimmt diese Methode, von welcher der doXxx()
aufzurufenden Methoden basierend auf request.getMethod()
. Wenn die ermittelte Methode im Servlet nicht vorhanden ist, wird in der Antwort ein HTTP 405-Fehler zurückgegeben.
Das Anforderungsobjekt bietet Zugriff auf alle Informationen zur HTTP-Anforderung, z. B. URL, Header, Abfragezeichenfolge und Text. Das Antwortobjekt bietet die Möglichkeit, die HTTP-Antwort nach Ihren Wünschen zu steuern und zu senden, indem Sie beispielsweise die Header und den Body festlegen (normalerweise mit generiertem HTML-Inhalt aus einer JSP-Datei). Wenn die HTTP-Antwort festgeschrieben und beendet ist, werden sowohl das Anforderungs- als auch das Antwortobjekt recycelt und zur Wiederverwendung verfügbar gemacht.
HttpSession
Wenn ein Client die Webanwendung zum ersten Mal besucht und / oder die HttpSession
zum ersten Mal über abgerufen wird request.getSession()
, erstellt der Servlet-Container ein neues HttpSession
Objekt, generiert eine lange und eindeutige ID (die Sie erhalten können session.getId()
) und speichert sie auf dem Server Erinnerung. Der Servlet-Container setzt auch ein Cookie
in den Set-Cookie
Header der HTTP-Antwort mitJSESSIONID
seinem Namen und der eindeutigen Sitzungs-ID als Wert fest.
Gemäß der HTTP-Cookie-Spezifikation (ein Vertrag, den jeder anständige Webbrowser und Webserver einhalten muss) muss der Client (der Webbrowser) dieses Cookie bei nachfolgenden Anforderungen im Cookie
Header zurücksenden, solange das Cookie gültig ist ( dh die eindeutige ID muss sich auf eine nicht abgelaufene Sitzung beziehen und die Domäne und der Pfad sind korrekt). Mit dem integrierten HTTP-Verkehrsmonitor Ihres Browsers können Sie überprüfen, ob das Cookie gültig ist (drücken Sie F12 in Chrome / Firefox 23+ / IE9 + und überprüfen Sie die Registerkarte Netz / Netzwerk ). Der Servlet-Container überprüft den Cookie
Header jeder eingehenden HTTP-Anforderung auf das Vorhandensein des Cookies mit dem Namen JSESSIONID
und verwendet seinen Wert (die Sitzungs-ID), um das zugehörige HttpSession
aus dem Serverspeicher abzurufen.
Das HttpSession
bleibt am Leben, bis es für mehr als den in <session-timeout>
einer Einstellung angegebenen Zeitlimitwert inaktiv war (dh nicht in einer Anforderung verwendet wurde)web.xml
. Der Timeout-Wert beträgt standardmäßig 30 Minuten. Wenn der Client die Web-App nicht länger als die angegebene Zeit besucht, wird die Sitzung vom Servlet-Container verworfen. Jede nachfolgende Anforderung hat auch mit dem angegebenen Cookie keinen Zugriff mehr auf dieselbe Sitzung. Der Servlet-Container erstellt eine neue Sitzung.
Auf der Clientseite bleibt das Sitzungscookie so lange aktiv, wie die Browserinstanz ausgeführt wird. Wenn der Client die Browserinstanz schließt (alle Registerkarten / Fenster), wird die Sitzung auf der Clientseite verworfen. In einer neuen Browserinstanz wäre das der Sitzung zugeordnete Cookie nicht vorhanden, sodass es nicht mehr gesendet wird. Dies führt zu einer völlig neuenHttpSession
Cookie erstellt, wobei ein völlig neues Sitzungscookie verwendet wird.
In einer Nussschale
- Das
ServletContext
Leben so lange wie die Web-App lebt. Es wird von allen Anforderungen in allen Sitzungen gemeinsam genutzt.
- Das
HttpSession
Leben dauert so lange, wie der Client mit derselben Webinstanz mit der Web-App interagiert und die Sitzung auf der Serverseite nicht abgelaufen ist. Es wird von allen Anforderungen in derselben Sitzung gemeinsam genutzt.
- Das
HttpServletRequest
und HttpServletResponse
live von dem Zeitpunkt an, an dem das Servlet eine HTTP-Anforderung vom Client empfängt, bis die vollständige Antwort (die Webseite) eingetroffen ist. Es wird nicht anderswo geteilt.
- Alle
Servlet
, Filter
und Listener
Instanzen leben, solange der Web - App lebt. Sie werden von allen Anforderungen in allen Sitzungen gemeinsam genutzt.
- Alles
attribute
, was in definiert ServletContext
ist HttpServletRequest
und HttpSession
so lange lebt, wie das betreffende Objekt lebt. Das Objekt selbst stellt den "Bereich" in Bean-Management-Frameworks wie JSF, CDI, Spring usw. dar. Diese Frameworks speichern ihre Scoped-Beans als einen attribute
der am besten passenden Bereiche .
Gewindesicherheit
Ihr Hauptanliegen ist jedoch möglicherweise die Thread-Sicherheit . Sie sollten jetzt wissen, dass Servlets und Filter von allen Anforderungen gemeinsam genutzt werden. Das ist das Schöne an Java, es ist Multithread-fähig und verschiedene Threads (sprich: HTTP-Anforderungen) können dieselbe Instanz verwenden. Es wäre sonst zu teuer, sie neu zu erstellen, init()
und zwar destroy()
für jede einzelne Anfrage.
Sie sollten auch erkennen , dass Sie sollten nie irgendwelche Anfrage oder Sitzungs - Zielbereichsdaten als zuweisen Instanz Variable eines Servlets oder Filter. Es wird für alle anderen Anforderungen in anderen Sitzungen freigegeben. Das ist nicht threadsicher! Das folgende Beispiel veranschaulicht dies:
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.
}
}
Siehe auch:
PHPSESSID
Cookie, ASP.NET mitASP.NET_SessionID
Cookie usw. Das ist auch der Grund, warum das Umschreiben von URLs,;jsessionid=xxx
wie es einige JSP / Servlet MVC-Frameworks automatisch tun, verpönt ist. Stellen Sie einfach sicher, dass die Sitzungs-ID niemals in URLs oder auf andere Weise auf Webseiten verfügbar gemacht wird, damit der ahnungslose Endbenutzer nicht angegriffen wird.Sitzungen
Kurz gesagt: Der Webserver gibt jedem Besucher bei seinem ersten Besuch eine eindeutige Kennung . Der Besucher muss diesen Ausweis mitbringen, damit er beim nächsten Mal erkannt wird. Mit dieser Kennung kann der Server auch Objekte einer Sitzung ordnungsgemäß von denen einer anderen Sitzung trennen.
Servlet-Instanziierung
Wenn load-on-startup ist falsch :
Wenn load-on-startup ist wahr :
Sobald er sich im Servicemodus und im Groove befindet, bearbeitet dasselbe Servlet die Anforderungen aller anderen Clients.
Warum ist es nicht eine gute Idee, eine Instanz pro Client zu haben? Denken Sie darüber nach: Werden Sie für jede Bestellung einen Pizzaboten einstellen? Wenn Sie das tun, sind Sie in kürzester Zeit aus dem Geschäft.
Es ist jedoch mit einem geringen Risiko verbunden. Denken Sie daran: Dieser einzelne Mann hat alle Bestellinformationen in der Tasche. Wenn Sie also bei der Thread-Sicherheit von Servlets nicht vorsichtig sind , gibt er möglicherweise einem bestimmten Kunden die falsche Bestellung.
quelle
to many requests at this moment. try again later
Die Sitzung in Java-Servlets entspricht der Sitzung in anderen Sprachen wie PHP. Es ist einzigartig für den Benutzer. Der Server kann dies auf verschiedene Arten verfolgen, z. B. durch Cookies, Umschreiben von URLs usw. Dieser Java-Dokumentartikel erläutert dies im Kontext von Java-Servlets und gibt an, dass die genaue Verwaltung der Sitzung ein Implementierungsdetail ist, das den Designern des Servers überlassen bleibt. Die Spezifikation sieht nur vor, dass sie für einen Benutzer über mehrere Verbindungen zum Server hinweg eindeutig sein muss. In diesem Artikel von Oracle finden Sie weitere Informationen zu Ihren beiden Fragen.
Bearbeiten Es gibt ein ausgezeichnetes Tutorial hier , wie mit Sitzung innerhalb von Servlets zu arbeiten. Und hier ist ein Kapitel von Sun über Java-Servlets, was sie sind und wie man sie verwendet. Zwischen diesen beiden Artikeln sollten Sie in der Lage sein, alle Ihre Fragen zu beantworten.
quelle
ServletContext
Objekt. Dieses Objekt hat null, ein oder mehrere Sitzungsobjekte - eine Sammlung von Sitzungsobjekten. Jede Sitzung wird durch eine Art Identifizierungszeichenfolge identifiziert, wie in Cartoons bei anderen Antworten zu sehen ist. Diese Kennung wird auf dem Client entweder durch Cookies oder durch Umschreiben von URLs verfolgt. Jedes Sitzungsobjekt hat seine eigenen Variablen.Wenn der Servlet-Container (wie Apache Tomcat) gestartet wird, liest er aus der Datei web.xml (nur eine pro Anwendung), wenn etwas schief geht oder ein Fehler an der Containerseite angezeigt wird. Andernfalls wird das gesamte Web bereitgestellt und geladen Anwendungen mithilfe von web.xml (so genannt als Deployment-Deskriptor).
Während der Instanziierungsphase des Servlets ist die Servlet-Instanz bereit, kann jedoch die Clientanforderung nicht bedienen, da sie mit zwei Informationen fehlt:
1: Kontextinformationen
2: Informationen zur Erstkonfiguration
Die Servlet-Engine erstellt ein servletConfig-Schnittstellenobjekt, in das die oben genannten fehlenden Informationen eingekapselt sind. Die Servlet-Engine ruft init () des Servlets auf, indem sie servletConfig-Objektreferenzen als Argument angibt. Sobald init () vollständig ausgeführt wurde, ist das Servlet bereit, die Clientanforderung zu bedienen.
F) Wie oft erfolgt in der Lebensdauer des Servlets die Instanziierung und Initialisierung?
A) Nur einmal (für jede Clientanforderung wird ein neuer Thread erstellt) bedient nur eine Instanz des Servlets eine beliebige Anzahl der Clientanfragen, dh nachdem ein Clientanforderungsserver bedient wurde, stirbt er nicht ab. Es wartet auf andere Clientanforderungen, dh welche CGI-Einschränkung (für jede Clientanforderung wird ein neuer Prozess erstellt) mit dem Servlet überwunden wird (die interne Servlet-Engine erstellt den Thread).
F) Wie funktioniert das Sitzungskonzept?
A) Wann immer getSession () für das HttpServletRequest-Objekt aufgerufen wird
Schritt 1 : Das Anforderungsobjekt wird auf die ID der eingehenden Sitzung ausgewertet.
Schritt 2 : Wenn die ID nicht verfügbar ist, wird ein brandneues HttpSession-Objekt erstellt und die entsprechende Sitzungs-ID (dh der HashTable) generiert. Die Sitzungs-ID wird im httpservlet-Antwortobjekt gespeichert und die Referenz des HttpSession-Objekts wird an das Servlet zurückgegeben (doGet / doPost). .
Schritt 3 : Wenn keine ID verfügbar ist, wird kein brandneues Sitzungsobjekt erstellt. Die Sitzungs-ID wird aus der Anforderung übernommen. Die Objektsuche wird in der Sitzungssammlung unter Verwendung der Sitzungs-ID als Schlüssel durchgeführt.
Nach erfolgreicher Suche wird die Sitzungs-ID in HttpServletResponse gespeichert und die vorhandenen Sitzungsobjektreferenzen werden an doGet () oder doPost () von UserDefineservlet zurückgegeben.
Hinweis:
1) Wenn die Steuerung vom Servlet-Code zum Client wechselt, vergessen Sie nicht, dass das Sitzungsobjekt vom Servlet-Container, dh der Servlet-Engine, gehalten wird
2) Multithreading bleibt den Servlet-Entwicklern für die Implementierung überlassen, dh sie müssen die mehrfachen Anforderungen des Clients bearbeiten, ohne sich um Multithread-Code zu kümmern
Kurzform:
Ein Servlet wird erstellt, wenn die Anwendung gestartet wird (sie wird auf dem Servlet-Container bereitgestellt) oder wenn beim ersten Instanziieren des Servlets (abhängig von der Einstellung beim Laden beim Start) zum ersten Mal darauf zugegriffen wird, wird die init () -Methode des Servlets aufgerufen Dann verarbeitet das Servlet (seine einzige Instanz) alle Anforderungen (seine service () -Methode wird von mehreren Threads aufgerufen). Aus diesem Grund ist eine Synchronisierung nicht ratsam. Sie sollten Instanzvariablen des Servlets vermeiden, wenn die Anwendung nicht bereitgestellt wird (der Servlet-Container stoppt). Die Methode destroy () wird aufgerufen.
quelle
Sitzungen - was Chris Thompson gesagt hat.
Instanziierung - ein Servlet instanziiert wird , wenn der Behälter die erste Anforderung an das Servlet kartiert empfängt (es sei denn die Servlet Last beim Start mit dem so konfiguriert ist ,
<load-on-startup>
Element inweb.xml
). Dieselbe Instanz wird verwendet, um nachfolgende Anforderungen zu bedienen.quelle
Die Servlet-Spezifikation JSR-315 definiert das Verhalten des Webcontainers in den Dienstmethoden (und doGet, doPost, doPut usw.) klar (2.3.3.1 Multithreading-Probleme, Seite 9):
quelle
Wie aus den obigen Erläuterungen hervorgeht, kann durch die Implementierung des SingleThreadModel ein Servlet durch den Servlet-Container die Thread-Sicherheit gewährleisten. Die Container-Implementierung kann dies auf zwei Arten tun:
1) Serialisieren von Anforderungen (Warteschlangen) an eine einzelne Instanz - dies ähnelt einem Servlet, das SingleThreadModel NICHT implementiert, ABER die Service / doXXX-Methoden synchronisiert. ODER
2) Erstellen eines Pools von Instanzen - eine bessere Option und ein Kompromiss zwischen dem Start- / Initialisierungsaufwand / der Zeit des Servlets und den restriktiven Parametern (Speicher- / CPU-Zeit) der Umgebung, in der sich das Servlet befindet.
quelle
Nr Servlets sind nicht Thread - sicher
Auf diese Weise können Sie auf mehrere Threads gleichzeitig zugreifen
Wenn du es Servlet als Thread-sicher machen willst, kannst du gehen
Implement SingleThreadInterface(i)
Das ist eine leere Schnittstelle gibt es keineMethoden
oder wir können Methoden synchronisieren
Wir können die gesamte Servicemethode synchronisieren, indem wir synchronisiert verwenden
Schlüsselwort vor Methode
Beispiel::
oder wir können den put-Block des Codes in den synchronisierten Block setzen
Beispiel::
Ich bin der Meinung, dass der synchronisierte Block besser ist als die gesamte Methode
Synchronisiert
quelle