Frage Wie funktionieren Servlets? Instanziierung, Sitzungen, gemeinsame Variablen und Multithreading


Angenommen, ich habe einen Webserver, der zahlreiche Servlets enthält. Für Informationen, die zwischen diesen Servlets übergeben werden, setze ich Sitzungs- und Instanzvariablen.

Wenn jetzt zwei oder mehr Benutzer eine Anfrage an diesen Server senden, was passiert dann mit den Sitzungsvariablen? Werden sie alle für alle Benutzer gemeinsam sein, oder sie werden für jeden Benutzer unterschiedlich sein. Wenn sie anders sind, wie konnte dann der Server zwischen verschiedenen Benutzern unterscheiden?

Noch eine ähnliche Frage, wenn es welche gibt n Wenn Benutzer auf ein bestimmtes Servlet zugreifen, wird dieses Servlet nur beim ersten Zugriff auf den ersten Benutzer instanziiert oder wird es für alle Benutzer separat instanziiert? Mit anderen Worten, was passiert mit den Instanzvariablen?


989
2018-06-24 00:16


Ursprung


Antworten:


ServletContext

Wenn der Servlet-Container (z. B. Apache tomcat) gestartet wird, wird es alle seine Webanwendungen bereitstellen und laden. Wenn eine Webanwendung geladen wird, erstellt der Servlet-Container die ServletContext einmal und speichert es im Speicher des Servers. Die Web-App web.xml Datei wird analysiert, und jeder <servlet>, <filter> und <listener> gefunden (oder jede Klasse kommentiert mit @WebServlet, @WebFilter und @WebListener bzw.) wird einmalig instanziiert und im Speicher des Servers gespeichert. Für jeden instanziierten Filter ist sein init() Methode wird mit einem neuen aufgerufen FilterConfig.

Wenn der Servlet-Container heruntergefahren wird, werden alle Web-Anwendungen entladen und aufgerufen destroy() Methode aller initialisierten Servlets und Filter und alle ServletContext, Servlet, Filter und Listener Instanzen werden verworfen.

Wenn ein Servlet hat ein <servlet><load-on-startup> oder @WebServlet(loadOnStartup) Wert größer als 0, es ist init() Methode wird auch beim Start mit einem neuen aufgerufen ServletConfig. Diese Servlets werden in der gleichen Reihenfolge initialisiert, die durch diesen Wert angegeben wird (1 -> 1st, 2 -> 2nd usw.). Wenn derselbe Wert für mehr als ein Servlet angegeben wird, wird jedes dieser Servlets in der Reihenfolge geladen, in der sie in der Liste erscheinen web.xml, oder @WebServlet Classloading. Für den Fall, dass der Wert "Load-on-Startup" nicht vorhanden ist, init() Die Methode wird immer dann aufgerufen, wenn die HTTP-Anforderung das erste Mal auf dieses Servlet trifft.

HttpServletRequest und HttpServletResponse

Der Servlet-Container ist an einen Web-Server angeschlossen, der HTTP-Anfragen an einer bestimmten Port-Nummer abhört (Port 8080 wird normalerweise während der Entwicklung und Port 80 in der Produktion verwendet). Wenn ein Client (Benutzer mit einem Webbrowser) eine HTTP-Anforderung sendet, erstellt der Servlet-Container new HttpServletRequest und HttpServletResponse Objekte und übergibt sie durch beliebige definiert Filter Kette und schließlich die Servlet Beispiel.

Im Falle des Filter, das doFilter() Methode wird aufgerufen. Wenn der Code anruft chain.doFilter(request, response), gehen die Anfrage und die Antwort weiter zum nächsten Filter oder treffen das Servlet, wenn keine Filter mehr vorhanden sind.

Im Falle des Servlets, das service() Methode wird aufgerufen. Standardmäßig bestimmt diese Methode, welche der doXxx() Methoden zum Aufrufen basierend auf request.getMethod(). Wenn die bestimmte 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. die Header und den Hauptteil. Das Antwortobjekt bietet die Möglichkeit, die HTTP-Antwort so zu steuern und zu senden, wie Sie möchten, indem Sie beispielsweise die Header und den Body festlegen (normalerweise mit generiertem HTML-Inhalt aus einer JSP-Datei). Wenn die HTTP-Antwort festgeschrieben und abgeschlossen ist, werden sowohl das Anfrage- als auch das Antwortobjekt wiederverwendet und zur Wiederverwendung bereitgestellt.

HttpSitzung

Wenn ein Kunde die Webapp zum ersten Mal besucht und / oder die HttpSession wird erstmals über erhalten request.getSession(), der Servlet-Container erstellt einen neuen HttpSession Objekt, erzeugt eine lange und eindeutige ID (die Sie bekommen können session.getId()), und speichern Sie es im Speicher des Servers. Der Servlet-Container setzt auch a Cookie in dem Set-Cookie Header der HTTP-Antwort mit JSESSIONID wie der Name und die eindeutige Sitzungs-ID als Wert.

Gemäß der HTTP-Cookie-Spezifikation (Ein Vertrag, den ein anständiger Web - Browser und Web - Server einhalten müssen), der Kunde (der Web - Browser) ist verpflichtet, dieses Cookie bei nachfolgenden Anfragen im Internet zu senden Cookie Header, solange das Cookie gültig ist (d. h. die eindeutige ID muss sich auf eine nicht abgelaufene Sitzung beziehen und die Domäne und der Pfad sind korrekt). Über den integrierten HTTP-Datenverkehrsmonitor Ihres Browsers können Sie überprüfen, ob der Cookie gültig ist (drücken Sie F12 in Chrome / Firefox 23+ / IE9 + und überprüfen Sie die Netz / Netzwerk Tab). Der Servlet-Container prüft das Cookie Header jeder eingehenden HTTP-Anfrage für das Vorhandensein des Cookies mit dem Namen JSESSIONID und verwenden Sie seinen Wert (die Sitzungs-ID), um die Verbindung zu erhalten HttpSession aus dem Speicher des Servers.

Das HttpSession bleibt am Leben, bis es für mehr als den in angegebenen Zeitüberschreitungswert nicht verwendet wurde <session-timeout>, eine Einstellung in web.xml. Der Zeitüberschreitungswert beträgt standardmäßig 30 Minuten. Wenn der Client die Webanwendung nicht länger als die angegebene Zeit besucht, löscht der Servlet-Container die Sitzung. Jede weitere Anfrage, auch mit dem angegebenen Cookie, hat keinen Zugriff mehr auf die gleiche Sitzung; Der Servlet-Container erstellt eine neue Sitzung.

Auf der Clientseite bleibt der Sitzungscookie so lange aktiv, wie die Browserinstanz ausgeführt wird. Wenn der Client die Browser-Instanz (alle Registerkarten / Fenster) schließt, wird die Sitzung auf der Client-Seite gelöscht. In einer neuen Browser-Instanz wäre der mit der Sitzung verknüpfte Cookie nicht vorhanden und würde daher nicht mehr gesendet. Dies verursacht ein völlig neues HTTPSession erstellt werden, wobei ein völlig neuer Session-Cookie verwendet wird.

In einer Nussschale

  • Das ServletContext lebt so lange wie die Web App lebt. Es ist geteilt unter alle Anfragen in alle Sitzungen.
  • Das HttpSession Lebt so lange, wie der Client mit der Webanwendung mit derselben Browserinstanz kommuniziert und die Sitzung nicht auf der Serverseite abgelaufen ist. Es ist geteilt unter alle Anfragen in der gleich Session.
  • Das HttpServletRequest und HttpServletResponse leben ab dem Zeitpunkt, zu dem das Servlet eine HTTP-Anfrage vom Client erhält, bis die vollständige Antwort (die Webseite) angekommen ist. Es ist nicht an anderer Stelle geteilt.
  • Alle Servlet, Filter und Listener Instanzen leben so lange wie die Web-App lebt. Sie werden geteilt alle Anfragen in alle Sitzungen.
  • Irgendein attribute das ist in definiert ServletContext, HttpServletRequest und HttpSession wird so lange leben, wie das fragliche Objekt lebt. Das Objekt selbst repräsentiert den "Geltungsbereich" in Bean-Management-Frameworks wie JSF, CDI, Spring usw. Diese Frameworks speichern ihre Scoped-Beans als ein attribute seines engsten übereinstimmenden Umfangs.

Fadensicherheit

Das heißt, Ihr Hauptanliegen ist möglicherweise Fadensicherheit. Sie sollten jetzt wissen, dass Servlets und Filter unter allen Anfragen geteilt werden. Das ist das Schöne an Java, es ist Multithread und verschiedene Threads (lesen: HTTP-Requests) können dieselbe Instanz benutzen. Es wäre sonst zu teuer, um neu zu erstellen, init() und destroy() sie für jede einzelne Anfrage.

Sie sollten auch erkennen, dass Sie sollten noch nie Weisen Sie alle Anforderungen oder Daten für den Sitzungsbereich als ein Beispiel Variable eines Servlets oder Filters. Es wird unter allen anderen Anfragen in anderen Sitzungen geteilt. Das ist nicht fadensicher! 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:


1623
2018-06-24 02:41



Sitzungen

enter image description here enter image description here

Kurz gesagt: Der Webserver gibt eine eindeutige Kennung an jeder Besucher auf seinem zuerst Besuch. Der Besucher muss diesen Ausweis mitbringen, damit er das nächste Mal wiedererkannt wird. Diese Kennung ermöglicht dem Server auch, Objekte, die einer Sitzung gehören, ordnungsgemäß von denen einer anderen zu trennen.

Servlet Instanziierung

Ob Laden beim Start ist falsch:

enter image description here enter image description here

Ob Laden beim Start ist wahr:

enter image description here enter image description here

Sobald er auf dem Service-Modus und auf dem Groove ist, der gleich Servlet wird an den Anfragen von allen anderen Clients arbeiten.

enter image description here

Warum ist es nicht sinnvoll, eine Instanz pro Client zu haben? Denken Sie darüber nach: Werden Sie für jede Bestellung einen Pizzamann einstellen? Mach das und du bist in kürzester Zeit erledigt.

Es kommt jedoch mit einem kleinen Risiko. Erinnern Sie sich: Dieser einzelne Kerl hält alle Ordnungsinformationen in seiner Tasche: wenn Sie nicht so vorsichtig sind Fadensicherheit auf Servlets, kann er am Ende einem bestimmten Kunden die falsche Reihenfolge geben.


394
2017-07-06 16:38



Die Sitzung in Java-Servlets entspricht der Sitzung in anderen Sprachen wie PHP. Es ist einzigartig für den Benutzer. Der Server kann auf verschiedene Arten wie Cookies, URL-Rewriting usw. auf dem Laufenden bleiben Java-Dokument Artikel erklärt es im Zusammenhang mit Java-Servlets und zeigt an, dass genau, wie Sitzung beibehalten wird, ein Implementierungsdetail ist, das den Entwerfern des Servers überlassen wird. Die Spezifikation legt lediglich fest, dass sie für einen Benutzer über mehrere Verbindungen zum Server hinweg einmalig sein muss. Auschecken Dieser Artikel von Oracle für mehr Informationen über beide Fragen.

Bearbeiten Es gibt ein ausgezeichnetes Tutorial Hier wie man mit Session innerhalb von Servlets arbeitet. Und Hier ist ein Kapitel von Sun über Java Servlets, was sie sind und wie man sie benutzt. Zwischen diesen beiden Artikeln sollten Sie alle Ihre Fragen beantworten können.


40
2018-06-24 00:20



Wenn der Servletcontainer (wie Apache Tomcat) gestartet wird, liest er aus der web.xml-Datei (nur eine pro Anwendung), wenn etwas schief läuft oder auf der Containerseitenkonsole Fehler angezeigt wird. Andernfalls werden alle Webapplikationen über das Web bereitgestellt und geladen .xml (also als Deployment-Deskriptor bezeichnet).

Während der Instanziierungsphase des Servlets ist servletInstance bereit, kann aber die Clientanforderung nicht ausführen, da sie mit zwei Informationen fehlt:
1: Kontextinformationen
2: Anfangskonfigurationsinformation

Die Servlet-Engine erstellt ein ServletConfig-Schnittstellenobjekt, das die oben fehlenden Informationen in die Servlet-Engine einkapselt Die Servlet-Engine ruft init () des Servlets auf, indem sie servletConfig Objektreferenzen als Argument bereitstellt. Sobald init () vollständig ausgeführt wurde, ist das Servlet bereit, die Client-Anfrage zu bedienen.

Q) In der Lebenszeit von Servlet wie oft geschieht Instanziierung und Initialisierung?

A) nur einmal (für jede Client-Anfrage wird ein neuer Thread erstellt) Nur eine Instanz des Servlets bedient eine beliebige Anzahl der Client-Anfrage, dh nach der Zustellung stirbt ein Client-Anfrage-Server nicht. Es wartet auf andere Clientanforderungen dh welche CGI (für jede Client-Anforderung wird ein neuer Prozess erstellt) wird die Beschränkung mit dem Servlet (intern erzeugt die Servlet-Engine den Thread) überwunden.

F) Wie funktioniert das Sitzungskonzept?

A) wann immer getSession () auf HttpServletRequest Objekt aufgerufen wird

Schritt 1: Anforderungsobjekt wird auf eingehende Sitzungs-ID überprüft.

Schritt 2: Wenn die ID nicht verfügbar ist, wird ein brandneues HttpSession-Objekt erstellt und die entsprechende Sitzungs-ID generiert (dh von HashTable) Sitzungs-ID wird in httpservlet response object gespeichert und der Verweis des HttpSession-Objekts wird an servlet (doGet / doPost) zurückgegeben.

Schritt 3: Wenn die ID verfügbar ist, wird ein neues Sitzungsobjekt erstellt. Die Sitzungs-ID wird vom Anforderungsobjekt übernommen. Die Suche wird in der Sitzungssammlung durchgeführt, indem die Sitzungs-ID als Schlüssel verwendet wird.

Sobald die Suche erfolgreich ist, wird die Sitzungs-ID in HttpServletResponse gespeichert und die vorhandenen Sitzungsobjektverweise werden an doGet () oder doPost () von UserDefineservlet zurückgegeben.

Hinweis:

1) Wenn die Steuerung vom Servlet-Code zum Client geht, vergiss nicht, dass das Session-Objekt von servletcontainer, dh servletengine, gehalten wird

2) Multithreading wird den Servlevlern überlassen, um ie zu implementieren. Behandeln Sie die Mehrfachanforderung des Clients, um sich über Multithread-Code keine Gedanken zu machen

Kurzes Formular:

Ein Servlet wird beim Start der Anwendung (es wird auf dem Servlet-Container bereitgestellt) oder beim ersten Zugriff (abhängig von der Einstellung beim Start beim Start) erstellt. Wenn das Servlet instanziiert wird, wird die Methode init () des Servlets aufgerufen dann behandelt das Servlet (seine einzige Instanz) alle Anfragen (seine Methode service () wird von mehreren Threads aufgerufen). Aus diesem Grund ist es nicht ratsam, eine Synchronisierung zu verwenden, und Sie sollten Instanzvariablen des Servlets vermeiden Wenn die Anwendung nicht bereitgestellt wird (der Servlet-Container wird gestoppt), wird die Methode destroy () aufgerufen.


30
2018-02-22 12:54



Sitzungen- Was Chris Thompson gesagt hat.

Instanziierung - Ein Servlet wird instanziiert, wenn der Container die erste Anforderung erhält, die dem Servlet zugeordnet ist (es sei denn, das Servlet ist so konfiguriert, dass es beim Start mit dem Servlet geladen wird.) <load-on-startup> Element in web.xml). Dieselbe Instanz wird verwendet, um nachfolgende Anforderungen zu bedienen.


20
2018-06-24 00:27



Die Servlet-Spezifikation JSR-315 definiert eindeutig das Web-Container-Verhalten in den Methoden service (und doGet, doPost, doPut usw.) (2.3.3.1 Multithreading-Probleme, Seite 9):

Ein Servlet-Container kann gleichzeitig Anfragen über den Service senden   Methode des Servlets. Um die Anfragen zu bearbeiten, der Servlet-Entwickler   muss angemessene Vorkehrungen für die gleichzeitige Verarbeitung mit mehreren treffen   Threads in der Servicemethode.

Obwohl es nicht empfohlen wird, ist eine Alternative für den Entwickler   Implementieren Sie die SingleThreadModel-Schnittstelle, die den Container benötigt   um zu garantieren, dass es immer nur einen Anfrage-Thread in der   Service-Methode. Ein Servlet-Container kann diese Anforderung erfüllen   Serialisierung von Anforderungen in einem Servlet oder durch Wartung eines Servlet-Pools   Instanzen. Wenn das Servlet Teil einer Webanwendung ist, die dies getan hat   Als verteilbar markiert, kann der Container einen Servlet-Pool verwalten   Instanzen in jeder JVM, auf die die Anwendung verteilt ist.

Für Servlets, die die SingleThreadModel-Schnittstelle nicht implementieren, wenn der   Service-Methode (oder Methoden wie DoGet oder DoPost, die sind   an die Service-Methode der abstrakten HttpServlet-Klasse gesendet)   wurde mit dem synchronisierten Schlüsselwort, dem Servlet-Container, definiert   kann den Instanzpoolansatz nicht verwenden, muss jedoch Anforderungen serialisieren   durch. Es wird dringend empfohlen, dass sich Entwickler nicht synchronisieren   die Service-Methode (oder Methoden, die an sie gesendet werden) in diesen   Umstände wegen nachteiliger Auswirkungen auf die Leistung


13
2018-03-05 11:41



Nein. Servlets sind nicht sicher

Das is erlaubt den Zugriff auf mehr als einen Thread gleichzeitig

Wenn du Servlet als Thread sicher machen willst, kann U gehen

Implement SingleThreadInterface(i)  was eine leere Schnittstelle ist, gibt es keine

Methoden

oder wir können Methoden synchronisieren

Wir können die gesamte Service-Methode als synchronisiert mit synchronisiert verwenden

Keword vor der Methode

Beispiel::

public Synchronized class service(ServletRequest request,ServletResponse response)throws ServletException,IOException

oder wir können den Block des Codes in den Synchronisierten Block setzen

Beispiel::

Synchronized(Object)

{

----Instructions-----

}

Ich finde, dass Synchronized Block ist besser als die ganze Methode

Synchronisiert


0
2018-04-14 15:32