Warum implementiert HttpServlet Serializable?

77

Nach meinem Verständnis von Servlet wird das Servlet vom Container instanziiert, seine init()Methode wird einmal aufgerufen und das Servlet wird wie ein Singleton leben, bis die JVM heruntergefahren wird.

Ich erwarte nicht, dass mein Servlet serialisiert wird, da es neu erstellt wird, wenn der App-Server wiederhergestellt oder normal gestartet wird. Das Servlet sollte keine sitzungsspezifischen Mitglieder enthalten, daher ist es nicht sinnvoll, es auf die Festplatte zu schreiben und erneut zu instanziieren. Gibt es eine praktische Verwendung dafür?

Ich befürchte, dass ich dort einige nicht serialisierbare Felder einfüge und meine App dann in einer Produktionsumgebung, in der eine andere Art der Sitzungsreplikation stattfindet, auf mysteriöse Weise fehlschlägt.

Andreas Petersson
quelle

Antworten:

59

Technisch gesehen glaube ich, dass der Servlet-Container das Servlet-Objekt auf die Festplatte "passivieren" darf, ähnlich wie es EJB-Session-Beans sein können. Sie stellen also zu Recht die Frage, ob Ihre App aufgrund nicht serialisierbarer Felder fehlschlägt.

In der Praxis habe ich noch nie von einem Container gehört, der dies tut. Es handelt sich also nur um Altgepäck aus den schlechten alten Zeiten des frühen J2EE. Ich würde mir darüber keine Sorgen machen.

Skaffman
quelle
1
Aber wer muss ein Servlet passivieren, wenn es threadsicher sein soll und keinen Konversationsstatus hat?
Amir Pashazadeh
1
Damit Cluster-Server nicht ausfallen und die Sitzung im Falle eines Ausfalls einem ähnlichen Fehler zugeordnet werden kann, wird dies
Dev
2
@dev Der Fehler betrifft nicht serialisierbare Sitzungsattribute, NICHT die Serialisierung von Servlets.
Arend v. Reinersdorff
Dies kann durch <distributable />in web.xml ausgelöst werden .
Archimedes Trajano
11

HttpServlet sollte auf die Festplatte serialisiert werden und den Neustart des Servlet-Containers überleben. Mit Tomcat können Sie beispielsweise ein Flag einrichten, das diese Art des Überlebens ermöglicht. Die nächste Option ist die Übertragung mit JNDI. Dies ist kein Müll, sondern wird nur in extremen Anwendungsfällen verwendet.

Rastislav Komara
quelle
Ist JNDI der einzig richtige Weg, um Felder festzulegen, die nicht serialisierbar sind? Es ist so schrecklich. :(
Trejkaz
1

Google scheint darauf hinzuweisen, dass dies getan wurde, damit Containerautoren die Option haben können, wenn sie dies wünschen.

Sie haben Recht, dass das Servlet keine sitzungsspezifischen Mitglieder enthalten sollte. Ich würde sogar denken, dass Sie so wenig Status wie möglich wünschen. Wenn Sie alles in Session oder ServletConfig speichern, können Sie die Serialisierung wahrscheinlich überleben.

matt b
quelle
2
Nun, es ist weitaus wahrscheinlicher, dass die Sitzung serialisiert wird als das Servlet, sodass das Speichern dort das Problem nicht mindern würde.
Skaffman
1
@matt b: Das Problem ist weniger der sitzungsspezifische Status als vielmehr die Abhängigkeiten des Servlets (z. B. Objekte der Serviceschicht)
Andrew Swan,
0

Genau wie Sitzungsobjekte serialisiert werden, um Caches für die Servlet-Container zu überleben, die die Cluster-Option angeben, gibt es möglicherweise eine Option für einen Container, um eine Servlet-Instanz auch auf einen anderen Cluster-Knoten zu übertragen. Ich rate nur hier

anjanb
quelle
-3

Serializable wird als Markierungsschnittstelle für Sitzungsattribute in verteilten Umgebungen verwendet.

SRV.7.7.2 Verteilte Umgebungen (JSR-154)

Innerhalb einer als verteilbar gekennzeichneten Anwendung müssen alle Anforderungen, die Teil einer Sitzung sind, jeweils von einer Java Virtual Machine („JVM“) verarbeitet werden. Der Container muss in der Lage sein, alle Objekte, die in Instanzen der HttpSession-Klasse platziert wurden, mit den Methoden setAttribute oder putValue entsprechend zu verarbeiten. Die folgenden Einschränkungen werden auferlegt, um diese Bedingungen zu erfüllen:

  • Der Container muss Objekte akzeptieren, die die serialisierbare Schnittstelle implementieren .
  • Die Migration von Sitzungen wird von container-spezifischen Einrichtungen durchgeführt.

Der verteilte Servlet-Container muss eine IllegalArgumentException für Objekte auslösen, bei denen der Container den für die Migration der Sitzung, in der sie gespeichert sind, erforderlichen Mechanismus nicht unterstützen kann .

Der verteilte Servlet-Container muss den Mechanismus unterstützen, der für die Migration von Objekten erforderlich ist , die Serializable implementieren .

(...)

Der Containeranbieter kann Skalierbarkeit und Dienstqualitätsfunktionen wie Lastausgleich und Failover sicherstellen, indem er ein Sitzungsobjekt und seinen Inhalt von einem aktiven Knoten des verteilten Systems auf einen anderen Knoten des Systems verschieben kann. Wenn verteilte Container Sitzungen beibehalten oder migrieren , um Dienstqualitätsfunktionen bereitzustellen, sind sie nicht auf die Verwendung des nativen JVM-Serialisierungsmechanismus zum Serialisieren von HttpSessions und ihrer Attribute beschränkt. Entwicklern wird nicht garantiert, dass Container die Methoden readObject und writeObject für Sitzungsattribute aufrufen, wenn sie diese implementieren. Es wird jedoch garantiert, dass der serialisierbare Abschluss ihrer Attribute erhalten bleibt .

Maciek Kreft
quelle
3
Dies ist eine irreführende Antwort. Eine Servlet-Instanz wird normalerweise nicht in der Sitzung gespeichert.
BalusC