Softwaretechnik Servlets / JSP Thomas Perschke
Rückblick Servlets Einfache Servlets Auswerten von Form-Daten
Heute JSP
Servlet - JSP HTML-Code wird im Servlet-Code erzeugt Darstellung und Logik vereint Java und HTML-Know-How notwendig Änderung der Darstellung hat Änderung des Servlet-Codes zur Folge Keine Nutzung von HTML-Entwicklungstools möglich Langer Entwicklungszyklus Lösung: JSP
JSP Java Server Pages Technologie für die Entwicklung dynamischer Web-Seiten Kein Produkt, sondern offene Spezifikation Ermöglicht die Auslagerung der HTML-Formatierung Trennung von Businesslogik und Darstellung Ermöglicht das Einbetten von speziellem Code in eine HTML- Seite anstelle der Einbettung von HTML-Code in den Programmcode JSP-Seiten bestehen aus HTML-Code Eingebettete JSP-Elemente JSP-Elemente werden serverseitig aufgelöst, bevor die Ergebnisseite zurück gesendet wird JSP-Seiten liegen auf dem Server compiliert vor Gutes Zusammenspiel von JSP und Servlets Voraussetzung: JDK, JSP-fähiger Web-Server
Konkurrierende Technologien ASP Ermöglicht das Integrieren von Programmcode in eine HTML-Seite (VBScript, JScript) Ermöglicht das Einbinden und Aufrufen von ActiveX-Komponenten Datenbankzugriff, andere Komponenten von Drittanbietern Funktionsweise wie bei JSP Microsoft-spezifische Funktionen, nur limitierter Support für andere Plattformen PHP Open Source Web Scripting Language C-ähnliche Syntax mit einigen Features von Perl, C++ und Java Große Anzahl an vordefinierten Funktionen (DB-Zugriff, LDAP, generieren von PDF-Dokumenten und Bilder) Funktionsweise wie bei JSP Unterstützt eine große Anzahl von Plattformen
Beispiel einer JSP-Seite <%@ page language="java" contenttype="text/html" %> <html> <head><title>meine JSP-Seite</title></head> <body> <h1>meine erste JSP-Seite</h1> <% java.util.date clock = new java.util.date() %> <% if(clock.gethours()<12){ %> <h2>guten Morgen</h2> <html> <html> <% } else if(clock.gethours()<18) <head><title>meine { %> JSP- JSP- <h2>guten Tag</h2> Seite</title></head> <% } else { %> <body> <body> <h2>guten Abend</h2> <h1>meine <h1>meine erste erste JSP-Seite</h1> JSP-Seite</h1> <% } %> <h2>guten <h2>guten Tag</h2> Tag</h2> </body> </body> </body> </html> </html> </html>
JSP-Elemente Direktive beschreibt Informationen über die Seite selbst Ändern sich nicht zwischen zwei Seitenaufrufen Direktive Elemente <%@ page... %> Seitenabhängige Attribute wie Script-Sprache, Fehlerseite <%@ include... %> Einbindung von Dateien währende der Übersetzungsphase <%@ taglib... %> Deklaration von Tag Libraries <%@ page errorpage= errorpage.jsp %> <%@ page iserrorpage= true %>
JSP-Elemente Standard Action Elemente Dienen zum Ausführen von Aktionen Basieren meist auf weiteren Informationen (Request- Parameter, Informationen von externen Systemen,...) Das Ergebnis der Aktion kann von Aufruf zu Aufruf unterschiedlich sein Action Elemente <jsp:usebean> Ermöglicht den Zugriff auf JavaBeans <jsp:getproperty>, <jsp:setproperty> Holt/Setzt den Wert eines bestimmten Attributes eines Beans <jsp:forward> Leitet die Bearbeitung eines Requests an eine JSP-Seite oder an eine Servlet weiter
JSP-Elemente Scripting Elements Ermöglichen das Einbetten kleiner Code-Fragmente in eine JSP-Seite (if, while,...) Scripting Elements: <%... %> Scriptlet, dient zur Einbindung von ScriptingCode <%=... %> Expression, dient zur Einbindung von Java-Ausdrücken, bei denen das Ergebnis der Seite hinzugefügt werden soll <%!... %> Deklaration, dient zur Deklaration von Instanzvariablen und Methoden in einer JSP-Seite
JSP Processing
Hello-World Servlet
Hello World JSP-Seite
Von JSP-Seite generiertes Servlet
Einschub: JavaBeans JavaBeans sind alle Javaklassen, die folgenden Bedingungen genügen: Implementieren das Interface java.io.serializable Verfügen über einen leeren Konstruktor Für den Zugriff auf die Attribute stehen get- und set-methoden zur Verfügung, die einer Namenskonvention genügen: Die get-/set-methoden beginnen mit get/set und Enden mit dem Attributname, wobei der erste Buchstabe des Attributes groß geschrieben ist Beispiel: Attribute: String name Get-Methode: public String getname()... Set-Methode: public void setname(string newname)...
Einschub: JavaBean - Beispiel public class Person { private String name; private String fname; private String email; private String pwd; public Person(){ } public void setname(string newname){ name = newname; } public String getname(){ return name; }... }
Beispiel: Person <%@ page language="java" contenttype="text/html" %> <html> <head><title>aktuelle Uhrzeit</title></head> <body> <jsp:usebean id="person" class= Person"></jsp:useBean> Die Daten der Person sind: <ul> <li>name: <jsp:getproperty name="person" property="name"></jsp:getpropert <li>vorname: <jsp:getproperty name="person" property="fname"></jsp:getpro <li>email: <jsp:getproperty name="person" property="email"></jsp:getprope <li>kennwort: <jsp:getproperty name="person" property="pwd"></jsp:getprop </ul> </body> </html>
Übergabe von Parametern (1) <html> <head><title>zeit eingeben</title></head> <body> Geben Sie das aktuelle Datum ein: <form method="post" action="zeit2.jsp"> <input type="text" name="hours" size="2">: <input type="text" name="minutes" size="2"> <br><input type="submit" value="go"> </form> </body> </html>
Übergabe von Parametern (2) <%@ page language="java" contenttype="text/html" %> <html> <head><title>eingegebene Uhrzeit</title></head> <body> <jsp:usebean id="clock" class="java.util.date scope= request > <jsp:setproperty name="clock" property="*"></jsp:setproperty> </jsp:usebean> Die eingegebene Zeit ist: <br>stunden: <jsp:getproperty name="clock" property="hours"></jsp:getproperty> <br>minuten: <jsp:getproperty name="clock" property="minutes"></jsp:getproperty> </body> </html>
Implizite JSP-Objekte Request Instanz der Klasse javax.servlet.http.httpservletrequest Ermöglicht Zugriff auf alle Informationen des Requests Response Instanz der Klasse javax.servlet.http.httpservletresponse Ermöglicht Zugriff auf alle Informationen des Response Exception Nur in Fehlerseiten verfügbar Liefert Informationen zum aufgetretenen Fehler
Beispiel: Request-Informationen <%@ page language="java" contenttype="text/html" %> <html> <head><title>eingegebene Uhrzeit</title></head> <body> <h1>request-informationen</h1>s Remote-Host: <%= request.getremotehost() %> <br>remote-addr: <%= request.getremoteaddr() %> <br>browserkennung: <%= request.getheader("user-agent") %> <br>protocol: <%= request.getprotocol() %> <br>parameter1: <%= request.getparameter("param1") %> <br>parameter2: <%= request.getparameter("param2") %> </body> </html>
Datenaustausch zwischen JSP und Servlets Scope Bestimmt, wie lange und für welche User gemeinsame Informationen gültig sind Page Sichtbar nur innerhalb der Seite Request Sichtbar innerhalb aller Seiten, die den gleichen eines Request abarbeiten Session Sichtbar innerhalb einer Session, u.u. über mehrere Requests hinweg Application Sichtbar innerhalb der Applikation, also sichtbar für alle User der gleichen Applikation
Beispiel: Datenaustausch ServletJSP (1) private synchronized void handlegetpersonaction( HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { Person person = new Person(); person.setname("perschke"); person.setfirstname("thomas"); person.setemail("bavs@perschke.info"); person.setpassword("tp"); request.setattribute("p1", person); RequestDispatcher rd = request.getrequestdispatcher("person.jsp"); rd.forward(request, response); }
Beispiel: Datenaustausch ServletJSP (2)... <body>... <jsp:usebean id="p1" scope="request" class= Person" /> <p>angaben zur Person: <br>name: <%= p1.getname() %> <br>vorname: <%= p1.getfirstname() %> <br>email: <%= p1.getemail() %>... <p>passwort: <jsp:getproperty name="p1" property= password %> </jsp:getproperty>...
Beispiel: Datenaustausch ServletJSP (3)... <body>... <jsp:usebean id= personen" scope="request" class= java.util.vector" /> <% for(int i=0; i<personen.size; i++){ %> <% Person eineperson = (Person)personen.elementAt(i); %> <p>angaben zur Person <%= (i+1) %>: <br>name: <%= eineperson.getname() %> <br>vorname: <%= eineperson.getfirstname() %> <br>email: <%= eineperson.getemail() %>... <p>passwort: <jsp:getproperty name= eineperson property= password %> </jsp:getproperty>...... <% }//end of for %>
JSP-Tags Problem: Grundlegende Java-Kenntnisse notwendig - Mangelnde Portierbarkeit durch Bindung an Servlet - Lösung: - Erzeugen eigener Tags zur Kapselung oft benötigter Funktionen - Ziel: - Vollständige Befreiung der JSP von Java-Code - Leichtere Wiederverwendung - Nutzung von Tag-Bibliotheken (JSP Standard Tag Library,...)
JSP-Tags: Beispiel iterator-tag Der iterator-tag soll dazu dienen, bestimmte HTML- Fragmente zu vervielfältigen. Vorher: Nachher: <%@ page language="java" [...] %> <html> [...] <body> <% for(int i=0; i<3; i++){ %> <p>carpe Diem: Genieße den Tag!</p> <% } %> </body> </html> <%@ taglib uri= [...] prefix= mytags %> <html> [...] <body> <mytags:iterate times= 3 > <p>carpe Diem: Genieße den Tag!</p> </mytags:iterate> </body> </html>
Ein eigenes Tag Vorgehensweise: 1. Erstellen der Java-Klasse 2. Konfiguration des Tag-Handlers 3. Einbinden der Tag-Bibliothek 4. Verwenden des Tags in einer JSP
Ein eigenes Tag Erstellen der Java-Klasse Erstellen der benötigten Java-Klasse, die die Funktionalität aufnimmt (Tag-Handler) Java stellt dabei im Paket javax.servlet.jsp.tagext verschiedene Interfaces bereit. Kürzer: Verwendung der Klassen TagSupport und BodyTagSupport und überschreiben der Methoden [...] public class IterationTag extends BodyTagSupport implements BodyTag { [...] }
Ein eigenes Tag Erstellen der Java-Klasse Lebenszyklus eines Tags <html> [...] Hier wird die Methode dostarttag() aufgerufen EVAL_BODY_INCLUDE SKIP_BODY <tag> [...] z.b. Text oder weitere Tags [...] </tag> Rumpf Hier wird die Methode doinitbody() aufgerufen Hier wird die Methode doafterbody() aufgerufen SKIP_BODY EVAL_BODY_AGAIN [...] Hier wird die Methode doendtag() aufgerufen </html> SKIP_PAGE Hier beginnt die Bearbeitung des nächsten Tags Ende des Dokuments
Ein eigenes Tag Erstellen der Java-Klasse Beispiel: Iterator-Tag public class IterationTag extends BodyTagSupport [...] { private int iterations = 0; public void settimes(integer value){ iterations = value; } public int doafterbody(){ BodyContent body = getbodycontent(); JspWriter out = body.getenclosingwriter(); try{ for(int i=0; i<iterations; i++){ out.print(body.getstring()); } }catch(ioexception e){[...]}; return SKIP_BODY; } }
Ein eigenes Tag Erstellen der Java-Klasse Viele Servlet-Container verwalten ihre Tags über einen Pool. Aus diesem Grund sollten Tag-Handler, die einen zustand besitzen, über die Methode release() in den Ausgangszustand zurückgesetzt werden. Die Methode release() wird vom Servlet- Container nach Beendigung des Tag-Lebenszyklus aufgerufen. public class IterationTag extends BodyTagSupport [...] { [...] public void release(){ iterations = 0; } }
Ein eigenes Tag Konfiguration des Tag-Handlers Dem Servlet-Container muss nun mitgeteilt werden, für welcher Tag-Handler für welches Tag zuständig ist. Was bei den Servlets der Deployment-Descriptor ist, wird in Tag-bibliotheken Tag Library Descriptor genannt (TLD). <?xml version="1.0" encoding="iso-8859-1"?> <!DOCTYPE taglib PUBLIC [...] > <taglib> [...] <tag> <name>iterate</name> <tag-class>iterationtag</tag-class> <attribute> <name>times</name> <required>true</required> <type>java.lang.integer</type> </attribute> </tag> [...] </taglib>
Ein eigenes Tag Einbinden der Tag-Bibliothek Der TLD wird üblicherweise unterhalb des Verzeichnisses webinf im Dateisystem abgelegt Im Web-Deployment-Descriptor wird der TLD dann verfügbar gemacht <?xml version="1.0" encoding="iso-8859-1"?> <!DOCTYPE web-app PUBLIC [...]> <web-app> [...] <taglib> <taglib-uri>/mytags</taglib-uri> <taglib-location>/web-inf/tlds/mytags.tld</taglib-location> </taglib> [...] </web-app>
Ein eigenes Tag Verwendung in der JSP <%@ taglib uri= [...] prefix= mytags %> <html> [...] <body> <mytags:iterate times= 3 > <p>carpe Diem: Genieße den Tag!</p> </mytags:iterate> </body> </html>