Java-Server-Pages Dynamische Html Seiten mit JSP generieren Prof. Dr. Nikolaus Wulff Agenda • Herausforderungen und Lösungsansätze • Prinzip der Java Server Pages • Syntax • Eigene Taglibs Prof. Dr. Nikolaus Wulff eCommerce WS 2004 2 Das optimale Konzept • Web-Design und Programmierung kann von jeweiligen Experten vorgenommen werden • Trennung der Datenverarbeitung von der Darstellung der Daten • Objektorientiert • Plattformunabhängig • Performant Prof. Dr. Nikolaus Wulff eCommerce WS 2004 3 Java Server Pages • Ermöglichen Aufgabenverteilung (Design und Codierung) bei der Entwicklung • Trennung nach dem Model-View-Controller-Pattern • Plattformunabhängig • Alle Bibliotheken des JDK stehen zur Verfügung • Sehr gute Unterstützung von Multithreading • Strukturiertes Exception-Handling • Gute bis sehr gute Performance: – Kompilierung der Seite erfolgt nur beim ersten Aufruf – Java auf Server-Seite ist schnell! Prof. Dr. Nikolaus Wulff eCommerce WS 2004 4 Andere Technologien • Die meisten Techniken unterstützen keine Trennung der Datenverarbeitung von der Darstellung (z.B. Perl, PHP) • CGI-Skripte starten bei jedem Aufruf einen Prozess auf dem Server • Häufig aufwendiges Session-Management (z.B. Perl) • Servlets erlauben kein normales Design einer Webseite • Active Server Pages sind konzeptionell sehr ähnlich, aber: – Ist auf Microsoft-Plattformen beschränkt – Basiert auf Visual Basic. – Verwendet ActiveX-Controls. Prof. Dr. Nikolaus Wulff eCommerce WS 2004 5 Architektur-Überblick Web Container EJB Container Servlet JSP EJB HTTP JAF Präsentation Präsentation Geschäftslogik • Darstellung von HTML, XML • Session Verwaltung • Use Cases • HTML Generierung • Business Objects JDBC Java Mail RM I- IIOP JTA JNDI JMS JAF JDBC JTA JNDI JMS Java Mail RM I/IIOP Browser RMI IIOP Database • ggf. Scripting Prof. Dr. Nikolaus Wulff eCommerce WS 2004 6 Hello World! Eine einfache Java Server Page: <HTML> <BODY> <% out.println(„Hello JSP World!“); %> </BODY> </HTML> Prof. Dr. Nikolaus Wulff eCommerce WS 2004 7 Prinzip der Java Server Pages • HTML-Design mit Tool nach Wahl (z.B. Dreamweaver) • Einfügen des Java-Codes mit geeignetem Editor, Dateiendung *.jsp • Bereitstellen der Datei im entsprechenden Verzeichnis auf dem Webserver • Beim ersten Aufruf durch einen Client kompiliert der Webserver die JSP in ein Servlet • Bei einem erneuten Abruf der Seite prüft der Webserver, ob sich die Seite geändert hat. Falls nein, wird das zuvor kompilierte Servlet ausgeführt. Prof. Dr. Nikolaus Wulff eCommerce WS 2004 8 Übung • Im ersten Schritt soll eine einfache HTML-Seite erstellt und auf dem Webserver bereitgestellt werden. • Anschließend erfolgt die Umwandlung in eine JSP und die Ausgabe des aktuellen Datums innerhalb der JSP. • Siehe Datei „JSP-Number1.jsp“ Prof. Dr. Nikolaus Wulff eCommerce WS 2004 9 Lösung <%@ page language="java" import="java.util.*" %> <HTML><HEAD> <TITLE>Titel unserer tollen Seite</TITLE> </HEAD><BODY> <H1>Der erste JSP-Test</H1> Dieser erste Teil ist statischer Text. <br> Doch hier kommt eine dynamisch erzeugte Ausgabe...<br><br> Hier und jetzt ist: <%=new Date() %> </BODY></HTML> Prof. Dr. Nikolaus Wulff eCommerce WS 2004 10 Laufzeitumgebung • Java SDK muss installiert sein (Compiler!) • Servlet-Engine des Webservers muss JSPs verarbeiten können • Beispiele: – WebLogic Application Server – IBM WebSphere – Apache Webserver mit Tomcat Prof. Dr. Nikolaus Wulff eCommerce WS 2004 11 Gliederung einer JSP • JSP-Direktiven – Voreinstellungen für Seite, Includes usw. • JSP-Deklarationen – Block für Definitionen statischer Variablen • JSP-Scriptlets – Blöcke, die Java-Code mit der Seitenlogik enthalten • JSP-Expression – Ausdruck, der ausgewertet in den Text eingefügt wird • JavaScript-Bereich für clientseitigen Code • HTML-Code Prof. Dr. Nikolaus Wulff eCommerce WS 2004 12 Beispiel JSP <%@ page language="java" import="java.util.*" %> <%! String strText = "<b>Text aus einer deklarierten Variable.</b>"; %> <% strText += " <b><i> dynamisch erweitert!</i></b>"; %> <HTML><HEAD> <TITLE>Titel unserer tollen Seite</TITLE> </HEAD><BODY> <H1>Der zweite JSP-Test</H1> Dieser erste Teil ist statischer Text.<br> Doch hier kommt eine dynamisch erzeugte Ausgabe...<br><br> Hier und jetzt ist: <b><%=new Date() %></b><br><br> Und hier die Variable strText: <br> <%=strText%> </BODY></HTML> Prof. Dr. Nikolaus Wulff eCommerce WS 2004 13 Syntax Direktiven 1 • Page-Direktive <%@ page attribut=„value“ %> Definiert Einstellungen, die für die gesamte Seite gültig sind. Mögliche Attribute sind (Auswahl): import, extends, errorPage, session Beispiel: <%@ page language="java" import="java.util.*, onlinestore.*" %> Prof. Dr. Nikolaus Wulff eCommerce WS 2004 14 Syntax Direktiven 2 • Include-Direktive <%@ include file=„url“ %> Angegebene Datei wird während der Kompilierung eingebunden. Es kann sich um eine HTML-Seite oder JSP handeln. Beispiel: <%@ include file=„mypage.html“ %> Prof. Dr. Nikolaus Wulff eCommerce WS 2004 15 Syntax Actions • Jsp:include-Action <jsp:include page=„url“ /> Angebene Datei wird bei Request der Seite eingebunden. Inhalt kann statisch oder dynamisch sein. • Jsp:usebean-Action <jsp:usebean attribut=„value“ /> Mögliche Attribute sind (Auswahl): id, scope, class • Jsp:forward-Action <jsp:forward page=„url“ /> Verzweigung auf statische Seite, Servlet oder andere JSP. Prozessierung der aktuellen Seite wird abgebrochen. Prof. Dr. Nikolaus Wulff eCommerce WS 2004 16 Syntax Deklarationen • • • • Kennzeichnung mit <%! .... %> Im Deklarations-Block werden Variablen definiert. Die Initialisierung erfolgt bei der Initialisierung der Seite. Vorsicht: Da es sich um Instanz-Variablen handelt, können die Werte Session-übergreifend sichtbar sein! • Beispiel: <%! String dummy = „hallo“; int version = 1; %> Prof. Dr. Nikolaus Wulff eCommerce WS 2004 17 Syntax Expressions • Kennzeichnung mit <%=... %> • Einzelner Ausdruck, dessen Ergebnis in den HTMLOutput eingeht. • Beispiel: <%=new Date()%> Prof. Dr. Nikolaus Wulff eCommerce WS 2004 18 Syntax Scriptlets • Kennzeichnung mit <% ... %> • Scriptlets sind mehrzeilige Blöcke von Java-Code, in denen die Verarbeitungslogik der Seite definiert wird. • Es kann mehrere von einander getrennte Blöcke pro JSP geben. • Einmal deklarierte Variablen gelten auch in nachfolgenden Blöcken. • Output in HTML-Stream über out.println(„abc“); Prof. Dr. Nikolaus Wulff eCommerce WS 2004 19 Beispiel Scriptlets <TABLE> <% int x; Artikel artikel; Vector list = StoreBean.getArtikel(); for (x=0; x<list.size(); x++) { artikel = (Artikel)list.elementAt(x); %> <TR> <TD><%=artikel.getName()%></TD> <TD><%=artikel.getBeschreibung()%></TD> </TR> <% } %> </TABLE> Prof. Dr. Nikolaus Wulff eCommerce WS 2004 20 Implizite Objekte • Implizite Objekte werden automatisch erzeugt und können ohne Deklaration verwendet werden. – request => HttpServletRequest – response => HttpServletResponse – session => HttpSession – out => PrintWriter – Außerdem: page, pageContext, config, exception, application Prof. Dr. Nikolaus Wulff eCommerce WS 2004 21 Beispiele Implizite Objekte • <% session.putValue(„MeinParameter“, „Wert“); %> • <% String param = (String)session.getValue („MeinParameter“); %> • <% String param2 = request.getParameter(„editDatum“); %> • <% out.println(„Dieser Text wird ausgegeben!“); %> Prof. Dr. Nikolaus Wulff eCommerce WS 2004 22 Jsp:usebean • Jsp:usebean <jsp:usebean <attribut>=<value> /> Mögliche Attribute: Scope: entweder page, request, session oder application Id: Name, unter dem auf die Bean zugegriffen wird Class: Vollständiger Name der JavaBean-Klasse Beispiel: <jsp:useBean id=„StoreBean" scope="session" class= „onlinestore.StoreBean" /> Prof. Dr. Nikolaus Wulff eCommerce WS 2004 23 Error-Handling • Es gibt zwei Arten von JSP-Fehlern: – Translation Time Errors: Fehler beim Kompilieren – Request Time Errors: Fehler zur Laufzeit • Compile-Errors sind im Logfile des Servers zu finden • Laufzeit-Fehler werfen eine Exception und können im JSP-Code abgefangen werden • Nicht abgefangene Exceptions werden an eine optional angegebene Fehler-Seite weitergegeben Prof. Dr. Nikolaus Wulff eCommerce WS 2004 24 JSP Vererbungshierarchie <<Interface>> Servlet (from ser vl et) <<Int erface>> JspPage js pInit() js pDestroy() <<Int erface>> HttpJspPage <<Interface>> ServletConfig <<Abstract>> GenericServlet (from serv let) (from serv let) <<Interface>> ServletContext <<Abstract>> HttpServlet (from serv let) (from http) <<Container>> HttpJspBase (from org.apache.j asper.runtime) abhängig von der JSPEngine. Hier Apache Tomcat _jspService() MyJavaServerPage <<generated>> MyJspServlet pageContext PageContext 1 Prof. Dr. Nikolaus Wulff eCommerce WS 2004 25 PageContext <<Interface>> ServletRequest <<Interface>> ServletResponse (from serv let) (from serv let) 1 <<Interface>> HttpSession +session (from http) Writer (from io) 1 PageContext (from lang) 0..1 0.. 1 +out 1 JspWri ter 1 <<Interface>> ServletConfig (from serv let) Prof. Dr. Nikolaus Wulff -attribut Object name : String eCommerce WS 2004 1 <<Interface>> ServletContext (from serv let) 26 Taglibs • Taglibs bieten die Möglichkeit, eigene Tags zu definieren • Verarbeitungslogik wird dorthin ausgelagert und kann so wiederverwendet werden • Ab JSP 1.1 • Positionierung stellt gewisse Konkurrenz zu PageBeans dar • Tags sind aber besser in den Kontext der Seite eingebunden • Einführung unter: http://www.javaworld.com/javaworld/jw-08-2000/jw-0811-jsptags.html Prof. Dr. Nikolaus Wulff eCommerce WS 2004 27 Tags Klassendiagramm PageContext (from j sp) 1 #pageContext -parent <<Interface>> Tag 0..1 TagSupport key : String / maps -value Object (from lang) doStartTag() doEndTag() JspWriter (from j sp) <<Interface>> BodyTag BodyTagSupport #bodyContent BodyContent doInitBody() doAfterBody() MyTag Prof. Dr. Nikolaus Wulff eCommerce WS 2004 MyTag Descriptor 28 Übung • Einbinden eines selbst definierten Tags für eine Datumsausgabe: <%@ page language="java" %> <html> <head><title>DateTag JSP Page</title> </head> <%@ taglib uri="/NWTagLib" prefix= "nwtag" %> <body> <h2>DateTag test</h2> Hier kommt die Zeit <nwtag:currentDate/> und so wird sie formatiert ausgegeben <nwtag:currentDate format="dd/MM/yyyy hh:mm:ss" /> Prof. Dr. Nikolaus Wulff eCommerce WS 2004 29 Einbinden von Tags • Erstellen einer TagKlasse, abgeleitet von Tag/BodyTagSupport. – Überladen der doStart/EndTag und doInit/AfterBody Methoden. – Einfügen von Setter-Methoden für Argumente im Tag • Erstellen einer TagLib Descriptor Beschreibung für die TagKlasse • Bekanntgabe des TagLib Descriptors in der Web.xml des WebContainers • optional: Deployment der Klasse(n) und Descriptoren in einem War-Archive Prof. Dr. Nikolaus Wulff eCommerce WS 2004 30 CurrentDateTag.java public class CurrentDateTag extends TagSupport { private SimpleDateFormat formatter; public void setFormat(String format) throws JspException { this.formatter = new SimpleDateFormat(format); } public int doStartTag() throws JspException { return TagSupport.EVAL_BODY_INCLUDE; } public int doEndTag() throws JspException { try { String currentDate; if (null != this.formatter) { currentDate = formatter.format(new Date()); } else { currentDate = new Date().toString(); } pageContext.getOut().write(currentDate); }catch(IOException e) { throw new JspException(e.toString()); } return TagSupport.EVAL_PAGE; } } Prof. Dr. Nikolaus Wulff eCommerce WS 2004 31 TagLib.tld <?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.1//EN" "http://java.sun.com/j2ee/dtds/web-jsptaglibrary_1_1.dtd"> <taglib> <!-- after this the default space is "http://java.sun.com/j2ee/dtds/jsptaglibrary_1_2.dtd" --> <tlibversion>1.0</tlibversion> <jspversion>1.1</jspversion> <shortname>NWTagLib</shortname> <uri>NWTagLib</uri> <info> Nikos simple tag library </info> <tag> .... Prof. Dr. Nikolaus Wulff eCommerce WS 2004 32 TagLib.tld ... <info> Nikos simple tag library </info> <tag> <name>currentDate</name> <tagclass>servlet.CurrentDateTag</tagclass> <attribute> <name>format</name> <required>false</required> <rtexprvalue>false</rtexprvalue> </attribute> </tag> Prof. Dr. Nikolaus Wulff eCommerce WS 2004 33 Web.xml <?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN" "http://java.sun.com/j2ee/dtds/web-app_2.2.dtd"> <web-app> <taglib> <taglib-uri> /NWTagLib </taglib-uri> <taglib-location> /WEB-INF/NWTagLib.tld </taglib-location> </taglib> </web-app> Prof. Dr. Nikolaus Wulff eCommerce WS 2004 34 JSTL • Die Java Standard Taglib Library (JSTL) wurde im Juli 2002 als JSTL1.0 freigegeben. • Seit dem wird diese Bibliothek ständig weiter entwickelt. • In der JSTL sind bis lang nur wenige verbindliche Tags definiert, die jedoch die wichtigsten Aufgaben wie JDBC-Verbindungen, Schleifen, URLs beinhalten. • Mit JSTL1.1 wurde auch eine eigene Expression Language JSTL-el definiert, die es erlaubt Java Ausdrücke in Tags zu schreiben. Prof. Dr. Nikolaus Wulff eCommerce WS 2004 35 JSTL Bibliotheken JSTL 1.0 besteht aus vier Kernbibliotheken: • core: Beinhaltet Schleifen forEach, Variablen und bedingte Anweisungen wie if und choose • format: Erlaubt formatierte Ausgaben wie z. B. numerische Felder, Währungen oder Datum • xml: Erlaubt XML/XSLT Transformationen • sql: Direkter Datenbankzugriff via JDBC Prof. Dr. Nikolaus Wulff eCommerce WS 2004 36 JSTL Expression Language • Seit JSTL 1.1 gibt es zusätzlich die Expression Language (EL). • Mit ihrer Hilfe ist es möglich einfache Java Ausdrücke direkt in Tags zu verwenden. • Um die Straße einer Person zu ermitteln heißt es statt: <%= person.getAdress().getStreet()%> einfach nur noch: <c:out value="${person.adress.street}"/> • Voraussetzung ist allerdings die Einhaltung der Java Beans Konventionen in den Person/Adress Klassen. Prof. Dr. Nikolaus Wulff eCommerce WS 2004 37 JSTL Flavors • Wichtig ist es die richtige TLD Beschreibung in der web.xml zu referenzieren, da die JSTL in zwei Varianten ausgeliefert werden. Einmal mit (JSTL1.1) einmal ohne EL (JSTL1.0). • Die Tags sehen von außen identisch aus, nur die EL Ausdrücke werden intern nicht aufgelöst! • In den TLDs kann dies an den unterschiedlichen Paketnamen für die Tag Klassen erkannt werden: <tag> <name>if</name> EL: <tag-class>org.apache.taglibs.standard.tag.el.core.IfTag</tag-class> RT: <tag-class>org.apache.taglibs.standard.tag.rt.core.IfTag</tag-class> Prof. Dr. Nikolaus Wulff eCommerce WS 2004 38 JSTL prefixes • Die vier JSTL Bibliotheken werden i. A. mit den vier Prefixes c, fmt, xml und sql versehen. • Die URI ist laut Standard fixiert zu: – http://java.sun.com/jstl/XXX – XXX aus {core, format, xml, sql} • Die web.xml muss einen entsprechenden Eintrag beinhalten: <!-- JSTL Tag Library Descriptor --> <taglib> <taglib-uri>http://java.sun.com/jstl/core</taglib-uri> <taglib-location>/WEB-INF/tld/c.tld</taglib-location> </taglib> Prof. Dr. Nikolaus Wulff eCommerce WS 2004 39 <c:set> • Variablen werden mit dem set-Tag gesetzt: <c:set var="name" value="expression" scope="xxx"/> • Die Variable ist danach mit dem symbolischen Namen assoziert. • Die Angabe des Scope ist optional und wird per Voreinstellung auf „pageScope“ gesetzt. • Der Ausdruck „expression“ kann eine einfache Variable sein oder auch ein berechneter Wert. • Es werden automatisch Wrapper-Klassen verwendet. Prof. Dr. Nikolaus Wulff eCommerce WS 2004 40 <c:out> • Der einfachste Tag ist die Ausgabe: <c:out value="${book.title}" /> • Die entsprechende Variable „book“ wird in folgender Reihenfolge gesucht: – – – – pageScope requestScope sessionScope applicationScope • Diese Sichbarkeitshierarchie wird für alle JSTL Tags verwendet. Prof. Dr. Nikolaus Wulff eCommerce WS 2004 41 <c:out> II • Es ist möglich eine Ausgabe als Voreinstellung bei <c:out> anzugeben, falls kein passendes Attribut gefunden wird. Dies geschieht mit dem default Attribute. • Auch ist es möglich anzugeben ob die Ausgabe HTML konform erfolgen soll, dann werden z.B. Sonderzeichen wie „<“ als „&lt;“ dargestellt. User <c:out value="${user}" default="guest" escapeXML="true"/> Prof. Dr. Nikolaus Wulff eCommerce WS 2004 42 <c:if> • Eine bedingte Anweisung lässt sich mit dem if-Tag realisieren: <c:if test="${!empty user}"> User <c:out value="${user}"/> logged on </c:if> • Innerhalb des test Attributs kann ein EL oder auch nur eine einfache Boolsche Variable stehen. • Es können normale Java Operatoren wie „==“, „!=“ oder auch symbolisch Ausdrücke wie „eq“, „ne“ vorkommen. • Neu ist der Ausdruck „empty“. Prof. Dr. Nikolaus Wulff eCommerce WS 2004 43 <c:choose/when/otherwise> • Vergeblich wird ein if-else Konstrukt gesucht. Statt dessen bietet JSTL ein switch-case per choose-whenotherwise. <c:choose> <c:when test="${ count % 10 == 0 }"> <tr bgcolor="#DDDDDD"> </c:when> <c:when test="${ count % 2 == 0 }"> <tr bgcolor="#DDFFDD"> </c:when> <c:otherwise> <tr bgcolor="#DDDDEF"> </c:otherwise> </c:choose> Prof. Dr. Nikolaus Wulff eCommerce WS 2004 44 <c:forEach> • Schleifen werden mit dem forEach-Tag realisiert. • Diese Auszeichnung iteriert einheitlich über Arrays und Container und kann auch als for-Schleife verwendet werden: <c:forEach var="j" begin="1" end="4" step="1"> <tr><td><c:out value="j"/> </td> quad=<c:out value="${j*j}"/></td></tr> </c:forEach> • Das Beispiel zeigt eine for-Schleife mit dem symbolischen Zähler „j“, der dann auch per EL zum Quadrieren verwendet werden kann. Prof. Dr. Nikolaus Wulff eCommerce WS 2004 45 <c:forEach>-Iterator • Auch die Iteration über eine Collection ist einfach zu realisieren: <c:forEach var="book" items="${RESULT}" > <tr><td><c:out value="${count}" /> </td> <td><c:out value="${book.title}" /> </td> <td><c:out value="${book.isbn}" /> </td> </tr> </c:forEach> • Die entsprechende Collection RESULT muss vorher im page, request, session oder application Scope unter diesem Alias hinterlegt worden sein. Prof. Dr. Nikolaus Wulff eCommerce WS 2004 46 <c:url> • Das url-Tag erlaubt den Zugriff auf andere Resourcen per Unique Ressource Locator. • Darüber hinaus erleichtert es URL-rewriting, indem es eine passend assoziierte SessionId an die Variablen anfügt: <c:url var="baseurl" value="/Control" /> ... <a href='<c:out value="${baseurl}" /?task=help' alt='Help'>Help</a> • Wird vom WebContainer URL-rewritting benötigt, so generiert der url-Tag dies automatisch. Prof. Dr. Nikolaus Wulff eCommerce WS 2004 47 Bitte beachten! • So wenig Java-Code in JSP wie möglich • Business-Logik gehört in EJBs, Controller-Logik möglichst in PageBean • Gebrauch von JavaScript möglichst einschränken (Browser-Kompatibilitätsprobleme) • HTML sollte nicht als Rückgabewert von PageBeanFunktionen erzeugt werden • Für größere Anwendungen Servlets und JSP mit MVC II Architektur einsetzen, z.B. Apache Struts. Prof. Dr. Nikolaus Wulff eCommerce WS 2004 48