11 Stimmen

Lebenszyklus von JSP-Tags

Ich habe gerade einen Fehler in meinen Code eingebaut, weil ich den Lebenszyklus des JSP-Tags anscheinend falsch verstanden habe.

Vor dem Fehler funktionierte der Tag folgendermaßen: Ich übergebe dem Tag eine Sammlung als Attribut, und es zeigt sie als Tabelle an. Die Sammlung wurde vom Controller an die JSP übergeben.

Nach der Wanze: Ich habe das Attribut entfernt, das die Sammlung festlegt. Stattdessen prüfe ich im Tag, ob die Sammlung null ist, und entnehme sie dann dem Namen nach der Anforderung (unter Verwendung einer Namenskonvention).

Die Sache, die ich nicht erwartet hatte: Nachdem die Auflistung zunächst im Tag festgelegt wurde, wird sie bei nachfolgenden Ausführungen niemals null! Es war immer noch als ein nicht erforderliches Attribut in der TLD definiert.

I erwartet das Tag, um frühere Werte zwischen den Ausführungen nicht beizubehalten.

12voto

Olaf Kock Punkte 44749

Sie haben die Frage selbst beantwortet - es wird zusammengelegt. Siehe die Tag-Tutorial was in Java-Implementierungen zu implementieren ist, zusammen mit der von dort verlinkten Seite, die die Aufrufreihenfolge :

ATag t = new ATag();
t.setPageContext(...);
t.setParent(...);
t.setAttribute1(value1);
t.setAttribute2(value2);
t.doStartTag();
t.doEndTag();
t.release();

Das heißt, Sie müssen Ihre Tag-Instanz in doEndTag() neu initialisieren, wie es die API verlangt. (geändert aufgrund eines Kommentars von Julien Kronegg, danke)

Beachten Sie, dass das Pooling wahrscheinlich von den Containern abhängt, aber durchaus legal ist (und aufgrund der API-Einrichtung wahrscheinlich überall durchgeführt wird).

8voto

user196621 Punkte 81

Die kurze Antwort: Sie sollten nicht selbst in die Attributeigenschaften schreiben. Wenn Sie dies tun, sind Sie für die Reinigung des Zustands verantwortlich.

Für eine längere Antwort, die JSP 2.0 Spezifikation schreibt das Folgende vor (Seite 2-51):

  • Setzer werden für alle angegeben Attribute eines bestimmten Vorkommens eines Tags
  • Einsteller sind pas gefordert unterlassen Attribute (wobei die Standardwerte erhalten bleiben und in Ihrem Fall ein unzulässiger Wert im internen Status)
  • Tag-Handler dürfen nur von Vorkommen mit demselben Satz angegebener Attribute wiederverwendet werden

Diese drei Punkte zusammen garantieren, dass die Attributeigenschaften immer korrekt initialisiert werden, wobei die (in einem Konstruktor oder einer Eigenschaftsdeklaration definierten) Standardwerte erhalten bleiben. Im Gegenzug funktioniert es nur unter der Annahme, dass nur der Container Attributeigenschaften manipuliert (durch Aufruf der Setter).

Der Vollständigkeit halber:

  • release() sollte nicht verwendet werden, um den internen Zustand zwischen Aufrufen eines Tag-Handlers zurückzusetzen. Es wird nur garantiert, dass es vor der GC aufgerufen wird, und sollte dazu verwendet werden, langfristige Ressourcen freizugeben.
  • Wenn Sie die Instanzvariablen in doStartTag() Achten Sie darauf, dass Sie keine Attribute überschreiben, da die Setter zu diesem Zeitpunkt bereits vom Container aufgerufen wurden.
  • doEndTag() sollte für die Initialisierung sicher sein, da Tags im Falle einer Ausnahme nie wieder verwendet werden sollten (siehe Seite 2-54 [2])

3voto

Nicko Punkte 3203

In der JSP 1.2-Spezifikation wurde die Schnittstelle TryCatchFinally hinzugefügt. http://docs.oracle.com/javaee/1.4/api/javax/servlet/jsp/tagext/TryCatchFinally.html

Es sieht also so aus, dass Sie die Ressourcen in der doStartTag()-Methode zuweisen und in der doFinally()-Methode aufräumen sollten.

1voto

mkoryak Punkte 55621

Die Antwort lautet also: Das Tag wird in einem magischen Pool gepoolt und zwischen den Ausführungen wiederverwendet:

"Nicht spezifizierte Attribute/Eigenschaften sollten nicht gesetzt werden (mit einer Setter-Methode)".

0voto

Die Beobachtung von Tomcat 6 legt nahe, dass release() nur aufgerufen wird, wenn der Container heruntergefahren wird. Tag-Handler-Instanzmitglieder sollten den Instanzstatus in doEndTag() löschen. Aus dem api Dokument:

"Alle mit dieser Instanz verbundenen Zustände müssen zurückgesetzt werden.

siehe [TagSupport.doEndTag()](http://java.sun.com/products/servlet/2.2/javadoc/javax/servlet/jsp/tagext/TagSupport.html#doEndTag())

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X