$KK(Der JSP Life Cycle) $R(Objective) Describe the purpose and event sequence of the JSP page life cycle: (1) JSP page translation, (2) JSP page compilation, (3) load class, (4) create instance, (5) call the jspInit method, (6) call the _jspService method, and (7) call the jspDestroy method. $R\ $KKK(Die 7 Phasen eines JSP Lebenszyklus) Eine JSP Seite durchläuft folgende 7 Phasen $T(caption,ll) Phase | Beschreibung || Übersetzung | Die JSP Seite wird geparst und es wird daraus eine Java-Datei mit dem entsprechenden Servlet erzeugt || Kompilieren | Die erzeugte Datei wird compiliert || Klasse einladen | Die compilierte Klasse wird eingeladen || Instantiierung | Es wird eine Instanz eines Servlets erzeugt || jspInit() | Diese Methode ermoeglicht die Initialisierung des Objekts || _jspService() | Diese Methode wird für jede Anfrage ausgeführt || jspDestroy() | Diese Methode wird aufgerufen, bevor der Container die Instanz dieses Servlet zerstört || $T\ Die Übersetzung Zunächst wird überprüft, ob sich die JSP seit der letzten Übersetzung geändert hat. Falls ja finden einige Überprüfungen statt, und es werden die Direktiven ausgewertet. Das Ergebnis ist eine Datei mit Java Code. Der Name der Klasse ist abhängig vom verwendeten Container. Kompilieren Die erzeugte Java Klasse wird mit einem normalen Java Compiler compiliert. Laden und Instantiieren Die geladene Instanz sollte (falls Http verwendet wird) das folgende Interface HttpJspPage erfüllen: $S() public interface JspPage extends Servlet { public void jspInit(); public void jspDestroy(); public void _jspService(ServletRequestSubtype request, ServletResponseSubtype response) throws ServletException, IOException; // _jspService - depends on the specific protocol used and // cannot be expressed in a generic way in Java. } public interface HttpJspPage extends JspPage { public void _jspService(HttpServletRequest req, HttpServletResponse res) throws javax.servlet.ServletException, java.io.IOException; } $S\ Die Methode jspInit() Diese Methode wird direkt nach der Instaniierung, auf jedenfall vor der ersten Anfrage ausgeführt. Man kann diese Methode als Skriplet in die JSP Seite deklarieren. $S() <%! public void jspInit() { ... } %> $S\ Beachte man ist nicht gezwungen, diese Methode zu deklarieren. Sie existiert schon in der Basisklasse. Die Methode jspDestroy() Diese Methode wird aufgerufen, wenn der Container entschlossen hat, das entsprechende Servlet auszuladen. Auch diese Methode muss nur dann deklariert werden, wenn man sie wirklich benötigt. $S() <%! public void jspDestroy() { ... } %> $S\ Die Methode _jspService() Diese Methode wird automatisch bei jeder Anfrage aufgerufen. Diese Methode wird bei der Übersetzung der JSP in das Servlet automatisch generiert. Es führt zu einem Fehler wenn der Programmierer versucht diese Methode zu deklarieren. $KKK(Translatation Unit) Mit Hilfe der include Direktive kann man den Inhalt einer anderen Seite (statisch oder wieder eine JSP) einbinden. Es wird nicht nur die aktuelle Seite, sondern auch die eingebundenen Seiten in ein einziges Servlet übersetzt. Die Menge an Seiten die in ein einziges Servlet übersetzt werden, wird Translation Unit genannt. Für eine Translation Unit gilt einige Regeln: * Die Page Direktiven beziehen sich auf die ganze Translation Unit. * Eine Variable Deklaration oder eine Methoden Dekleration darf nicht innerhalb einer Translation Unit mehrmals vorkommen. * Die Standard Aktion jsp:useBean kann nicht innerhalb einer Translation Unit zweimal dieselbe JavaBean deklarieren. $KKK(Übersetzung einer JSP im Detail) * Die Direktiven werden während der Übersetzung ausgewertet. Einige Direktive wie die page Direktive mit Attribut import erzeugen Code in der ServletKlasse. Andere Direktiven setzen Eigenschaften einer Seite fest, und führen nicht zu einem Code in das Servlet. * Alle Deklarationen werden in die zu übersetzende Servlet Klasse eingebaut, Variablen Deklarationen werden zu Instanzvariablen umgewandelt, Methoden Deklarationen werden Methoden des Servlets. * Alle JSP Scriplets werden Teil der _jspService() Methode.Variablen innerhalb eines Skriplets werden zu lokalen Variablen der _jspService() Methode. * Auch alle Ausdrücke und EL Ausdrücke werden Teil der _jspService() Methode. Für EL Ausdrücke werden durch spezielle Klassen ausgewertet. Die herkömmlichen JSP Ausdrücke werden durch eine out.print() Methode umwickelt. * Alle JSP Aktionen werden durch Aufrufe an entsprechende Klassen ersetzt * Ausdrücke (EL oder ordinär) die innerhalb einerhalb einer Aktion einem Attribut einen Wert zuweisen, werden nicht mit out.print ausgegeben. Der Ausdruck wird in diesem Fall während einer Anfrage ausgewertet, dem Attribut zugewiesen und der Aktion entspechenden Java Klasse aufgerufen. * Alle JSP Kommentare werden ignoriert. * Die Template Texte werden Teil der _jspService() Methoden und in die Methode out.write() umwickelt. Beachte einige Besonderheiten: * Es ist nicht wichtig in welcher Reihenfolge die Deklarationen in der JSP Seite erscheinen. Beispiel: $S() pi = <%=pi%> <%! final double pi=3.1414 %> $S\ Das Beispiel ergibt kein Fehler obwohl die Deklaration von pi erst nach der Benutzung erfolgt. * Bei Skriplets spielt die Reihenfolge der Variablendeklarationen sehr wohl eine Rolle $S() <% String s = s1+s2; %> <%! String s1 = "hello"; %> <% String s2 = "world"; %> <% out.println(s); %> $S\ Dieses Beispiel scheitert in der Zeil String s = s1+s2;. Das Problem liegt nicht in der Varialbe s1, da diese in einer Deklaration ist, und in eine Instanzvariable übersetzt wird. Das Problem liegt in der lokalen Variablen s2, die zu spät deklariert und definiert wird. * Iterative und Conditionale Ausdrücke Man sollte darauf achten dass bei Schleifen, immer in Skriplets immer die Klammern gesetzt werden, auch dann wenn man scheinbar nur eine Anweisung hat. Siehe z.B folgenden JSP-Code: $S() <% if (isUserLoggedIn) %> Welcome, <%= userName %> $S\ Dies wird folgendermassen übersetzt: $S() if (isUserLoggedIn) out.write("Welcome, "); out.print(username); $S\ Der Anwendername wird auch angegeben, wenn isUserLoggedIn den Wert false hat. So wäre es richtig: $S() <% if (isUserLoggedIn) { %> Welcome, <%= userName %> <% } %> $S\