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: