Einstieg in JavaServer Pages 2.0

Werbung
Liebe Leserin, lieber Leser,
ich freue mich, dass Sie sich für ein Galileo Computing-Buch entschieden haben.
Unsere Einsteigertitel sind besonders für Leser geeignet, die sowohl inhaltlich als
auch didaktisch professionell gemachte Fachliteratur schätzen und sich nicht mit
»schnellen« Produkten zufrieden geben.
Dieses Buch befasst sich mit der aktuellen Version 2.0 der JavaServer Pages. Und
es hat sich Einiges getan. Das Buch schafft den Spagat zwischen der Beschreibung
bisher üblicher Verfahren und der Behandlung der vollständig neuen Möglichkeiten von 2.0. Die Materie ist komplex; unser Einstieg hilft, JSP 2.0 zu verstehen und
effektiv anzuwenden.
Das Buch wurde sorgfältig geprüft und die Beispiele getestet. Doch kein noch so
gutes EDV-Buch ist ohne Fehler. Lassen Sie uns wissen, wenn etwas nicht so funktioniert, wie Sie es erwarten. Über Anregungen und Lob freuen wir uns natürlich
auch!
Jetzt wünsche ich viel Freude beim Lesen!
Judith Stevens-Lemoine
Lektorat Galileo Computing
[email protected]
www.galileocomputing.de
Galileo Press • Gartenstraße 24 • 53229 Bonn
Auf einen Blick
1 Java Server Pages im Überblick ............... 17
2 Einrichten einer Entwicklungsumgebung
61
3 Entwicklung dynamischer Webseiten
mit JSP 2.0 .............................................. 85
4 Einrichten dynamischer
Webanwendungen .................................. 389
5 Erweiterungen und fortgeschrittene
Lösungen ................................................. 415
6 Kurzreferenz Java Server Pages 2.0 .......... 479
Bibliografische Information Der Deutschen Bibliothek
Die Deutsche Bibliothek verzeichnet diese Publikation in der Deutschen Nationalbibliografie; detaillierte
bibliografische Daten sind im Internet über http://dnb.ddb.de abrufbar.
ISBN 3-89842-360-3
© Galileo Press GmbH, Bonn 2004
1. Auflage 2004
Der Name Galileo Press geht auf den italienischen Mathematiker und
Philosophen Galileo Galilei (1564–1642) zurück. Er gilt als Gründungsfigur der neuzeitlichen Wissenschaft und wurde berühmt als Verfechter
des modernen, heliozentrischen Weltbilds. Legendär ist sein Ausspruch
Eppur se muove (Und sie bewegt sich doch). Das Emblem von Galileo
Press ist der Jupiter, umkreist von den vier Galileischen Monden. Galilei
entdeckte die nach ihm benannten Monde 1610.
Das vorliegende Werk ist in all seinen Teilen urheberrechtlich geschützt. Alle Rechte vorbehalten, insbesondere das Recht der Übersetzung, des Vortrags, der Reproduktion, der Vervielfältigung auf fotomechanischem oder anderen Wegen und der Speicherung in elektronischen Medien.
Ungeachtet der Sorgfalt, die auf die Erstellung von Text, Abbildungen und Programmen verwendet
wurde, können weder Verlag noch Autor, Herausgeber oder Übersetzer für mögliche Fehler und deren
Folgen eine juristische Verantwortung oder irgendeine Haftung übernehmen.
Die in diesem Werk wiedergegebenen Gebrauchsnamen, Handelsnamen, Warenbezeichnungen usw.
können auch ohne besondere Kennzeichnung Marken sein und als solche den gesetzlichen Bestimmungen unterliegen.
Lektorat Judith Stevens-Lemoine
Korrektorat Claudia Falk, Dr. Rainer Noske, Bonn
Einbandgestaltung Barbara Thoben, Köln
Herstellung Iris Warkus
Titelbild zefa visual media
Satz Typographie & Computer, Krefeld
Druck und Bindung Koninklijke Wöhrmann, Zutphen, Niederlande
Inhalt
Vorwort
15
1
JavaServer Pages im Überblick
19
1.1
Von statischen zu dynamischen Webseiten ..........................................
19
1.2
Die Basis: das HTTP-Protokoll ...............................................................
1.2.1
Das Anfrage/Antwort-Modell ...................................................
1.2.2
Verbindungslos ........................................................................
1.2.3
Ohne Zustand ..........................................................................
1.2.4
Aufbau von HTTP-Nachrichten .................................................
1.2.5
Das Format der Anfrage ...........................................................
1.2.6
Das Format der Antwort ..........................................................
1.2.7
Beobachtung der HTTP-Kommunikation ...................................
20
20
21
22
22
23
26
29
1.3
JSP im Vergleich zu älteren Serveranwendungen ..................................
1.3.1
Common Gateway Interface .....................................................
1.3.2
Servererweiterungen ................................................................
1.3.3
Java-Servlets ............................................................................
1.3.4
Active Server Pages ..................................................................
1.3.5
Von Servlets zu JavaServer Pages ..............................................
1.3.6
Arbeitsteilung zwischen Programmierung und Seitendesign ......
1.3.7
Was spricht für JSP? .................................................................
29
30
31
31
35
36
37
38
1.4
Anwendungsgebiete und -modelle .......................................................
1.4.1
JSP oder DHTML? ....................................................................
1.4.2
Das Designmodell Model-View-Controller ...............................
39
39
39
1.5
Von JSP 1.2 nach JSP 2 .........................................................................
1.5.1
Plattform und Servlet-API .........................................................
1.5.2
JSTL und andere Tag-Bibliotheken ............................................
1.5.3
Expression Language ................................................................
1.5.4
Simple Tag-Handler ..................................................................
1.5.5
Tag-Dateien .............................................................................
1.5.6
JSP als XML-Dokument und XML-Views ...................................
1.5.7
Neue Standardaktionen und dynamische Attribute ...................
41
42
42
42
43
43
43
44
1.6
Allgemeine Merkmale von JSP ..............................................................
1.6.1
Laufzeitumgebung für JSP ........................................................
1.6.2
Einbindung in J2EE ...................................................................
1.6.3
Aufbau einer JSP ......................................................................
1.6.4
Übersetzungsphase ..................................................................
1.6.5
Die JSP-Implementierungsklasse ...............................................
44
44
45
48
49
50
Inhalt
5
1.6.6
1.6.7
6
Ausführungsphase ....................................................................
Quellcode des Beispiels ...........................................................
51
55
2
Einrichten einer Entwicklungsumgebung
63
2.1
Werkzeuge für Java ...............................................................................
63
2.2
Webserver und JSP-Container ..............................................................
2.2.1
Apache Tomcat 5.0 installieren ................................................
2.2.2
Einrichten der Umgebung ........................................................
2.2.3
Serverbetrieb ...........................................................................
2.2.4
Serverkonfigurierung: server.xml ..............................................
2.2.5
Webanwendungen ..................................................................
2.2.6
Gemeinsame Bibliotheken .......................................................
64
65
66
68
72
77
82
2.3
Einrichten der Beispiele ........................................................................
82
2.4
Entwicklungswerkzeuge für JSP ...........................................................
83
3
Entwicklung dynamischer
Webseiten mit JSP 2.087
3.1
JSPs und JSP-Dokumente .....................................................................
3.1.1
Standardsyntax und XML-Syntax ..............................................
87
87
3.2
Syntaktische Bestandteile einer JSP .....................................................
3.2.1
JSP-Elemente und Template-Daten ..........................................
3.2.2
Elemente und Attribute ...........................................................
3.2.3
EL-Ausdrücke ..........................................................................
3.2.4
Kommentare ...........................................................................
3.2.5
Sonderzeichen und Escape-Sequenzen .....................................
3.2.6
Relative URLs ...........................................................................
3.2.7
Hinweis zu den Dateinamen ....................................................
88
88
90
91
91
93
94
94
3.3
Direktiven an den JSP-Container ..........................................................
3.3.1
Die Direktive page ...................................................................
3.3.2
Die Direktive include ...............................................................
3.3.3
Alternative Import-Mechanismen .............................................
3.3.4
Die Direktive taglib ..................................................................
3.3.5
Hinweise zur Schreibweise bei Direktiven ................................
95
95
105
109
109
114
3.4
Skriptelemente .....................................................................................
3.4.1
Java-Code in JSPs .....................................................................
3.4.2
Deklarationen ..........................................................................
3.4.3
Skriptlets .................................................................................
3.4.4
Ausdrücke ...............................................................................
3.4.5
Skriptlösung für ein Web-Tagebuch .........................................
114
115
116
120
130
133
3.5
Zugriff auf serverseitige Objekte .......................................................... 137
3.5.1
Objekte und Variablen ............................................................. 138
3.5.2
Implizite Objekte ..................................................................... 139
Inhalt
3.6
Arbeit mit impliziten Objekten .............................................................
3.6.1
Request ....................................................................................
3.6.2
Response .................................................................................
3.6.3
PageContext ............................................................................
3.6.4
Session .....................................................................................
3.6.5
Application ..............................................................................
3.6.6
Out ..........................................................................................
3.6.7
Config ......................................................................................
3.6.8
Page .........................................................................................
3.6.9
Exception .................................................................................
141
141
142
143
143
144
146
148
148
148
3.7
Expression Language .............................................................................
3.7.1
Einfacher als Skriptausdrücke ...................................................
3.7.2
Die API-Erweiterung für EL ......................................................
3.7.3
Einsatz von EL-Ausdrücken .......................................................
3.7.4
Implizite Objekte in EL-Ausdrücken .........................................
3.7.5
Hinweise zur Syntax von EL ......................................................
3.7.6
Funktionen ..............................................................................
148
149
150
151
152
154
157
3.8
Einsatz von Standardaktionen ...............................................................
3.8.1
Allgemeine Syntax von Aktionen ..............................................
3.8.2
Attributwerte ...........................................................................
3.8.3
Typumwandlungen ..................................................................
3.8.4
Ressourcen einfügen – <jsp:include> ........................................
3.8.5
Weiterleiten einer Anfrage – <jsp:forward> ..............................
3.8.6
Parameterübergabe – <jsp:param> ...........................................
3.8.7
Komponenten einbetten – <jsp:plugin> ....................................
3.8.8
Parametergruppen – <jsp:params> ...........................................
3.8.9
Notausgang – <jsp:fallback> .....................................................
3.8.10 Elemente erzeugen – <jsp:element> .........................................
3.8.11 Attribute erzeugen – <jsp:attribute> .........................................
3.8.12 Rumpf einfügen – <jsp:body> ...................................................
3.8.13 Fragmente aufrufen – <jsp:invoke> ...........................................
3.8.14 Template-Text einfügen – <jsp:text> .........................................
3.8.15 Rumpf ausführen – <jsp:doBody> .............................................
3.8.16 Nutzen von JavaBean-Komponenten ........................................
3.8.17 JavaBeans deklarieren – <jsp:useBean> .....................................
3.8.18 Eigenschaften abfragen – <jsp:getProperty> ..............................
3.8.19 Eigenschaften setzen – <jsp:setProperty> .................................
3.8.20 Weitere Standardaktionen ........................................................
3.8.21 Verwandschaftsbeziehungen und Attributkombinationen .........
160
161
162
162
162
169
172
173
178
178
178
180
182
183
185
185
186
190
196
197
200
200
3.9
Einsatz der JSP Standard Tag Library – JSTL ..........................................
3.9.1
Aktionen anstelle von Skriptelementen ....................................
3.9.2
JSTL 1.0 und 1.1 ......................................................................
3.9.3
Abwärtskompatibilität ..............................................................
3.9.4
Zusammensetzung der Bibliothek .............................................
3.9.5
Ablaufsteuerung mit JSTL .........................................................
3.9.6
Verarbeitung von XML-Dokumenten ........................................
3.9.7
Zugriff auf Datenbanken ...........................................................
3.9.8
Formatierung von Zahlen, Zeit- und Datumsangaben ...............
3.9.9
Lokalisierung und Internationalisierung ....................................
201
201
203
204
204
206
214
227
228
232
Inhalt
7
3.10
8
JSP als XML-Dokument ........................................................................
3.10.1 Allgemeine Merkmale von XML ...............................................
3.10.2 Identifizierung von JSP-Dokumenten .......................................
3.10.3 Aufbau von JSP-Dokumenten ..................................................
3.10.4 Verarbeitung eines JSP-Dokuments ..........................................
3.10.5 Vorteile von JSP-Dokumenten .................................................
3.10.6 JSPs mit XML-Elementen .........................................................
232
236
241
241
248
248
248
3.11
XML-Ansicht einer JSP .......................................................................... 249
3.12
Nebenläufigkeit und Thread-Sicherheit ................................................ 251
3.12.1 Single-Thread-Modell .............................................................. 251
3.12.2 Synchronisierung ..................................................................... 252
3.13
Verarbeitung der Ein- und Ausgabe ......................................................
3.13.1 Formulare und Anfrage-Parameter ...........................................
3.13.2 Beispiel für ein Anmeldeformular .............................................
3.13.3 Steuerung der Formularverarbeitung ........................................
3.13.4 Formularauswertung ................................................................
3.13.5 Validierung von Benutzereingaben ...........................................
253
254
254
258
264
266
3.14
Einsatz von JavaBeans ..........................................................................
3.14.1 JavaBeans als Komponenten in JSP ..........................................
3.14.2 Allgemeine Merkmale von Beans .............................................
3.14.3 Eigenschaften und Zugriffsmethoden .......................................
3.14.4 Andere Methoden ...................................................................
3.14.5 Zustände und Serialisierung .....................................................
3.14.6 JavaBean-Konstruktor ..............................................................
3.14.7 JavaBean als Datenbehälter innerhalb eines Anmeldeverfahrens
3.14.8 Kompilieren und Installieren von Beans ...................................
3.14.9 Skriptvariable und JavaBean-Objekte .......................................
271
271
271
273
274
275
275
275
284
284
3.15
Zugriff auf Servlet-Komponenten ......................................................... 285
3.15.1 Servlets kompilieren und installieren ........................................ 286
3.16
Austausch zwischen Anwendungskomponenten .................................. 289
3.17
Cookies
3.17.1
3.17.2
3.17.3
3.17.4
.................................................................................................
Cookies schreiben ....................................................................
Cookies auslesen .....................................................................
Cookies ändern ........................................................................
Cookies löschen .......................................................................
292
293
295
297
297
3.18
Sitzungsverfolgung ...............................................................................
3.18.1 Das Session-Konzept in HTTP ..................................................
3.18.2 Sitzungsverfolgung mit Cookies ................................................
3.18.3 Umschreiben von URLs ............................................................
3.18.4 Sitzungskennungen über versteckte Formularfelder ..................
3.18.5 SSL-Sitzungen ..........................................................................
297
298
299
299
301
302
3.19
Handhabung einer Sitzung ...................................................................
3.19.1 Start einer Sitzung ....................................................................
3.19.2 Abfrage der Sitzungsinformationen ..........................................
3.19.3 Daten an das Sitzungsobjekt anbinden .....................................
3.19.4 Einbau von Beobachtern ..........................................................
3.19.5 Sitzungsende ...........................................................................
302
303
303
304
305
306
Inhalt
3.19.6
3.19.7
JSPs in Sitzung einfügen ........................................................... 306
Test der Sitzungsverfolgung ...................................................... 307
3.20
Filter und Filterketten ........................................................................... 309
3.21
Internationale und lokale Websites ......................................................
3.21.1 Unicode und Zeichenkodierungen ............................................
3.21.2 Separate Webpräsenzen für mehrere Sprachen .........................
3.21.3 Automatische Sprachauswahl ...................................................
3.21.4 I18N – Internationale Sites .......................................................
3.21.5 Java-Klassen für I18N ...............................................................
3.21.6 Ressourcenbündel ....................................................................
3.21.7 Zeichenkodierung für dynamische Inhalte ................................
3.21.8 Aktionen der Standardbibliothek für die Internationalisierung ..
3.21.9 Stadt, Land, Fluss – international ..............................................
313
313
314
315
316
317
321
322
322
323
3.22
Zugriff auf Datenbanken mit JDBC .......................................................
3.22.1 Allgemeine Merkmale von SQL ................................................
3.22.2 Die JDBC-Architektur ...............................................................
3.22.3 Der Zugriff auf Datenbanken in der Übersicht ..........................
3.22.4 Erstes Beispiel mit MySQL ........................................................
3.22.5 Die Arbeit mit Datenquellen ....................................................
3.22.6 Neue Daten in die Datenbank einfügen ....................................
3.22.7 Datenbankoperationen mit Hilfe von JSTL ................................
3.22.8 Ausführen von SQL-Anweisungen ............................................
3.22.9 Parameter für die Ergebnismenge .............................................
3.22.10 Verarbeiten der Ergebnismenge ................................................
3.22.11 Das Interface RowSet ...............................................................
3.22.12 Transaktionen ..........................................................................
3.22.13 Zugriff auf Metadaten ..............................................................
3.22.14 Ausnahmebehandlung und Warnungen ....................................
3.22.15 Auslagern des Zugriffscodes in Komponenten ...........................
3.22.16 Connection Pooling ..................................................................
328
328
330
338
342
347
353
357
364
370
373
378
378
381
383
383
384
3.23
Fehlersuche und Debugging .................................................................
3.23.1 Auswerten der Fehlermeldungen ..............................................
3.23.2 Testverfahren ...........................................................................
3.23.3 Erzeugen von Fehlerseiten .......................................................
3.23.4 Error-Handler ...........................................................................
385
385
387
387
387
4
Einrichten dynamischer Webanwendungen 391
4.1
Anwendungsdeskriptoren .....................................................................
4.1.1
Beschreibungselemente im Überblick .......................................
4.1.2
Übergreifende Einstellungen ....................................................
4.1.3
Einstellungen für Servlets und JSPs ...........................................
4.1.4
Listener und Filter ....................................................................
4.1.5
MIME-Zuordnungen ................................................................
4.1.6
Startseiten ................................................................................
4.1.7
Fehlerseiten .............................................................................
4.1.8
Lokalisierung ............................................................................
4.1.9
Sicherheitsmaßnahmen und Berechtigungen ............................
391
391
394
395
397
399
400
400
401
401
Inhalt
9
Benutzerauthentifizierung ........................................................
JSP-Konfiguration ....................................................................
Bezug auf JNDI-Objekte ..........................................................
Beispiel für eine Deskriptor-Datei ............................................
404
405
408
409
4.2
Veröffentlichungsverfahren ..................................................................
4.2.1
Schnüren eines WAR-Pakets ....................................................
4.2.2
Installation einer WAR-Datei unter Tomcat ..............................
4.2.3
Deployment ohne Archiv .........................................................
4.2.4
Anwendungsmanagement ........................................................
410
411
412
413
413
5
Erweiterungen und fortgeschrittene
Lösungen417
5.1
Benutzerdefinierte Tags ........................................................................
5.1.1
Einsatz von Tag-Bibliotheken ...................................................
5.1.2
Eine einfache Aktion ................................................................
5.1.3
Merkmale eigener Aktionen .....................................................
5.1.4
Das Interface IterationTag ........................................................
5.1.5
Ein Tag, das seinen Rumpf auswertet .......................................
5.1.6
Ausnahmebehandlung .............................................................
5.2
Einfache Tag-Handler ............................................................................ 438
5.3
Einbindung von Tags in eine Tag-Bibliothek ........................................
5.3.1
Aufbau eines Tag-Bibliothek-Deskriptors ..................................
5.3.2
Beschreibung der einzelnen Aktionen ......................................
5.3.3
Erweiterungen der Taglib .........................................................
5.3.4
Installieren der Tag-Bibliothek ..................................................
5.3.5
Einbinden einer Tag-Bibliothek in eine Anwendung .................
5.3.6
Tags oder Beans? .....................................................................
5.3.7
Validierung von Tag-Bibliotheken .............................................
445
446
448
452
454
455
457
457
5.4
Tag-Dateien ..........................................................................................
5.4.1
Platzierung der Tag-Dateien .....................................................
5.4.2
Inhalt von Tag-Dateien ............................................................
5.4.3
Die Direktive tag ......................................................................
5.4.4
Die Direktive attribute .............................................................
5.4.5
Die Direktive variable ..............................................................
5.4.6
Zugriff auf implizite Objekte ....................................................
5.4.7
Synchronisierung der Variablen ................................................
5.4.8
Ein Tag mit einem Attribut .......................................................
5.4.9
Tags zur dynamischen Präsentation von Daten .........................
5.4.10 Aufruf von Fragmenten ............................................................
459
461
462
463
465
466
467
467
470
471
475
5.5
Struts-Framework ................................................................................. 476
4.1.10
4.1.11
4.1.12
4.1.13
10
Inhalt
417
418
418
426
431
432
437
6
Kurzreferenz JavaServer Pages 2.0
481
6.1
Allgemeine Regeln ................................................................................ 481
6.1.1
Maskierungen .......................................................................... 481
6.1.2
Typographische Konventionen ................................................. 482
6.2
Kommentare ......................................................................................... 482
6.3
Direktiven .............................................................................................
6.3.1
page .........................................................................................
6.3.2
Include .....................................................................................
6.3.3
Taglib .......................................................................................
483
483
485
486
6.4
Skriptelemente ......................................................................................
6.4.1
Deklaration ..............................................................................
6.4.2
Skriptausdruck .........................................................................
6.4.3
Skriptlets ..................................................................................
6.4.4
Implizite Objekte für Skriptlets und Ausdrücke .........................
487
487
488
489
490
6.5
EL-Ausdrücke ........................................................................................
6.5.1
Syntax ......................................................................................
6.5.2
Implizite Objekte in EL-Ausdrücken .........................................
6.5.3
Literale .....................................................................................
6.5.4
Operatoren ..............................................................................
6.5.5
Funktionen ..............................................................................
491
492
492
492
493
495
6.6
Standardaktionen ..................................................................................
6.6.1
<jsp:root> ................................................................................
6.6.2
<jsp:text> .................................................................................
6.6.3
<jsp:forward> ...........................................................................
6.6.4
<jsp:include> ...........................................................................
6.6.5
<jsp:param> .............................................................................
6.6.6
<jsp:plugin> .............................................................................
6.6.7
<jsp:params> ............................................................................
6.6.8
<jsp:fallback> ...........................................................................
6.6.9
<jsp:useBean> ..........................................................................
6.6.10 <jsp:getProperty> .....................................................................
6.6.11 <jsp:setProperty> .....................................................................
6.6.12 <jsp:element> ..........................................................................
6.6.13 <jsp:attribute> .........................................................................
6.6.14 <jsp:body> ...............................................................................
6.6.15 <jsp:invoke> ............................................................................
6.6.16 <jsp:doBody> ...........................................................................
6.6.17 <jsp:output> ............................................................................
495
496
497
497
498
499
500
502
503
503
504
505
506
507
508
508
509
510
6.7
Kurzreferenz der JSTL ............................................................................
6.7.1
Kern-Tag-Bibliothek .................................................................
6.7.2
Tags für allgemeine Aufgaben ...................................................
6.7.3
<c:catch> .................................................................................
6.7.4
<c:out> ....................................................................................
6.7.5
<c:set> .....................................................................................
6.7.6
<c:remove> ..............................................................................
6.7.7
Verzweigungen ........................................................................
510
511
511
511
511
512
513
514
Inhalt
11
6.7.8
6.7.9
6.7.10
6.7.11
6.7.12
6.7.13
6.7.14
6.7.15
6.7.16
6.7.17
6.7.18
6.7.19
6.7.20
6.7.21
6.7.22
6.7.23
6.7.24
6.7.25
6.7.26
6.7.27
6.7.28
6.7.29
6.7.30
6.7.31
6.7.32
6.7.33
6.7.34
6.7.35
6.7.36
6.7.37
6.7.38
6.7.39
6.7.40
6.7.41
6.7.42
6.7.43
6.7.44
6.7.45
6.7.46
6.7.47
6.7.48
6.7.49
6.7.50
6.7.51
6.7.52
6.7.53
6.7.54
6.7.55
6.7.56
6.7.57
6.7.58
6.7.59
12
Inhalt
<c:if> .......................................................................................
<c:choose> ..............................................................................
<c:when> ................................................................................
<c:otherwise> ..........................................................................
Wiederholungen ......................................................................
<c:forEach> .............................................................................
<c:forTokens > .........................................................................
Import und URL-Behandlung ...................................................
<c:import> ..............................................................................
<c:url> .....................................................................................
<c:redirect> .............................................................................
<c:param> ...............................................................................
Tags für die Verarbeitung von XML ..........................................
<x:parse> .................................................................................
<x:out> ....................................................................................
<x:set> ....................................................................................
<x:if> .......................................................................................
<x:choose> ..............................................................................
<x:when> ................................................................................
<x:otherwise> ..........................................................................
<x:forEach> .............................................................................
<x:transform> ..........................................................................
<x:param> ...............................................................................
Tags für die Arbeit mit Datenbanken ........................................
<sql:setDataSource> ................................................................
<sql:query> .............................................................................
<sql:update> ...........................................................................
<sql:param> .............................................................................
<sql:dateParam> ......................................................................
<sql:transaction> .....................................................................
Tags für die Formatierung von Werten .....................................
<fmt:formatNumber> ..............................................................
<fmt:parseNumber> ................................................................
<fmt:formatDate> ....................................................................
<fmt:parseDate> ......................................................................
<fmt:timeZone> .......................................................................
<fmt:setTimeZone> ..................................................................
Internationalisierung von Anwendungen ..................................
<fmt:bundle> ..........................................................................
<fmt:setBundle> ......................................................................
<fmt:setLocale> .......................................................................
<fmt:message> ........................................................................
<fmt:param> ............................................................................
<fmt:requestEncoding> ............................................................
Standardfunktionen .................................................................
fn:contains ...............................................................................
fn:containsIgnoreCase ..............................................................
fn:endsWith .............................................................................
fn:escapeXml ...........................................................................
fn:indexOf ...............................................................................
fn:join ......................................................................................
fn:length ..................................................................................
514
515
515
516
516
516
517
518
518
519
520
521
521
522
523
523
524
524
525
525
525
526
528
529
529
530
532
533
533
534
535
535
537
539
540
542
542
543
543
544
544
545
546
546
547
547
547
548
548
549
549
550
6.7.60
6.7.61
6.7.62
6.7.63
6.7.64
6.7.65
6.7.66
6.7.67
6.7.68
6.8
fn:replace .................................................................................
fn:split .....................................................................................
fn:startsWith ............................................................................
fn:substring ..............................................................................
fn:substringAfter ......................................................................
fn:substringBefore ....................................................................
fn:toLowerCase ........................................................................
fn:toUpperCase ........................................................................
fn:trim .....................................................................................
550
551
551
552
552
553
554
554
554
JSP-Ressourcen ..................................................................................... 555
Glossar
557
Index
569
Inhalt
13
Vorwort
Auch der Siegeszug der Eisenbahn begann mit einem Börsencrash.
Unbekannter Trostspender
Längst gehört es zu unseren Lebensgewohnheiten, den Fahrplan für eine Reise,
das Kinoprogramm in der Stadt, das Angebot von offenen Stellen, von
gebrauchten Autos, von Büchern, CDs und DVDs über das Internet einzusehen,
online unsere Bankgeschäfte zu erledigen, Tickets zu buchen und Artikel zu
bestellen. Das Wissen der Welt, soweit es digital aufbereitet ist, lässt sich über
Suchmaschinen anzapfen. Portale können auf die persönlichen Bedürfnisse
zugeschnittene Informationspakete mit einer erstaunlichen Aktualität zur Verfügung stellen.
All diese Angebote sind erst durch Verfahren möglich geworden, die über die
erste Phase der Internetnutzung hinausgeführt haben. Diese erste Phase war
durch die Möglichkeiten bestimmt, die auf der Basis von HTML realisiert werden konnten. Diese Technik arbeitet mit statischen Seiten, die durch Hyperlinks miteinander verkettet sind. Der Webbesucher kann über den Link zwar
von Seite zu Seite springen, aber der Inhalt all dieser Seiten ist fixiert.
Der nächste Schritt war, die statischen Inhalte durch solche zu erweitern, die
erst auf Anfrage, also dynamisch zusammengestellt werden. In erster Linie
wurde dazu eine Verzahnung von Webseiten mit Datenbanken benötigt, die
das Material liefern, um aktuelle Informationen in das Gerüst einer statischen
Seite einzubinden.
Auf dem Terrain, das mit diesem zweiten Schritt erreicht wurde, konkurrieren
eine ganze Reihe von Verfahren, und dieser Wettbewerb hat sich durchaus
günstig auf die Leistungsfähigkeit der inzwischen verfügbaren Lösungen ausgewirkt.
Eine dieser Technologien sind die JavaServer Pages (JSP), die Sun seit 1998 für
die Erzeugung dynamischer Webinhalte in den Markt eingeführt hat. Wie
HTML- oder XHTML-Seiten sind auch JSPs Textdokumente, die festlegen, wie
eine Webseite in einem Browser ausgegeben werden soll. Viele JSPs enthalten
Bestandteile, die denen von HTML- oder XHTML-Seiten entsprechen. (Eine JSP
kann sogar ausschließlich aus HTML oder XHTML bestehen.) Andere Elemente
in einer JSP können aber mehr als nur gegebene Texte, Bilder und sonstige
Medien von einem Webserver auf den Bildschirm laden. Sie sind imstande, auf
dem Server Verarbeitungsprozesse in Gang zu setzen, die die Antwort des Ser-
Vorwort
15
vers durch den Inhalt der Anfrage bestimmen. Diese Antwort wird in der Regel
in Form von HTML- oder XHTML-Seiten an den Client geschickt, was nebenbei
den Vorteil hat, dass Firewalls nicht im Wege stehen.
Aufgerufen werden können JSPs entweder direkt oder über Formulare, Links
oder spezielle Aktionen zum Inkludieren oder zur Weiterleitung von Anfragen.
Dabei können Parameter in Form von Name/Wert-Paaren übergeben werden.
JSPs können sich auch selbst aufrufen.
Der Zuspruch zu dieser Lösung ist in den letzten Jahren ständig gewachsen.
Das hat sicher mit dem Erfolg von Java als plattformunabhängiger Programmiersprache zu tun, zum anderen auch damit, dass JSP ganz in eine Architektur
eingebettet ist, die die notwendigen Dienstleistungen für anspruchsvolle
Anwendungen in Form entsprechender Bibliotheken wie JDBC, JNDI oder EJB
schon mitbringt. Gemeint ist J2EE, die Edition der Java 2-Plattform für unternehmensweite Anwendungen.
In schneller Folge wurden mehrere Versionen der JSP-Spezifikation bereitgestellt. Im Juni 1999 lag die Spezifizierung von JSP 1.0 vor, JSP 1.1 folgte schon
im Dezember. JSP 1.2 wurde 2001 verabschiedet. Dieses Buch befasst sich insbesondere mit der neuen JSP-Version 2.0. Diese Version baut auf der ServletAPI-Spezifikation 2.4 auf. JSP 2 erfordert die Java 2-Plattform in der Standard
Edition Version 1.3 für Standalone-Container bzw. 1.4 für Container, die Teil
der Umgebung Java 2 Enterprise Edition 1.4 sind. Diese Edition ist seit November 2003 verfügbar. Als Referenzimplementierung für JSP 2.0 wird der Open
Source Tomcat-Container in der Version 5.0 verwendet.
Dieses Buch gibt Ihnen einen kompakten Einstieg in die aktuelle Version von
JSP, die vermutlich die Art und Weise, wie solche Projekte in Zukunft realisiert
werden, stark verändern wird. JSP 2.0 unterstützt zwar weiterhin eine Reihe
von Verfahren, die in diesem Bereich bisher üblich waren, gemeint sind insbesondere die verschiedenen Formen von Skriptelementen. Es bietet aber zugleich deren weitgehenden oder sogar vollständigen Ersatz durch den Einsatz
von Elementen an, die klar an den inzwischen allgemein anerkannten XMLStandards orientiert sind. In gewissem Sinne befindet sich JSP also in einer Art
Übergangsstadium, sodass gelegentlich konkurrierende Verfahren für den gleichen Zweck beschrieben werden.
Die beiliegende CD enthält neben den im Buch beschriebenen Beispielen die
aktuellen Spezifikationen zu JSP 2, JSTL 1.1, Servlet 2.4 und die API-Dokumentation für J2EE 1.4, J2SE 1.4 und JSP 2.0. Auch das J2SE-SDK und die aktuellen
Tomcat 5.0-Binaries für Windows und UNIX liegen bei.
Helmut Vonhoegen
16
Vorwort
Köln, im Januar 2004
1
2
1 JavaServer Pages im
Überblick
3
4
5
1.1 Von statischen zu dynamischen Webseiten....... 19
6
1.2 Die Basis: das HTTP-Protokoll ........................... 20
7
1.3 JSP im Vergleich zu älteren Serveranwendungen 29
8
1.4 Anwendungsgebiete und -modelle.................... 39
9
1.5 Von JSP 1.2 nach JSP 2 ...................................... 41
10
1.6 Allgemeine Merkmale von JSP .......................... 44
11
12
13
14
17
1
Java Server Pages im Überblick
2
Einrichten einer Entwicklungsumgebung
3
Entwicklung dynamischer Webseiten mit JSP 2.0
4
Einrichten dynamischer Webanwendungen
5
Erweiterungen und fortgeschrittene Lösungen
6
Kurzreferenz Java Server Pages 2.0
1
2
1
JavaServer Pages im Überblick
3
Online-Dienstleistungen taugen nur etwas, wenn sie den Bedürfnissen der Besucher entsprechen. Dazu reichen statische Angebote nicht
aus.
4
5
6
Das Web wird gern als interaktives Medium betrachtet. Tatsächlich ist HTML
ein wunderbares Mittel, um bunte Seiten vom Server zum Anwender zu schicken. Mittels Hyperlinks hangelt sich der Besucher mühelos von Seite zu Seite,
und mit Hilfe von eingebauten Komponenten lassen sich Medien jeder Art auf
dem Bildschirm wiedergeben.
7
8
Dennoch bleibt das Web mit den Mitteln von HTML allein eine Einbahnstraße,
es gibt für den Besucher keine Möglichkeit – abgesehen von der Eingabe von
Webadressen –, selbst Informationen an das Web abzugeben und so seine Interessen besser ins Spiel zu bringen.
10
1.1
11
9
Von statischen zu dynamischen Webseiten
Es gibt ganz unterschiedliche Gründe für mehr Interaktion. Häufig ist es beispielsweise für die Besucher der Sites großer Medien angenehm, wenn sie eine
Vorauswahl der Themen treffen können, zu denen Inhalte angeboten werden.
Umgekehrt werden Informationsangebote oft nur dann freigegeben, wenn der
Benutzer sich beim Anbieter anmeldet und seine Berechtigung nachweist, etwa
bei abonnierten Diensten wie MedLine. Online-Anbieter möchten die Kundenbindung verstärken, indem sie den Besucher nicht nur mit seinem Namen
ansprechen, sondern ihm auch Spezialangebote vorschlagen, die zu dem passen könnten, was er bisher schon gekauft hat. E-Commerce und Online-Banking sind nicht möglich, ohne den Zugriff auf Datenbanken auf der Seite des
Servers.
12
13
14
Die Technologien, die in diesem Buch vorgestellt werden, erlauben solche
Lösungen oder sind zumindest ein bedeutender Teil davon. Die Besonderheiten dieser Verhahren ergeben sich zu einem großen Teil aus den Gegebenheiten, die durch die technische Strukur des Internets bedingt sind. Um den in den
folgenden Kapiteln beschriebenen Details ein Fundament zu geben, wird
zunächst das Kommunikationsmodell vorgestellt, das den JavaServer Pages
zugrunde liegt.
JavaServer Pages im Überblick
19
1.2
Die Basis: das HTTP-Protokoll
Die Webanwendungen, von denen in diesem Buch die Rede sein wird, können
ganz allgemein als Programme gekennzeichnet werden, die auf einem Webserver ablaufen und von Clients, in der Regel in Form von Webbrowsern, aufgerufen werden. Während dies heute noch hauptsächlich von PCs aus stattfindet,
sind schon die verschiedenartigsten Geräte auf dem Vormarsch, die den Zugriff
auf Webserver-Anwendungen auch für unterwegs erlauben: PDAs, Handys,
intelligente Armbanduhren, vielleicht demnächst auch Brillen von der Art, wie
sie in der Werbung eines bekannten Kreditkartenanbieters auftauchten.
1.2.1
Das Anfrage/Antwort-Modell
Die Basis für all diese Erweiterungen der menschlichen und maschinellen Kommunikation ist das HTTP-Protokoll, und jeder, der mit der Entwicklung von
Anwendungen zu tun hat, die dieses Protokoll als Fundament nutzen, sollte ein
paar Hintergrundinformationen dazu nicht verschmähen. Die Besonderheiten
von HTTP bestimmen nämlich sehr ausdrücklich die Art und Weise, wie Webanwendungen gestaltet werden können.
Abbildung 1.1 Schema des Anfrage/Antwort-Modells in HTTP
Das Hypertext Transfer Protocol (HTTP) ist ein bewusst einfaches Protokoll auf
der Basis des TCP/IP-Protokolls. Es wurde spezifiziert durch die Internet Engineering Task Force (IETF) in einem Request for Comments (RFC), und zwar
zunächst in RFC 1945.
Jeder HTTP-Server muss die Version HTTP/1.0 unterstützen, die meisten erlauben aber auch die erweiterte Version HTTP/1.1 (RFC 2616), die insbesondere
auch persistente Verbindungen erlaubt.
20
JavaServer Pages im Überblick
1
2
Der Kern des Kommunikationsmodells, das durch HTTP geregelt wird, lässt
sich vereinfacht als Schrittfolge beschreiben:
3
1. Ein Client öffnet eine Verbindung zum HTTP-Port eines Servers (Vorgabe ist
Port 80). Er benutzt dazu ein TCP/IP-Socket.
4
2. Er sendet über diese Verbindung eine Anfrage (Request). Ziel ist eine Ressource auf diesem Server.
5
3. Der Server lauscht auf eingehende Anfragen an dem dafür bestimmten Port.
Geht eine Anfrage darüber ein, sendet er eine Antwort (Response) an den
Socket des Clients: entweder die angeforderte Ressource oder eine Fehlermeldung, wenn die Adresse nicht stimmt.
6
4. Die Verbindung wird wieder geschlossen.
8
7
In der Regel ist der Client ein Programm, das in der Lage ist, Anfragen abzusenden, meist ein Browser. Die Anfrage kann direkt durch die manuelle Eingabe
einer Webadresse gestartet werden oder durch Anklicken eines Links oder auch
durch das Abschicken eines Formulars. Es kann aber auch z.B. eine Suchmaschine sein, die automatisch Anfragen generiert.
9
10
11
In der Rolle des Servers kann im Prinzip jedes Programm agieren, das in der
Lage ist, solche Client-Anfragen zu verstehen und mit einer entsprechenden
Antwort zu reagieren. Durch Zwischenschaltung von Proxies, Tunnels oder
Gateways kann der Ablauf der Kommunikation auch komplexere Formen
annehmen, aber davon soll hier nicht die Rede sein.
12
13
Das HTTP-Protokoll legt dabei insbesondere fest, in welchem Format diese
Nachrichten zwischen Client und Server ausgetauscht werden.
14
Bevor auf die Einzelheiten der beiden Seiten der Kommunikation eingegangen
wird, sollen noch einige wesentliche Merkmale von HTTP betont werden, die
gerade für die Webentwicklung von Bedeutung sind.
1.2.2
Verbindungslos
Aufgrund der Tatsache, dass für jedes Anfrage/Antwort-Paar eine eigene Verbindung auf- und wieder abgebaut wird, kann HTTP auch als ein verbindungsloses Protokoll bezeichnet werden. Dieses Merkmal hat seine Vor- und Nachteile. Zunächst spart der sofortige Abbau einer Verbindung, sobald der Server
seine Antwort losgeworden ist, viele Ressourcen auf der Serverseite, falls der
Server von zahlreichen Clients adressiert wird. Andererseits erhöht sich durch
die zahlreichen Verbindungsaufnahmen der Netzverkehr.
Die Basis: das HTTP-Protokoll
21
1.2.3
Ohne Zustand
HTTP ist zugleich ein zustandsloses Protokoll. Der Server behält keinerlei Informationen über den Client, sobald eine Verbindung nach dem Zusenden der
Antwort abgeschlossen ist. Die Folge davon ist, dass das Protokoll nicht merkt,
wenn ein Client A zum wiederholten Male eine Verbindung zu Server B aufbaut.
Auch über die Art des Zugangs gibt HTTP dem Server keinen Aufschluss, der
Server kann also nicht unterscheiden, ob eine Anfrage durch Anklicken eines
Links, durch Abschicken eines Formulars oder durch Klick auf die Schaltfläche
Zurück erfolgt ist.
Für HTTP sind alle Verbindungen gleich, und nach ihrer Beendigung gibt es
keine »Erinnerung« an das, was früher geschehen ist. Hier unterscheidet sich
HTTP deutlich von FTP, bei dem Verbindungen aufgebaut werden können, die
für mehrere Anfragen bestehen bleiben.
Dass HTTP ein zustandsloses Protokoll ist, hat den Vorteil, dass weniger Ressourcen auf dem Server verbraucht werden und so mehr gleichzeitige Zugriffe
möglich sind.
Wo es aber notwendig ist, HTTP-Verbindungen mit einer Art Erinnerungsvermögen auszustatten, müssen besondere Maßnahmen ergriffen werden, wie sie
in Abschnitt 3.18 beschrieben werden.
1.2.4
Aufbau von HTTP-Nachrichten
Wie die Anfrage eines Clients und die Antwort eines Servers aussehen können,
ist durch das HTTP-Protokoll genau beschrieben. Beide Nachrichtentypen
haben einen gemeinsamen Aufbau, der aber unterschiedlich ausgefüllt wird.
Jede Nachricht setzt sich aus folgenden Komponenten zusammen:
왘 Startzeile
왘 Nachrichten-Header*
왘 CRLF
왘 [Nachrichtenrumpf]
Die erste Zeile ist erforderlich, die Anzahl der Header-Zeilen kann ganz unterschiedlich sein, je nachdem, welche Informationen an die jeweils andere Seite
übergeben werden sollen. Dabei wird zwischen allgemeinen Headern, Anfragebzw. Antwort-Headern und solchen unterschieden, die sich speziell auf die
Nachrichten beziehen, die im Nachrichtenrumpf enthalten sind, falls ein solcher verwendet wird. Dieser Teil wird von den Headern jeweils durch eine
22
JavaServer Pages im Überblick
1
2
Leerzeile abgetrennt. Die Header werden in Form von Name/Wert-Paaren
angegeben.
3
1.2.5
4
Das Format der Anfrage
Bei jeder Anfrage eines Clients an einen Webserver wird ein URL verwendet,
der zunächst das Protokoll und den gewünschten Server und dann die Ressource angibt, auf die auf diesem Server zugegriffen werden soll. Der Webserver lauscht auf eingehende Anfragen über einen bestimmten Port, Vorgabe ist
der Port 80. Diese Vorgabe kann geändert werden, indem die gewünschte Portnummer hinter der Angabe des Servers, getrennt durch einen Doppelpunkt,
angehängt wird:
5
6
7
8
http://www.helmut-vonhoegen.de:8080/index.html
9
Die erste Zeile bei einer Anfrage ist eine Anfragezeile (request-line), bei der
Antwort eine Statuszeile (status-line).
10
Wird beispielsweise ein URL wie
http://www.helmut-vonhoegen.de/index.html
11
eingegeben, besteht die Anfragezeile aus:
12
GET /index.html HTTP/1.1
13
Die erste Zeile einer Anfrage gibt zunächst die Anfragemethode an und
benennt die Ressource, die angefordert wird. Dann folgt die vom Browser verwendete HTTP-Version.
14
Anfragemethoden
GET ist die vorgegebene Methode, die für normale Aufrufe von HTML-Seiten
und JSPs verwendet wird. Sie fordert einfach vom Webserver die angegebene
Ressource an. Ein Nachrichtenrumpf wird nicht verwendet.
Die POST-Methode, die ebenfalls im Zusammenhang mit JSP eingesetzt wird,
erlaubt es, mit der Anfrage auch größere Datenmengen zu übertragen, die
jeweils im Nachrichtenrumpf zusammengestellt werden.
Die anderen hier möglichen Methoden – HEAD, CONNECT, DELETE, OPTIONS, PUT
und TRACE – spielen im Zusammenhang mit JSP normalerweise keine Rolle.
Header
Die Liste der möglichen Header ist ziemlich lang und kann unter
www.w3.org/Protocols/rfc2616/rfc2616-sec14.html nachgesehen werden.
Die Basis: das HTTP-Protokoll
23
Beschrieben werden hier nur einige der am häufigsten verwendeten Header in
der Anfrage.
Host – Dieses Feld ist das einzige, das in jeder Anfrage enthalten sein muss.
Angegeben wird der Name des Webservers und eventuell die Portnummer, wie
sie aus dem verwendeten URL ausgelesen werden kann. Falls der IP-Adresse
eines Servers mehrere Servernamen zugeordnet sind, kann so zwischen den
verschiedenen virtuellen Hosts unterschieden werden.
Host: www.w3.org
Connection – Mit dem Wert close wird der Server angewiesen, die Verbindung zu schließen, sobald die Übertragung der Antwort abgeschlossen ist. Die
Alternative ist keep-alive, wenn die Verbindung aufrechterhalten bleiben soll.
Connection: close
User-Agent – übergibt Informationen zu dem verwendeten Browser. Die
Abfrage dieser Information erlaubt dem Server beispielsweise, unterschiedliche Seiten zurückzugeben, je nachdem, welcher Browser im Einsatz ist. Dieser
Header kann auch darauf hinweisen, dass ein Browser auf einem PDA oder
Handy genutzt wird.
User-Agent: Mozilla/4.51 [en] (WinNT; I]
Eine Gruppe von Headern liefert dem Server Hinweise, wie die Antwort an den
Browser an dessen Möglichkeiten angepasst werden kann:
Accept – wird verwendet, um die Medientypen (also die MIME-Typen) aufzulisten, die der Browser akzeptieren kann.
Accept: audio/*, text/html, image/gif, image/jpeg
Accept-Charset – gibt die Zeichensätze an, mit denen der Browser etwas
anfangen kann.
Accept-Charset: iso-8859–5
Accept-Encoding – informiert über die möglichen Kodierungen, die für den
Inhalt der Antwort verwendet werden können.
Accept-Encoding: compress, gzip
Accept-Language – gibt die in der Antwort bevorzugten Sprachen an.
Accept-Language: de, en
24
JavaServer Pages im Überblick
1
2
Anfrageparameter
3
Wenn bei einer Anfrage die GET-Methode verwendet wird, lassen sich an den
URL Parameter anhängen, die der Server zur Generierung der Antwort verwenden kann, etwa bei der Abfrage einer Datenbank. Soll beispielsweise eine Liste
mit Artikeln einer bestimmten Modellgruppe angefordert werden, kann der
Name der Modellgruppe als Parameter übergeben werden. Parameter werden
nach einem trennenden Fragezeichen hinter den URL in Form von Name/WertPaaren angehängt, die selbst wieder durch &-Zeichen getrennt werden, wie in
dem folgenden Beispiel:
4
5
6
7
http://www.lichtlager.de/deckenlampen?modellgruppe=halogen&preisgruppe=A
8
Dabei muss eine bestimmte Kodierung beachtet werden, die Zeichen maskiert,
die innerhalb eines URL nicht in der Bedeutung verwendet werden sollen, wie
sie nach der URL-Syntax vorgesehen sind. Die untenstehende Tabelle listet die
Escape-Codes für diese Zeichen auf.
10
Anfragerumpf
11
Bei der HTTP-Methode POST werden die Daten, die an den Server übergeben
werden sollen, etwa die Eingaben in einem Formular, nicht als Parameter an
den URL, sondern hinter den Headern als Rumpf
12
9
13
Zeichen
Escape-Code
Leerzeichen
%20
»
%22
~
%7E
.
%2E
,
%2C
<
%3C
>
%3E
#
%23
%
%25
{
%7B
}
%7D
|
%7C
\
%74
14
Die Basis: das HTTP-Protokoll
25
Zeichen
Escape-Code
^
%5E
~
%7E
[
%5B
]
%5D
'
%60
;
%3B
/
%2F
?
%3F
:
%3A
@
%40
=
%3D
&
%26
Diese Parameter lassen sich entweder manuell an den URL anfügen oder über
ein Formular, das die jeweiligen Werte abfragt. Sobald die Submit-Schaltfläche
benutzt wird, werden die Parameter gesetzt.
Anfragerumpf
Bei der HTTP-Methode POST werden die Daten, die an den Server übergeben
werden sollen, etwa die Eingaben in einem Formular, nicht als Parameter an
den URL, sondern hinter den Headern als Rumpf der Nachricht angehängt. Auf
diese Weise können bei einer Anfrage auch größere Datenmengen übertragen
werden. Mehr dazu im Abschnitt zu den HTML-Formularen.
1.2.6
Das Format der Antwort
Die Antwort des Servers folgt immer unmittelbar auf die Anfrage des Clients.
Der Server versucht, die in der Anfrage angegebene Ressource zu finden, sei
dies nun eine einfache Webseite oder ein Programm wie etwa ein CGI-Skript.
Die Antwort ergibt sich folglich aus dem, was dem Server durch die Abfrage
abverlangt wird. Das Format der Antwort entspricht in der Grundstruktur dem
der Anfrage. Sie ist zusammengesetzt aus einer Reihe von Antwort-Headern
und einem Antwort-Rumpf. Die Antwort-Header sind insbesondere dazu da,
dem Browser Informationen zu liefern. Diese benötigt er, um mit dem Antwort-Rumpf etwas anfangen zu können, um Cookies zu setzen oder um zu
26
JavaServer Pages im Überblick
1
2
einer anderen Seite umzuleiten. Grundsätzlich werden immer erst die Header
an den Browser geschickt, bevor der Rumpf übermittelt wird.
3
Statuszeile
4
Die erste Zeile ist immer eine Statuszeile, die sofort erkennen lässt, ob die
Anfrage erfolgreich bearbeitet werden konnte oder nicht. Die Statuszeile
benennt das verwendete Protokoll, gibt dann einen Statuscode in Form einer
dreistelligen Zahl und danach eine Kurzbeschreibung der durch den Statuscode
identifizierten Situation an. Eine erfreuliche Statuszeile sieht deshalb so aus:
5
6
7
HTTP/1.1 200 OK
Die Anfrage wurde vom Server entgegengenommen, verstanden und akzeptiert. Wird die Ressource nicht gefunden, gibt es den weniger erfreulichen
Code 400 bad request. Wird der Zugriff auf eine Seite verweigert, weil der
Benutzer sich nicht identifizieren kann, ist der Code 401 unauthorized.
8
Die Statuscodes sind nach der ersten Zahl in fünf Klassen eingeteilt, die in der
Tabelle beschrieben sind:
10
9
11
Code-Bereich
Kategorie
Bedeutung
1xx
Information
provisorischer Code für experiementelle Anwendungen,
wird nur von HTTP/1.1 verwendet
2xx
Erfolgreich
gibt an, dass eine Anfrage erfolgreich bearbeitet wurde
3xx
Umleitung
Der Server fordert die Weiterleitung der Anfrage an eine
andere Stelle an.
4xx
Client-Fehler
Codes für Fehler auf der Client-Seite, z.B. ein falsch eingegebener URL für eine Ressource, die deshalb nicht
gefunden werden kann
5xx
Server-Fehler
Codes für Fehler auf der Serverseite. Der Server kann
beispielsweise eine Anfrage nicht ausführen, obwohl der
URL in Ordnung ist, etwa wegen Überlastung der Verbindungen.
12
13
14
Die vollständige Liste der Codes ist unter www.w3.org/Protocols/rfc2616/
rfc2616-sec10.html zu finden.
Antwort-Header
Hinter der Statuszeile folgen üblicherweise einige Header, wie in dem folgenden Beispiel:
Die Basis: das HTTP-Protokoll
27
HTTP/1.1 200 OK
Date: Sat, 04 Mar 2003 13:39:02 GMT
Accept-Ranges: bytes
Server: Apache/1.3.1
Content-Length: 1280
Content-Type: text/html
Last-Modified: Fri, 03 Mar 2003 06:54:40 GMT
<html>
<head>
...
Auch in der Antwort kommen unterschiedliche Typen von Headern vor. Einige
enthalten allgemeine Informationen im Zusammenhang mit der Antwort, z.B.:
왘
Date – gibt das Datum der Antwort an.
왘 Andere Header betreffen Informationen über die Antwort selbst:
왘
Server – gibt den Namen des verwendeten Servers bzw. des Serverprogramms und der verwendeten Version an.
왘
Accept-Ranges – zeigt an, dass auch Anfragen zu einzelnen Bereichen der
Ressource möglich sind, und gibt die Einheit an, die dabei verwendet werden kann.
Eine Reihe von Headern beziehen sich auf den Inhalt des Nachrichtenrumpfes in der Antwort:
왘
Content-Length – gibt die Länge des nach der Leerzeile angehängten Nachrichtenrumpfes an.
왘
Content-Type – gibt den Inhaltstyp des Nachrichtenrumpfes an, also ob es
sich z.B. um HTML- oder XML-Code oder um einfachen Text handelt. Hier
wird der entsprechende MIME-Typ eingetragen, an dem der Browser erkennen kann, ob er für die Darstellung der Daten möglicherweise auf ein Plugin
zurückgreifen muss.
왘
Last-Modified – liefert das Datum der letzten Änderung an dem Nachrichtenrumpf oder an der wiedergegebenen Ressource. Der Browser kann diese
Information in einem lokalen Cache als Zeitstempel verwenden, sodass Ressourcen nur dann neu angefordert werden müssen, wenn sie sich seit der
letzten Anfrage geändert haben.
Antwortrumpf
Der Rumpf der Antwort kann einfache HTML-Seiten enthalten oder auch
andere Inhaltstypen wie XML etc. Sind im Rumpf Tags enthalten, die selbst
28
JavaServer Pages im Überblick
1
2
wieder auf andere Ressourcen verweisen, etwa ein <img>-Tag für ein Bild,
erzeugt der Browser bei der Entgegennahme der Antwort daraus automatisch
eine erneute, spezielle Anfrage an den Server, diese Ressource ebenfalls zu liefern. Das Laden einer großen Seite mit vielen Bildern und sonstigen eingeschlossenen Ressourcen – Videos, Audiostreams etc. – kann sich also zu einem
munteren Anfrage/Antwort-Spiel auffächern, bis eine Seite endlich vollständig
zu sehen ist. Das führt bei langsamen Modemverbindungen zu den gefürchteten Wartezeiten.
1.2.7
3
4
5
6
Beobachtung der HTTP-Kommunikation
7
Wenn Sie die Client/Server-Kommunikation im Detail überprüfen wollen, können Sie eines der Tools verwenden, das die HTTP-Nachrichten sichtbar macht.
Die Abbildung zeigt ein Dialogfenster des ProtocolExplorers, der auf der Seite
www.sourcestream.com von Dustin R. Callaway angeboten wird.
8
9
10
11
12
13
14
Abbildung 1.2 HTTP-Nachrichten bei einer Anfrage
1.3
JSP im Vergleich zu älteren Serveranwendungen
Der erste Lösungsansatz für dynamische Webseiten, der auch heute noch bei
vielen Formularseiten verwendet wird, benutzt das so genannte Common
Gateway Interface (CGI). Diese »Allgemeine Übergangsschnittstelle« bot zum
JSP im Vergleich zu älteren Serveranwendungen
29
ersten Mal die Möglichkeit, Daten vom Anwender zum Server zu schicken und
auf diesem Weg an den Anbieter einer Website weiterzuleiten. Die Schnittstelle regelt, wie der Browser dabei mit Programmen auf der Serverseite kommuniziert.
1.3.1
Common Gateway Interface
Der Ansatz des CGI ist relativ einfach. Bei normalen Webseiten wird von einem
Browser aus ein URL an den Webserver geschickt. Findet der Server die adressierte Seite, wird sie unverändert an den Browser geschickt und darin angezeigt. Bei einem CGI-Aufruf dagegen lokalisiert der aufrufende URL keine
HTML-Seite, sondern ein Programm oder Skript auf dem Webserver. Wenn der
Server die Anfrage empfängt, setzt er eine Reihe von Umgebungsvariablen, auf
die die CGI-Anwendung zugreifen kann. Dazu gehören etwa die Portnummer,
der Skriptname, der Abfragestring, der Inhaltstyp und die Länge der Daten, die
dem Skript übergeben werden, um nur einige zu nennen.
Der Server startet nach diesen Vorbereitungen die Anwendung. Vom Besucher
eingegebene Daten werden entweder als Parameter, die an den URL angehängt
sind, übergeben oder im Nachrichtenrumpf der Anfrage. Diese Daten werden
über die Standardeingabe an das CGI weitergereicht.
Das Programm verwendet die übergebenen Daten, um damit etwas mehr oder
weniger Sinnvolles zu tun, und schickt eine Antwortseite zurück. Das kann
eine einfache Bestätigung sein, dass ein Formular empfangen wurde, oder auch
das Ergebnis einer Datenbankabfrage, die von dem CGI-Skript ausgeführt wird.
Das Skript schreibt dazu diese Antwort einfach in die Standardausgabe, und der
Server schickt sie an den Client.
Die weite Verbreitung von CGI-Lösungen hat sicher auch damit zu tun, dass
CGI-Programme in zahlreichen Sprachen geschrieben werden können. Provider stellen häufig Bibliotheken mit verwendbaren CGI-Anwendungen zur Verfügung, um Standardfunktionen anzubieten.
Typische Aufgaben sind:
왘 Formmailer – Weiterleiten von ausgefüllten Formularen per E-Mail an den
Anbieter
왘 Suchfunktionen – Auffinden von Informationen innerhalb umfangreicher
Websites
왘 Besucherzähler – Messung der Zugriffe auf einzelne Webseiten
Die CGI-Lösung bringt aber eine Reihe von Nachteilen, die sehr bald die Suche
nach Alternativen angestoßen hat. Der gravierendste Nachteil ist, dass der
30
JavaServer Pages im Überblick
1
2
Webserver für jede Anfrage einen eigenen Systemprozess starten und einen
Sprach-Interpreter laden muss, der dann das Skript ausführt. Kommen zahlreiche Anfragen gleichzeitig an, geht die Performanz leicht in die Knie. Da jeder
CGI-Prozess separat ausgeführt wird, ist es auch schwierig, Daten zwischen verschiedenen CGI-Anwendungen auszutauschen, etwa um eine Sitzungsverfolgung zu realisieren. Zwar hat hier die Erweiterung FastCGI, die von der Firma
Open Market entwickelt wurde, insofern eine Verbesserung erlaubt, als dass
mehrere Anfragen in einem permananten Prozess abgearbeitet werden können. Diese Lösung wird aber nur von einigen Servern unterstützt.
3
4
5
6
7
1.3.2
Servererweiterungen
8
Die Einschränkungen der CGI-Lösung führten zu einer Reihe von Alternativen
in Form von speziellen Servererweiterungen. Webserver-APIs sorgen dafür,
dass nicht für jede Anfrage ein neuer Prozess gestartet werden muss. Die
Anwendungen werden nach der ersten Anfrage im Speicher gehalten und über
Funktionsaufrufe für alle folgenden Anfragen genutzt. Dazu zählen das NSAPI
auf dem Webserver von Netscape/iPlanet, das ISAPI auf dem Internet Information Server (IIS) von Microsoft und das Apache-API auf dem bekannten Apache
Webserver.
9
10
11
12
Webserver-APIs bringen insbesondere Geschwindigkeitsvorteile gegenüber
den CGI-Lösungen. Zugleich werden aber auch die Funktionsmöglichkeiten
erweitert, weil diese Interfaces Zugriff auf die internen Strukturen des jeweiligen Servers haben. Der Nachteil ist allerdings, dass Anwendungen, die diese
APIs nutzen, nicht ohne weiteres auf andere Server übertragen werden können
und dass sie an bestimmte Sprachen gebunden sind.
1.3.3
13
14
Java-Servlets
In der Java-Welt – Start 1994 – führte Sun 1996 eine ähnliche Lösung ein: Servlets als Komponenten auf der Serverseite. Dazu wurde die Spezifikation für ein
Servlet-API entwickelt, die inzwischen bis zu der Version 2.4 fortgeschritten
ist. Sie beschreibt die Interfaces und Klassen, die Servlets nutzen, um Webanwendungen mit dynamischen Inhalten generieren zu können.
Allerdings geschieht dies gewissermaßen im Hintergrund, denn Servlets haben
anders als Java-Applets, die sich direkt in einem Browser zeigen und ihre Steuerelemente anbieten, keine grafische Schnittstelle. Dafür haben sie den Vorteil,
dass sie auf einer virtuellen Maschine in einer kontrollierten Serverumgebung
ablaufen und für die Kommunikation mit den Clients nur auf HTTP angewiesen
sind. Deshalb sind Servlets auch nicht von den Einschränkungen betroffen, die
einem Applet durch die Umgebung, in der es innerhalb eines Browsers laufen
JSP im Vergleich zu älteren Serveranwendungen
31
soll, gesetzt sind. Das Ergebnis eines Servlets wird auf dem Client einfach in
HTML ausgegeben, was selbst für ältere Browser keine Probleme aufwirft. Auf
dem Client muss also keine zusätzliche Software installiert sein.
Klassen für die HTTP-Kommunikation
Zunächst einmal sind Servlets reguläre Java-Klassen. Sie unterscheiden sich
aber von anderen Java-Anwendungen dadurch, dass sie nur in einer bestimmten Umgebung ausgeführt werden können. Diese gibt vor, was ein Servlet kann
und was nicht. Deshalb werden Servlets auch als Erweiterung von zwei speziellen Klassen realisiert, die es erlauben, die durch das HTTP-Protokoll gegebenen Formen der Kommunikation zwischen Webbrowser und Webserver zu
nutzen. Dies sind die Klassen GenericServlet und HTTPServlet.
Diese Klassen bieten zahlreiche vordefinierte Methoden an, und die Aufgabe
der Entwicklung besteht im Wesentlichen darin, entsprechende Unterklassen
daraus zu bilden und die Methoden passend zu überschreiben, die für eine
bestimmte Anwendung benötigt werden.
Servlets erlauben es, auf eine Anfrage an den Webserver nicht einfach statische
Inhalte, die in Form von Webseiten auf dem Server vorliegen, zurückzugegeben, sondern Informationen, die das Servlet aktuell durch Verarbeitung der
vorliegenden Daten generiert.
Ein Servlet stellt also auf der Basis von Daten, die im Zuge einer Anfrage übergeben werden, etwas Bestimmtes an, und erst die Ergebnisse dieser Aktivitäten
werden in Form einer Antwortseite im Browser wieder sichtbar.
Komponenten und Container
Webanwendungen, die mit Hilfe von Servlets realisiert werden, sind Softwarekomponenten, die zur Ausführung eine spezielle Laufzeitumgebung benötigen.
Diese Umgebung wird in der Java-Welt durch Container hergestellt. Während
für Applets auf der Client-Seite ein Applet-Container benötigt wird, benötigen
Servlets auf der Serverseite einen Servlet-Container.
Alle Servlet-Container müssen den Servlets bestimmte Dienste anbieten, die
jedes Servlet braucht, wenn es eingesetzt werden soll. Und sie müssen diese
Dienste in derselben Weise anbieten, damit Servlets, die auf einem bestimmten
Container entwickelt wurden, auch auf jeden anderen Servlet-Container übertragen werden können. Diese Einheitlichkeit wird dadurch gewährleistet, dass
die Container der Servlet-Spezifikation entsprechen müssen. Container stellen
außerdem bestimmte Werkzeuge – Deployment Tools – zur Verfügung, mit
denen Komponenten innerhalb des Containers eingerichtet und konfiguriert
32
JavaServer Pages im Überblick
1
2
werden können. Dabei werden Deskriptoren in Form von XML-Dokumenten
verwendet.
3
4
5
6
7
8
9
10
11
Abbildung 1.3 Server, Servlet-Container und Servlets
12
Die Hauptaufgabe des Servlet-Containers ist, den so genannten Lebenszyklus
der Servlets zu managen. Der Container lädt meist die Klasse eines Servlets,
wenn die erste Anfrage danach von einem Browser eingeht, legt die Eingangswerte fest und ermöglicht dann die Abarbeitung der Anfrage. Weitere Anfragen
können das bereits initialisierte Servlet erneut verwenden, bis der Server
schließlich heruntergefahren wird. Der Container gibt dem Servlet die Möglichkeit, genutzte Ressourcen wieder freizugeben und Zustandsinformationen,
die während des Lebenszyklus erworben wurden, zu sichern.
13
14
Serverprozess und Threads
Dabei benutzen Servlets denselben Prozessraum wie der Webserver selbst, dessen Wirkungsmöglichkeiten sie erweitern. Sie werden wie gesagt nur einmal
geladen, entweder bei der ersten Anfrage oder auch gleich beim Start des Servers. Jede einzelne Anfrage kann dann als ein separater Ausführungspfad, als
Thread, innerhalb dieses permanenten Prozesses behandelt werden. Das wiederum eröffnet die Möglichkeit, in einem einzigen Prozess auch mehrere
Threads parallel zu handhaben. Ist ein Servlet einmal geladen, können alle
Anfragen an dieses Servlet, die gleichzeitig eingehen, auf mehrere Threads verteilt werden.
JSP im Vergleich zu älteren Serveranwendungen
33
Servlets haben dabei Zugriff auf die Dienste, die der Webserver zur Verfügung
stellt, z.B. Logbuchfunktionen, Benutzeridentifizierung etc. Außerdem kann
auf Ressourcen zugegriffen werden, die zwischen verschiedenen Anfragen im
Speicher verbleiben, etwa geöffnete Datenbankverbindungen.
Automatische Kompilierung
Weitere Vorteile ergeben sich daraus, dass Servlets beim ersten Aufruf kompiliert werden und nur bei einer Änderung erneut kompiliert werden müssen.
Insofern sind diese Komponenten wesentlich schneller als Skriptlösungen, die
jedes Mal neu interpretiert werden. Da es sich um Java-Klassen handelt, ist
auch die Überprüfung der verwendeten Datentypen immer streng, sodass Fehler in diesem Bereich schon bei der Kompilierung entdeckt werden und nicht
erst bei der Ausführung auffallen.
Java Virtual Machine – JVM
Wie bei den Java-Applets werden auch Java-Servlets von einer virtuellen JavaMaschine (JVM) ausgeführt. Auf diese Weise wird der direkte Zugriff auf den
Speicher vermieden und somit werden Möglichkeiten für einem Systemcrash
minimiert. Bei Problemen werden Ausnahmen erzeugt, die von den Anwendungen behandelt oder abgefangen werden können.
Plattformunabhängigkeit
Da Servlets als Java-Klassen realisiert werden, gelten natürlich auch für Servlets
die allgemeinen Vorzüge der Sprache bezüglich der Übertragbarkeit auf verschiedene Plattformen und Serverumgebungen. Servlets können inzwischen
auf fast allen marktgängigen Webservern eingesetzt werden. Entweder unterstützen die Server den Einsatz von Servlets direkt oder mit Hilfe von entsprechenden Add-Ons.
Seitengenerierung über Servlets
Was bisher zu Servlets gesagt wurde, zeigt diese Technik als mächtiges Instrument für die Generierung von dynamischen Webinhalten. Die Art und Weise,
wie ein Servlet schließlich die sichtbare Antwort auf eine Anfrage erzeugt, kann
aber nicht überzeugen.
Der HTML-Code, der schließlich für die Anzeige der Antwort auf dem Browser
benötigt wird, muss durch häufig unübersichtliche Folgen von Ausgabeanweisungen generiert werden, wie schon das folgende kleine Beispiel zeigt
(Anrede.java):
34
JavaServer Pages im Überblick
1
2
import javax.servlet.*;
import javax.servlet.http.*;
public class anrede extends HttpServlet {
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
3
4
5
6
response.setContentType("text/html");
PrintWriter out = response.getWriter();
String name = request.getParameter("gast");
out.println("<HTML>");
out.println("<HEAD><TITLE>Gruss</TITLE></HEAD>");
out.println("<BODY>");
out.println("Guten Tag " + name);
out.println("</BODY></HTML>");
7
8
9
}
10
}
Der entscheidende Nachteil von Servlets ist offensichtlich: Eine klare Trennung
von Anwendungslogik und Präsentation bei der Entwicklung von Webanwendungen ist unmöglich. Selbst kleine Änderungen an der Darstellung einer Seite
erfordern, dass das Servlet neu kompiliert wird. Für die Entwicklung von Servlets werden zudem Programmierer benötigt, die mit Java umgehen können.
Die Webdesigner können mit dieser Form der Seitengestaltung in der Regel
aber nicht glücklich werden. Alternativen waren also gefragt.
1.3.4
11
12
13
14
Active Server Pages
Um die Entwicklung von dynamischen Webanwendungen zu vereinfachen,
führte Microsoft auf der Basis seines Internet Information Servers (IIS) die
Active Server Pages (ASP) ein. Dabei handelt es sich um Webseiten, bei denen
der normale HTML-Code mit Einschüben aus Skriptelementen gemischt ist.
Anders als bei Lösungen mit Skriptelementen, die direkt im Browser aktiviert
werden, etwa mit JavaScript oder VBScript, geht es hier aber um Skripte, die
auf dem Server ausgeführt werden, um auf der Basis des HTTP-Protokolls dynamische Antwortseiten zu erzeugen, die an den Webbrowser zurückgegeben
werden.
Webentwickler bewegen sich dabei über weite Strecken in ihrer vertrauten
HTML- oder auch DHTMLWelt. Nur an den Stellen, an denen dynamische
Inhalte verlangt werden, sind spezielle Blöcke mit Skriptcode nötig. Sie werden
JSP im Vergleich zu älteren Serveranwendungen
35
jeweils durch die Begrenzer <% und %> von den HTML-Elementen abgesondert.
Das kleine Beispiel zeigt, wie dies aussehen kann:
<%@ LANGUAGE="VBSCRIPT" %>
<% Response.Expires=0 %>
<html>
<head>
<title>Zeitansage</title>
</head>
<body>
<h2>Die aktuelle Zeit ist: <%= Now%></h2>
</body>
</html>
Als Skriptsprache wird meistens VBScript oder JScript verwendet, obwohl die
Laufzeitumgebung im Prinzip auch von anderen Sprachen wie Perl oder Python
genutzt werden kann. Der Webserver reicht die Aufrufe von ASP-Seiten an eine
ISAPI-Servererweiterung weiter, die dafür sorgt, dass das ASP-Dokument von
der ASP.DLL interpretiert wird. COM-Komponenten können über die Skriptelemente eingebunden werden, um komplexere Aufgaben zu erledigen.
Diese Technik führte zu einer spürbaren Vereinfachung, wenn es darum ging,
Websites mit dynamischen Inhalten zu erzeugen. Wesentlichster Nachteil war
aber die Einschränkung durch die Bindung an die Windows-Plattform, auch
wenn es mit Produkten wie Chili!Soft ASP von Sun und InstantASP von Halcyon Software eine begrenzte Unterstützung für andere Plattformen gab.
1.3.5
Von Servlets zu JavaServer Pages
Auf der Basis des Java Servlet-APIs führte schließlich auch Sun 1998 eine Lösung
ein, die eine bessere Trennung von Webseitendesign und Programmierung von
Anwendungslogik erlaubt: die JavaServer Pages, abgekürzt JSP. Dabei werden die
Vorteile der Servlet-Lösung insofern beibehalten, als JSPs auf dem Webserver
automatisch in Servlets übersetzt und als Servlets ausgeführt werden.
Zudem können Webanwendungen Servlets und JSPs auch mischen. Dies wird
in neuen Anwendungsarchitekturen wie Struts genutzt, die eine strenge Trennung zwischen der Anwendungslogik, der Steuerung der Aufgabenverteilung
und der eigentlichen Datenpräsentation vornehmen, wobei Servlets für die beiden ersten Bereiche und JSP für die Darstellung auf dem Client eingesetzt werden. Dies ist insbesondere bei großen Unternehmensanwendungen sinnvoll,
die von Entwicklerteams realisiert und gepflegt werden. Mehr dazu in
Abschnitt 1.4 und 5.6.
36
JavaServer Pages im Überblick
1
2
3
4
5
6
7
8
9
Abbildung 1.4 Von der JSP über das Servlet zur HTML-Ausgabe
10
Der Schwerpunkt dieses Einstiegs liegt auf der JSP-Technologie. Das ServletAPI, das ja bei der Ausführung von JSPs direkt zum Einsatz kommt, wird also
hier im Wesentlichen nur im Zusammenhang mit JSP behandelt.
11
Es ist kein Geheimnis, dass die »aktiven Seiten auf dem Server« in vielen ihrer
Merkmale auch für die JavaServer Pages Pate gestanden haben. Das voneinander Lernen ist schließlich die Basis jeden Fortschritts. Ähnlich wie bei einer
ASP-Seite wird der normale HTML- oder XHTML-Code, der für das Äußere der
Seite sorgt, durch abgesonderte Inseln mit JSP-Elementen erweitert. Diese sorgen dafür, dass auf der Seite des Servers eine bestimmte Verarbeitung ausgeführt wird, die in die statische HTML-Seite den Inhalt von dynamischen Elementen einfügt.
1.3.6
12
13
14
Arbeitsteilung zwischen Programmierung und Seitendesign
Während die HTML-Elemente in einer JSP so, wie sie sind, in der Ausgabe wiedergegeben werden, stoßen die JSP-Elemente auf dem Webserver Verarbeitungsprozesse an, von deren Ergebnis dann abhängt, was an der Stelle
erscheint, an der die Elemente stehen. Wenn also beispielsweise ein JSP-Element eine Datenbank auf dem Server mit einem bestimmten Kriterium abfragt,
erscheinen die bei dieser Abfrage gefundenen Datensätze an der entsprechenden Stelle.
Um solche dynamischen Lösungen zu ermöglichen, stellt JSP zunächst eine
Reihe von Standardelementen zur Verfügung, Aktionen für typische Aufgaben,
Direktiven oder Skriptelemente. Seit der JSP-Version 1.1 wird zusätzlich ein
JSP im Vergleich zu älteren Serveranwendungen
37
Erweiterungsmechanismus angeboten, der mit Hilfe von benutzerdefinierten
Aktionen und von JavaBeans oder Enterprise JavaBeans den Entwicklern ein
weites Feld öffnet. Durch solche Komponenten lassen sich auch komplexe
Abläufe so kapseln, dass Designer, die diese in ihre Seite einbauen, über die
Details nicht viel wissen müssen. All dies erleichtert die Arbeitsteilung, wenn
große Sites in Teams aus Designern und Programmierern zu realisieren sind.
Es soll aber nicht unerwähnt bleiben, dass die Mischung von HTML- und JSPElementen in umfangreichen JSP-Anwendungen auch leicht zu einer unübersichtlichen Situation führen kann. Die Anordnung der verschiedenen Elemente
ist in keiner Weise vorgeschrieben, kann also auch weniger gelungen sein. In
solchen Fällen wird vor allem die Fehlersuche zu einem harten Job. Auch die
Pflege solcher Sites kann Kopfschmerzen bereiten. Oft ist es deshalb ratsam,
eine Anwendung modular aus kleineren Komponenten aufzubauen, die sich
einzeln testen lassen. Hier kann insbesondere das Model-View-ControllerModell helfen, das im nächsten Abschnitt beschrieben wird.
1.3.7
Was spricht für JSP?
Zu den Vorteilen, die JSP gegenüber ASP vorweisen kann, gehört gewiss die
Verwendung von Java, wodurch die Implementierung von Webanwendungen
auf unterschiedlichen Plattformen entscheidend vereinfacht wird. Die meisten
populären Webserver sind in der Lage, entweder direkt oder indirekt durch
entsprechende Add-Ons JSP-Lösungen zu beherbergen. Virtuelle Java-Maschinen stehen auf allen Plattformen zur Verfügung. Außerdem ist Java eine komplette Programmiersprache, unterliegt also nicht den Einschränkungen, die für
Skriptsprachen typisch sind.
Ein wesentliches Merkmal von JSP ist die Erweiterbarkeit. Die Erweiterungsmechanismen sind gerade in der neuen JSP-Version noch einmal ausgebaut
und zugleich vereinfacht worden. Dabei werden insbesondere auch die Vorteile der allgemein anerkannten XML-Standards genutzt.
Eine Besonderheit von JSP ist sicher auch, dass es sich um eine Spezifikation
handelt und nicht um ein fertiges Produkt. Es gibt zwar eine Referenzimplementierung für jede JSP-Version, deren Zweck es ist, am praktischen Beispiel zu
klären, wie spezielle Merkmale der Spezifikation in der Praxis anzuwenden
sind. Unabhängig davon aber können Anbieter eigene Implementierungen der
Spezifikation entwickeln und dem Sturm der Konkurrenz aussetzen.
Die Auseinandersetzung um die beste Lösung für die angesprochenen Probleme ist natürlich überhaupt nicht abgeschlossen. In mancher Hinsicht ist
ASP.NET – der Nachfolger von ASP – wiederum als Antwort auf die Merkmale
38
JavaServer Pages im Überblick
1
2
zu verstehen, die JSP über ASP hinausgeführt haben. Beispielsweise werden
ASP.NET-Seiten nun auch vor der Ausführung kompiliert, was deutliche
Geschwindigkeitsgewinne gegenüber interpretierten Skripten erlaubt. Beide
Technologien konkurrieren auf einem hohen Level miteinander, der Sache
kann das nur gut tun.
3
4
5
1.4
Anwendungsgebiete und -modelle
6
Um in statische Webseiten dynamische Elemente einzubauen, stehen eine
Reihe von Verfahren auf der Client-Seite und auf der Serverseite zur Verfügung.
Manche Aufgabe kann sowohl auf der einen als auch auf der anderen Seite
gelöst werden.
1.4.1
7
8
JSP oder DHTML?
9
Anwendungen auf der Serverseite sind sicher immer dann zu bevorzugen,
wenn es um Seiten geht, die auf umfangreiche Datenbestände zugreifen. Solche
JSP-Lösungen sind auch innerhalb von Intranets effektiv.
10
Natürlich könnte ein Versandhaus seinen digitalen Katalog im Prinzip auch
zum Download anbieten, so wie es ja auch gedruckte Kataloge an den Kundenstamm verschickt. Das hat aber, abgesehen von den Übertragungskosten, den
Nachteil, dass diese Kataloge nur durch ständige Updates aktuell gehalten werden. Wird dagegen ein Katalog auf dem Server gepflegt, greifen alle Clients
immer auf den aktuellen Katalog zu.
11
Es gibt aber viele weniger umfangreiche Funktionen, die sich sowohl auf der
Client-Seite als auch auf der Serverseite bereitstellen lassen. Auch bei Funktionen,
die sich ohne jeden Nachteil etwa mit Skripten beim Client realisieren lassen,
kann es trotzdem sinnvoll sein, sie über Webanwendungen auf dem Server zu
realisieren. Dadurch wird beispielsweise vermieden, dass eine solche Funktion
für den Webbesucher nicht verfügbar ist, wenn er in seinem Browser die Ausführung etwa von JavaScripts aufgrund von Sicherheitsbedenken unterbindet.
14
1.4.2
12
13
Das Designmodell Model-View-Controller
Umfangreichere Webanwendungen enthalten fast immer eine Formularkomponente, in die der Besucher Eingaben macht, die anschließend auf der Serverseite geprüft werden, bestimmte Verarbeitungsschritte einleiten – wie die
Abfrage einer Datenbank – und schließlich in einer von diesen Schritten
bestimmten Antwort des Servers an den Client enden.
Solche typischen Abläufe lassen sich gut in einem Designmodell gruppieren,
das mit der Abkürzung MVC für Model-View-Controller benannt wird. Das
Anwendungsgebiete und -modelle
39
Modell wurde schon in den spätern 80ern im Zusammenhang mit der Programmiersprache Smalltalk vorgestellt. Die Grundidee ist eine saubere Trennung von drei Aufgabenbereichen, die sich bei jeder Anwendung, die mit einer
Benutzerschnittstelle arbeitet, unterscheiden lassen. Jeder Bereich wird dabei
in einem Objekt zusammengefasst:
왘 Das Model-Objekt liefert das Datenmodell für die Vorgänge, um die es geht,
und die Regeln dafür, wie diese Daten verwendet werden sollen. Dieses Objekt
vereint die logische Seite der Anwendung in sich, wobei von der Frage, wie
Daten vom Benutzer eingegeben werden und wie die Ergebnisse der Datenverarbeitung präsentiert werden sollen, zunächst ganz abgesehen wird.
왘 Das View-Objekt ist für die visuelle Präsentation der Daten zuständig. Dazu
muss ihm bekannt sein, mit welchen Methoden die Daten des ModelObjekts ausgelesen werden und wie diese Daten durch das ControllerObjekt geändert werden können.
왘 Das Controller-Objekt ist für die Verarbeitung der vom Benutzer vorgenom-
menen Eingaben zuständig. Es sitzt gewissermaßen zwischen dem Viewund dem Model-Objekt. Wenn auf der Benutzerebene über ein Steuerelement z.B. ein angezeigter Wert verändert wird, sorgt das Controller-Objekt
dafür, dass diese Änderung an den Daten des Model-Objekts vorgenommen
wird. Umgekehrt werden innerhalb des Model-Objekts neu berechnete
Daten über das Controller-Objekt wieder an das View-Objekt zurückgegeben, sodass sich die angezeigten Daten entsprechend ändern.
Bei unternehmensweiten Anwendungen ist es in der Regel sinnvoll, sie als
Zusammenspiel von mehreren Komponenten zu realisieren, die sich dem
Modell entsprechend auf eine der Aufgaben konzentrieren.
Abbildung 1.5 MVC in der Übersicht
40
JavaServer Pages im Überblick
1
2
Durch eine klare Trennung der verschiedenen Rollen wird es möglich, eine Veränderung an der Benutzeroberfläche vorzunehmen, ohne dass sich an dem
Model-Objekt etwas ändern muss. Einem Model-Objekt können mehrere
View-Objekte zugeordnet werden, die beispielsweise die Dateneingabe über
unterschiedliche Instrumente abwickeln.
3
4
5
Umgekehrt bleibt die Präsentation der Daten durch das View-Objekt von Änderungen in den Berechnungsverfahren des Model-Objekts unberührt. Dagegen
sind die View- und Controller-Objekte in der Regel enger verzahnt. Zu jedem
View-Objekt muss es ein Controller-Objekt geben. Dieses Paar stellt die Benutzeroberfläche der Anwendung dar, also das, was auch »look and feel« genannt
wird.
6
7
8
Hilfreich ist zudem die Auslagerung von Funktionen, die in mehreren JSPs
benötigt werden, etwa Suchfunktionen oder Login-Verfahren, die in separaten
Komponenten eingeschlossen werden können.
9
Welche Komponenten einer Webanwendung jeweils eine der drei Rollen
innerhalb dieses Modells übernehmen, kann je nach den Anforderungen ganz
unterschiedlich sein. Der Entwicklung steht hier jedenfalls eine große Bandbreite von Lösungen offen, weil JSP 2.0 mit der Unterstützung von JavaBeans,
Tag-Bibliotheken und Tag-Dateien mehrere Methoden anbietet, Funktionen in
Komponenten zu kapseln. Außerdem besteht immer die Möglichkeit, JSPLösungen und originäre Servlets miteinander zu verknüpfen.
10
11
12
13
In unternehmensweiten Anwendungen wird es häufig sinnvoll sein, JSP in erster Linie für die View-Rolle, also für die Präsentation und Eingabe von Daten an
der Benutzeroberfläche zu verwenden, für die Model-Rolle mit JavaBeans oder
Enterprise JavaBeans zu arbeiten und als Controller Servlets zu nutzen. Dabei
kann die View-Rolle beispielsweise auch durch eine bestimmte Abfolge von
JSPs realisiert werden.
14
Da es in vielen Webanwendungen eine ganze Reihe von immer wiederkehrenden Aufgabenstellungen gibt, entwickelt sich hier ein Markt für Komponenten,
der nicht nur Sammlungen von benutzerdefinierten Aktionen anbietet, sondern Frameworks wie Struts, die gleich ein Grundgerüst liefern, das für den
konkreten Bedarf aufgefüllt werden kann. Wenigstens einen Blick darauf finden Sie in Abschnitt 5.6.
1.5
Von JSP 1.2 nach JSP 2
Ursprünglich sollte auf JSP 1.2 eine Spezifikation mit der Nummer 1.3 folgen,
doch im Laufe des Verfahrens entschied sich die verantwortliche JSR 152Expertengruppe, Teil von JCP (die Abkürzung steht für Java Community Pro-
Von JSP 1.2 nach JSP 2
41
cess), für die Nummer 2.0, um deutlich zu machen, dass die neue Version ganz
maßgebliche Veränderungen gegenüber den bisherigen Verfahren der Erstellung von dynamischen Webinhalten erlaubt. Wen die Arbeit der Gruppe interessiert, der findet über www.jcp.org Näheres.
Wie schon so oft in der Software-Industrie steht die neue Version unter der
Hauptforderung, es den Anwendern leichter machen zu sollen als bisher. In
diesem Fall insbesondere den Webdesignern, die die Java-Programmierung
nicht als ihre Sache betrachten. Inwieweit dies allerdings gelungen ist, muss
sich erst noch in der Praxis erweisen.
1.5.1
Plattform und Servlet-API
JSP 2.0 erweitert die bisherige Spezifikation, um die Funktionalität der Java 2Plattform in der Standard Edition 1.4 und in der Enterprise Edition 1.4 voll ausnutzen zu können. Außerdem wird das Servlet-API genutzt, das der ServletSpezifikation 2.4 entspricht. Diese Version ist eine konservative Erweiterung
der Version 2.3. Sie erlaubt die Verwendung von Filtern nun auch in Zusammenhang mit Request-Dispatchern. Die Unterstützung von HTTP/1.1 ist jetzt
vorgeschrieben. Für Deployment-Deskriptoren wurde ein XML-Schema definiert.
1.5.2
JSTL und andere Tag-Bibliotheken
Das Hauptmotiv für den Entwurf der JSP 2.0-Spezifikation war der Wunsch,
die Entwicklung von dynamischen Webseiten zu vereinfachen. Die Notwendigkeit für Webdesigner, sich mit dem Schreiben von Skripten in Java-Code zu
quälen, sollte weitgehend entfallen, auch wenn die Möglichkeit dazu weiter
unterstützt wird. Die entsprechende Funktionalität wird dazu in Tags verpackt,
die ihm von der Arbeit mit HTML oder XHTML vertraut sind. Die Innereien
von Java können dem Designer auf diese Weise verborgen bleiben.
Eine wesentliche Rolle spielt hier die im Rahmen des Jakarta-Projekts entstandene JavaServer Pages Standard Tag Library (JSTL), die inzwischen vom JCP
spezifiziert und als verbindliche Lösung für viele typische Standardaufgaben in
dynamischen Webseiten eingesetzt werden kann.
Gleichzeitig ist die Erweiterbarkeit von JSP durch eigene oder auf dem Markt
verfügbare zusätzliche Tag-Sammlungen weiter ausgebaut worden.
1.5.3
Expression Language
Die zunächst im Rahmen des JSTL-Projekts entwickelte Expression Language
(EL) wurde aus der neuen Version 1.1 der JSTL-Spezifikation ausgekoppelt, um
42
JavaServer Pages im Überblick
1
2
sie auch unabhängig von der Tag-Bibliothek verwenden zu können. EL wurde
nun direkt in die JSP 2.0-Spezifikation integriert, ein entsprechendes EL-API
wurde dem JSP-API hinzugefügt.
3
4
Die Sprache wurde für JSP 2.0 um die Unterstützung von Funktionen erweitert. EL ist in Anlehnung an JavaScript und XPath entstanden und dazu gedacht,
die bisher in Form von Skriptelementen verwendeten Ausdrücke zu ersetzen.
EL-Ausdrücke in der Form ${ausdruck} können jetzt auch direkt innerhalb des
Template-Textes einer JSP vorkommen. Besonders komfortabel ist, dass sich
Attributwerte in Aktionen – seien es Standardaktionen oder Aktionen aus
zusätzlichen Bibliotheken –, die erst bei der Ausführung der Seite bestimmt
werden, über solche Ausdrücke definieren lassen. Die Sprache erlaubt insbesondere auch einen einfachen Zugriff auf die Eigenschaften von JavaBeans.
1.5.4
5
6
7
8
9
Simple Tag-Handler
Zusätzlich zu dem bisher verwendeten Aufrufprotokoll für Tag-Handler, das auf
die Verwendung von Java-Code zugeschnitten ist, führt JSP 2.0 ein vereinfachtes Protokoll für Tag-Erweiterungen ein, das Simple Tag Extension genannt
wird.
10
11
Dieses Protokoll ist in der Erwartung entwickelt, dass in Zukunft bei der Gestaltung von dynamischen Webinhalten ganz auf Skriptelemente in JSPs verzichtet
werden kann. Dabei wird es den Autoren solcher Erweiterungen freigestellt,
diese auf der Basis von Java-Klassen oder auch direkt in JSP zu definieren.
Dafür wird das Konzept der JSP-Fragmente verwendet, die Teilfunktionen in
einer Form kapseln, die sie wiederverwendbar macht.
1.5.5
12
13
14
Tag-Dateien
Neben dem schon bekannten Erweiterungsmodell auf der Basis von Tag-Bibliotheken wird in JSP 2.0 deshalb parallel eine vereinfachte Form, eigene Tags in
die JSP einzubringen, eröffnet, die spezielle Tag-Dateien verwendet. Diese
bestehen ausschließlich aus JSP-Elementen, enthalten also keinen Java-Code,
sodass auch Designer, die keine Java-Kenntnisse mitbringen, eigene Tags für
wiederholt benötigte Funktionen definieren können.
1.5.6
JSP als XML-Dokument und XML-Views
Ein allgemeiner Zug der neuen Version ist die deutliche Ausrichtung an XML als
Basistechnologie. Die Autoren von JSP-Anwendungen werden dazu ermuntert,
JSPs direkt als vollwertige XML-Dokumente zu editieren, um die Vorteile von
Werkzeugen nutzen zu können, die XML unterstützen. Gleichzeitig wird intern
Von JSP 1.2 nach JSP 2
43
bei der Verarbeitung von JSPs mit einer automatisch generierten XML-Sicht
auch der JSPs gearbeitet, die in der älteren Standardsyntax geschrieben sind,
wenn Validatoren für die verwendeten Tag-Bibliotheken eingesetzt werden.
1.5.7
Neue Standardaktionen und dynamische Attribute
JSP 2.0 erweitert auch die Liste der Standardaktionen, insbesondere um die
Elemente <jsp:attribute> und <jsp:body>. Mit Hilfe dieser Elemente lassen
sich Werte im Rumpf einer Aktion definieren, anstatt sie im Start-Tag der
Aktion unterzubringen. Das ist besonders in Zusammenhang mit Attributen
von Bedeutung, deren Name erst während der Ausführung der Seite dynamisch
zugewiesen wird. Dynamische Attribute sind ebenfalls eine wichtige Erweiterung von JSP. Dafür wurde in dem Paket javax.servlet.jsp.tagext ein spezielles DynamicAttributes-Interface eingeführt.
1.6
Allgemeine Merkmale von JSP
JSP-Anwendungen sind Webanwendungen auf der Basis des HTTP-Protokolls.
Um eine solche Webanwendung auszuführen, ist eine wesentlich komplexere
Umgebung notwendig als bei einem Programm, das für einen lokalen Rechner
geschrieben ist. Bevor die syntaktischen Details der JSP-Programmierung zum
Thema werden, soll deshalb ein kurzer Überblick darüber gegeben werden,
was überhaupt beim Aufruf von JSP-Anwendungen geschieht.
1.6.1
Laufzeitumgebung für JSP
Wenn Autoren eine einfache Webseite in HTML oder XHTML veröffentlichen,
legen sie diese Seite auf einem Webserver ab. Wird von irgendeinem Browser
die Adresse dieser Seite eingegeben, liefert der Server als Antwort auf die
Anfrage die gewünschte Seite genau so an den Client aus, wie die Autoren sie
auf den Server gelegt haben.
Bei den JavaServer Pages ist auf der Seite des Servers mehr zu tun, als nur die
angeforderte Seite abzuliefern. Zunächst wird auch die JSP von den Autoren
auf dem Webserver abgelegt. Damit eine JSP ausgeführt werden kann, reichen
die Funktionen, die ein Webserver beim Aufruf von statischen HTML-Seiten
anbietet, aber nicht aus.
Es wird eine Laufzeitumgebung benötigt, die mit JSPs etwas anfangen kann.
Auf dem Server wird dazu ein JSP-Container benötigt, eine Servererweiterung
für den Umgang mit JSP. Dieser Container sorgt dafür, dass eine JSP in ein Servlet übersetzt wird, das dann wie ein originäres Servlet ausgeführt werden kann.
Der JSP-Container wird häufig selbst als ein spezielles Servlet implementiert,
44
JavaServer Pages im Überblick
1
2
das für die Ausführung von JSPs konfiguriert ist und innerhalb eines ServletContainers ausgeführt wird. In anderen Fällen werden ein Servlet-Container
und ein JSP-Container auch zu einem Paket kombiniert, das dann insgesamt als
Web-Container bezeichnet wird, so wie es auch die JSP 2.0-Spezifikation tut.
3
4
Die JSP-Technologie ist in diesem Sinne also als eine Erweiterung der ServletTechnologie zu verstehen, weshalb es zwischen Servlets und JSP-Lösungen
auch grundlegende Gemeinsamkeiten gibt, auch wenn der Quellcode eines
Servlets und der Text einer JSP ziemlich verschieden aussehen.
5
6
Ein solcher Servlet-Container kann in verschiedenen Formen realisiert werden. Er
kann Teil eines Webservers oder Teil eines Applikationsservers sein. Im ersten Fall
ist er entweder direkt in den Webserver integriert oder er wird durch eine Add-onKomponente eingebunden, wenn der Webserver selbst keine genuine Unterstützung für Servlets zur Verfügung stellt. Das ist z.B. bei Apache und bei IIS der Fall.
7
8
9
Ein Container kann aber auch, wie es beispielsweise für Tomcat gilt, als Standalone-Server betrieben werden, der neben normalen HTTP-Funktionen eine
Laufzeitumgebung für Servlets und JSPs zur Verfügung stellt. Der Server kann
ohne Probleme parallel zu anderen Webservern betrieben werden, solange mit
unterschiedlichen Parts gearbeitet wird.
10
11
12
In jedem Fall muss ein JSP-Container das HTTP-Protokoll unterstützen, wobei
die Versionen HTTP/1.0 und 1.1 verlangt werden. HTTPS kann hinzukommen.
13
1.6.2
Einbindung in J2EE
14
Wie die schon kurz angesprochene Servlet-Technologie sind auch die JavaServer Pages Teil der Software-Architektur Java 2 Enterprise Edition. Sun Microsystems hat die Java-Welt 1999 neu geordnet, und die gesamte Masse der dazugehörenden Klassenbibliotheken und Pakete in drei Editionen gruppiert:
왘 J2SE ist die Standard-Edition mit den Standard-APIs, die in erster Linie für
lokale Desktop-Anwendungen und für Applets, also Komponenten auf der
Client-Seite benötigt werden.
왘 J2EE fügt auf der Basis von J2SE zahlreiche Erweiterungen für die Serverseite
hinzu, um webbasierte, mehrschichtige unternehmensweite Anwendungen
auf der Basis des HTTP-Protokolls zu ermöglichen. Dazu gehört in erster Linie
die Einführung von Enterprise JavaBeans (EJB), einer Architekturspezifikation für Serverkomponenten, die mehrschichtige Anwendungen in Java vereinfachen, indem grundlegende technische Aspekte wie Transaktions- und
Zustandsverwaltung, Persistenz, Sicherheit, Nebenläufigkeit und Ressourcenverwaltung bereits durch den EJB-Container gewährleistet werden.
Allgemeine Merkmale von JSP
45
왘 J2ME, die Micro-Edition ist eine für den Einsatz auf mobilen Geräten wie
PDAs, Handys und Pager und in Embedded Systems wie Navigationssystemen abgespeckte Version, deren Kern ein spezielle Variante der Java Virtual
Machine, die Kilobyte Virtual Machine (KVM) ist.
Die J2EE-Spezifikation, die hier vor allem interessiert, definiert einen Standard, der sich aus einer Anzahl notwendiger APIs und allgemeiner Richtlinien
ergibt, die durch einen Applikationsserver unterstützt werden müssen, wenn
er die Einstufung »J2EE-kompatibel« erhalten will.
J2EE ist kein abgeschlossenes Produkt, sondern die Definition eines Rahmens
für Anwendungen auf der Basis eines Komponentenmodells im Sprachraum
von Java.
Wesentliches Merkmal von J2EE ist, dass die für konkrete Lösungen benötigten Komponenten durch beschreibende Konfigurationsdateien in vielfältiger
Weise angepasst werden können, ohne eine Zeile des Quellcodes ändern zu
müssen. Diese so genannten Deployment-Deskriptoren werden in Form von
XML-Dokumenten gepflegt, für die verbindliche XML-Schemas definiert sind.
Auch die Übertragung von Lösungen auf einen anderen J2EE-Server kann im
Prinzip ohne Anfassen des Quellcodes allein durch Anpassungen der Deskriptoren vorgenommen werden.
Als Laufzeitumgebung für J2EE-Anwendungen werden Container verwendet –
Servlet- und JSP-Container beispielsweise –, die den Lebenszyklus der darin
angesiedelten Webkomponenten steuern und ihnen standardisierte Dienste
zur Verfügung stellen. Die Arbeitsaufteilung zwischen Container und Komponente, die auch Kontrakt genannt wird, ist durch entsprechende Interfaces spezifiziert, etwa das Interface Servlet, das festlegt, in welcher Abfolge der Server
in eigener Regie und nicht durch den Anwendungscode die benötigten Methoden aufruft. Jede J2EE-Implementierung muss also den einzelnen Webanwendungen die gleichen Dienste zur Verfügung stellen. Dabei werden die in den
Konfigurationsdateien abgelegten Informationen automatisch umgesetzt.
Ergänzt wird die J2EE-Spezifikation durch die J2EE-Blueprints (Rezepte und
Designmuster für J2EE-Anwendungen), siehe java.sun.com/blueprints/
enterprise, ein J2EE-Server als Referenzimplementierung, der für nichtkommerzielle Tests genutzt werden kann (java.sun.com/j2ee/download.html)
und eine J2EE-Testsuite, mit der die Kompatibilität von neuen Anwendungen
überprüft werden kann. Unter java.sun.com/j2ee/compatibility.html werden alle Produkte gelistet, die diesen Test bestanden haben.
Da JSP vollständig in J2EE eingebunden ist, stehen zahlreiche Dienste der Plattform und die dazugehörigen APIs den Webanwendungen zur Verfügung. Die
46
JavaServer Pages im Überblick
1
2
folgende Tabelle gibt einen kurzen Überblick über wichtige Programmierschnittstellen, die zu J2EE 1.4 gehören bzw. bereits durch J2SE 1.4 zur Verfügung stehen:
3
4
API
Beschreibung
JDBC 3.0
Standardschnittstelle für den Zugriff auf Datenbanken mit
Hilfe von Datenbanktreibern
Servlet-API 2.4
Schnittstelle, die von allen Servlets implementiert und die
auch für die Ausführung von JavaServer Pages verwendet
wird
JSP 2.0
Schnittstelle, um JSP-Elemente in eine Webseite zu integrieren, die dynamische Inhalte ermöglicht
Enterprise JavaBeans (EJB)
2.1
Erweiterung der JavaBean-Komponententechnik für unternehmensweite, mehrschichtige Anwendungen
Java Naming and Directory
Interface (JNDI) 1.2
Gemeinsame Schnittstelle, über die Java-Programme J2EENamens- und Verzeichnisdienste nutzen können oder auch
LDAP oder NDS. Dadurch kann auf Objekte und Ressourcen
jeder Art mit Hilfe von logischen Namen zugegriffen werden.
Java Message Service (JMS)
1.1
Ein offener Standard, der den Zugriff auf Message Oriented
Middleware (MOM) in Java-Anwendungen erlaubt
Java Transaction API (JTA)
1.0
Schnittstelle zur Interaktion mit einem Transaktionsmanager
Java Connector Architecture
(JCA) 1.5
Schnittstelle für die Anbindung von Enterprise Information
Systems (EIS) an J2EE-Anwendungen
Java API for XML Processing
(JAXP) 1.2
Integriert XML-Parser in J2EE-Anwendungen und implementiert den XSLT-Standard
JavaMail 1.3
Schnittstelle für den E-Mail-Versand und Empfang
5
6
7
8
9
10
11
12
13
14
JavaBeans Activation Frame- Bestimmt den Typ von Daten aufgrund der MIME-Spezifikawork (JAF)
tion und kann entsprechende Viewer starten. Wird für JavaMail benötigt.
Java Authentication &
Stellt Verfahren zur Authentifizierung und zur ZugriffskontAuthorization Service (JAAS) rolle zur Verfügung. Basiert auf dem unter UNIX verwendeten Pluggable Authentication Modules.
JAX-RPC 1.1
Schnittstelle für die Nutzung von Webdiensten auf der Basis
von WSDL und SOAP
JAXP 1.2
Das Java API for XML Parsing macht J2EE unabhängig von
konkreten Parsern und XSLT-Prozessoren.
JAXR 1.0
Das Java API for XML Registries erlaubt den Zugriff auf
UDDI und andere Repositorien.
Allgemeine Merkmale von JSP
47
API
Beschreibung
SAAJ 1.2
Das SOAP with Attachments API for Java erlaubt die Bildung und Verarbeitung von Meldungen, die dem SOAP 1.1Standard entsprechen.
JSEE Connector Architecture 1.5
Erlaubt die Bildung von Ressourcen-Adaptern, um auf beliebige betriebliche Informationssysteme zugreifen zu können
Es soll allerdings nicht verschwiegen werden, dass der Umgang mit den oft tief
gestaffelten Kompontenhierarchien in der Java-Welt nicht zu unterschätzende
Anforderungen an die Entwicklung von Anwendungen stellt. Wettbewerbe mit
Gedächtniskünstlern sind nicht die erste Aufgabe von Website-Entwicklern.
Dokumentationen mit einfachen Navigationselementen, »intelligente« Editoren und Entwicklungsumgebungen sind deshalb dringende Erfordernisse für
eine effektive Arbeitsweise.
1.6.3
Aufbau einer JSP
Ohne hier schon auf Details der Standardsyntax einzugehen, lässt sich der Aufbau
einer JSP in den meisten Fällen als eine Mischung aus speziellen JSP-Elementen
und Nicht-JSP-Elementen beschreiben, wobei es sich meist um HTML-Code oder
einfachen Text handelt. Der Zweck einer JSP ist dabei immer, exakt zu beschreiben, wie eine Anfrage verarbeitet und eine Antwort erzeugt werden soll.
In der folgenden Abbildung wird an einem kleinen JSP-Beispiel die Anordnung
der unterschiedlichen Elemente durch Markierungen verdeutlicht. Es ist gleich
sichtbar, dass die verschiedenartigen Bestandteile der Seite nicht etwa in zwei
abgesonderte Bereiche eingeordnet werden müssen, sondern über die Seite
verstreut werden können. Der dynamische Inhalt einer Seite wird genau an der
Stelle in der Abfolge der Seitenelemente beschrieben, an der er in der Antwort,
die der Server generiert, erscheinen soll. Die Reihenfolge von statischen und
dynamischen Inhalten wird also durch das Layout der Seite bestimmt.
Abbildung 1.6 JSP mit Template-Daten und JSP-Elementen (grau markiert)
48
JavaServer Pages im Überblick
1
2
Diese JSP erzeugt folgende Ausgabe, wenn sie über den Browser aufgerufen
wird:
3
4
5
6
7
Abbildung 1.7 Ausgabe der Seite mit statischen und dynamischen Bestandteilen
8
In dem Beispiel werden neben dem HTML-Code eine page-Direktive und eine
Standardaktion verwendet, die auf eine JavaBean zugreift, also auf eine Komponente, die außerhalb der JSP definiert ist. Schließlich ist noch ein Ausdruck
der neuen Expression Language (EL) enthalten, der für die Ausgabe der Zeitangaben sorgt.
9
10
11
1.6.4 Übersetzungsphase
12
Was geschieht nun, wenn diese Seite, vorausgesetzt, sie ist auf einem Server
veröffentlicht, von einem Browser angefordert wird? Wird eine Anfrage für
eine JSP von einem Browser abgeschickt, nimmt der auf der Seite des Servers
aktive JSP- oder Web-Container – die JSP-Spezifikation verwendet diese beiden
Begriffe synonym – die Anfrage entgegen.
13
14
Wird die JSP zum ersten Mal aufgerufen, übersetzt der Container aus dem Text
der JSP zunächst den Java-Quellcode für ein entsprechendes Servlet und legt
ihn in einer .java-Datei ab. Anschließend kompiliert er daraus eine ServletKlasse und legt sie in einer .class-Datei ab. Dies geschieht automatisch. Übersetzung und Kompilierung zusammen werden als Übersetzungsphase
bezeichnet. In dieser Phase können Fehler entdeckt werden, die aber erst angezeigt werden, wenn versucht wird, die JSP auszuführen.
Dabei wird für alle JSP-Elemente der entsprechende Java-Code übernommen,
um durch die Verarbeitung dieses Codes die dynamischen Bestandteile der
Seite zu erzeugen. Dagegen werden die Bestandteile, die keine JSP-Elemente
sind, in die schon angesprochenen Java-Ausgabeanweisungen übersetzt, mit
denen die entsprechenden statischen Elemente in der Antwort des Servers auf
die eingegangene Anfrage fixiert werden.
Allgemeine Merkmale von JSP
49
Abbildung 1.8 Übersicht über die Verarbeitung einer JSP-Anfrage
1.6.5
Die JSP-Implementierungsklasse
Die aus der JSP generierte Servlet-Klasse wird JSP page implementation class
genannt. Der genaue Name der erzeugten Klasse ist von der Implementierung
abhängig. Das JSP-Implementierungsobjekt ist dabei Teil eines Pakets, dessen
Name ebenfalls von der gewählten Implementierung abhängig ist. (Stattdessen
kann für eine Seite auch eine Oberklasse angegeben werden, von der die Klasse
abzuleiten ist, und zwar durch ein spezielles extends-Attribut der page-Direktive, was in Abschnitt 3.3 beschrieben wird. Allerdings schränkt dieses Verfahren die Entscheidungsmöglichkeiten des JSP-Containers ein und sollte normalerweise gemieden werden. JSP 2.0 erlaubt es übrigens nicht, mit unbenannten
Paketen zu arbeiten, was bei der Übernahme von älteren Anwendungen, in
denen so verfahren wurde, zu Fehlern führen kann.
Die JSP-Klasse implementiert im Kern das Interface javax.servlet.Servlet,
das die grundlegenden Methoden enthält, die von Servlets beherrscht werden
müssen. Anfragen werden deshalb genau so an diese Klasse zur Ausführung
übergeben, wie es die Servlet 2.4-Spezifikation festlegt.
50
JavaServer Pages im Überblick
1
2
Eine JSP-Implementierungsklasse kann von bestimmten Support-Klassen
abhängig sein. Ist die Klasse in eine WAR-Datei verpackt, darauf wird in
Abschnitt 4.2 noch im Detail eingegangen, muss jede dieser Klassen eingefügt
werden, damit das Paket zwischen allen JSP-Containern portabel bleibt.
3
4
Da die Frage/Antwort-Kommunikation zwischen Client und Server nur über
ein von beiden Seiten eingehaltenes Protokoll möglich ist, muss der JSP-Container außerdem sicherstellen, dass ein solches Protokoll verwendet wird. In
der Regel ist das HTTP, und deshalb muss die Implementierungsklasse dafür
auch das Interface HttpJspPage implementieren, welches eine Erweiterung
des Interfaces JspPage ist.
5
6
7
Wird eine Seite, die schon kompiliert ist, später verändert, ist es Aufgabe des
Containers, die Seite beim nächsten Aufruf neu zu kompilieren. Verwendet
eine Seite Komponenten wie JavaBeans oder inkludierte Seiten, findet allerdings nicht unter allen Umständen eine Neukompilierung statt. Mehr dazu in
Abschnitt 3.14.
8
9
10
Die Übersetzungsphase kann auch vom Aufruf der JSP getrennt werden. Dazu
kann ein spezieller jsp_precompile-Parameter beim Aufruf der Seite verwendet werden, der den Container veranlasst, die Seite zu übersetzen und zu kompilieren, ohne die darin enthaltene Anfrage auszuführen.
11
12
http://localhost:8080/einstiegjsp/Kapitel1/zeitAnsage.jsp?jsp_
precompile=true
13
Diese Vorkompilierung hat den Vorteil, dass die durch die notwendige Übersetzung bedingte Verzögerung der Serverantwort beim ersten Aufruf einer JSP
vermieden werden kann. Mehr dazu in Abschnitt 4.5.
14
1.6.6 Ausführungsphase
Ist durch die Übersetzung und Kompilierung ein Servlet erzeugt, das die JSP
repräsentiert, kann der JSP-Container alle Anfragen an das Implementierungsobjekt richten, das er als Instanz der JSP-Implementierungsklasse bildet. Dazu
ruft der Container das Servlet auf. Es mag so lange im Speicher bleiben, bis der
Server heruntergefahren wird, sodass eine Serie von Anfragen verarbeitet werden kann, ohne einen neuen Prozess starten zu müssen.
Die Ausführung des Servers erzeugt schließlich auf der Basis der Daten und
Anweisungen, die in der Anfrage enthalten sind, die Ausgabe, die als Antwort
an den anfragenden Client zurückgeschickt wird. In diesem Prozess werden
häufig noch andere Objekte erzeugt oder benutzt. Die JSP kann außerdem
noch festlegen, wie auf bestimmte Ereignisse reagiert werden soll. JSP 2.0
Allgemeine Merkmale von JSP
51
kennt allerdings nur die Ereignisse init und destroy, also den Moment, in
dem ein Servlet initialisiert wird, und den Moment, in dem das Implementierungsobjekt wieder zerstört wird.
Für jede eingehende Anfrage findet der JSP-Container jeweils die passende
Instanz der JSP-Implementierungsklasse und übergibt auf der Basis des ServletProtokolls die zugehörigen Anfragen. Die Servlet-Klasse definiert eine Art Kontrakt zwischen dem JSP-Container und der JSP-Implementierungsklasse.
Da JSPs in der Regel das HTTP-Protokoll verwenden, wird dieser Kontrakt
durch die HttpServlet-Klasse beschrieben. Der JSP-Container macht dabei
automatisch eine Reihe von serverseitigen Objekten verfügbar, die implizite
Objekte genannt werden. Auf solche Objekte kann während der Ausführung
der Seite über Skriptlets und Skriptausdrücke zugegriffen werden, etwa um
Daten aus den Anfrage-Headern auszulesen oder um Statusinformationen abzufragen. Auch Ausdrücke der Expression Language haben Zugriff auf implizite
Objekte. Die JSP-Spezifikation ist im Prinzip auch für andere Protokolle offen.
Verarbeitung einer JSP durch den JSP-Container
Das Interface javax.servlet.Servlet stellt die Mittel bereit, damit ein Servlet ausgeführt werden kann. Es stellt die Methoden zur Verfügung, um Eingangswerte für ein Servlet zu setzen, sorgt für die Bedienung der Anfragen und
ermöglicht es, das Servlet aus dem Speicher zu entfernen, wenn es seine
Dienstleistung abgeschlossen hat.
Wie dies genau geschieht, ist normalerweise Sache der jeweiligen JSP-Container-Implementierung, es sei denn, JSP-Autoren legen über das extends-Attribut der page-Direktive eine andere Oberklasse fest. Diese muss dann gewährleisten, dass das Nötige geschieht.
Die Methodenabfolge regelt den Lebenszyklus
Stellt der Container eine Anfrage durch einen Client fest, wird das entsprechende Servlet, wenn es noch nicht geladen ist, durch einen speziellen Klassenlader in den Speicher geholt. Für jede Anfrage wird normalerweise ein eigener
Thread verwendet, sodass auch mehrere Anfragen von einer einzigen Instanz
der Implementierungsklasse parallel bearbeitet werden können.
Der Container ruft dabei die benötigten Methoden des Servlet-Objekts in einer
bestimmten Reihenfolge automatisch auf. Diese Abfolge wird gern Lebenszyklus genannt. Für Servlets, die JSP-Implementierungsklassen sind, werden dabei
von Servlet abgeleitete Interfaces verwendet.
52
JavaServer Pages im Überblick
1
2
Über das Interface JspPage stehen die Methoden jspInit() und jspDestroy()
zur Verfügung, die der Autor einer JSP überschreiben kann. Über das Interface
HttpJspPage, die JspPage erweitert, kommt die jspService()-Methode hinzu,
um die Kommunikation zwischen Client und Server zu steuern. Diese Methode
wird durch den JSP-Container automatisch definiert, und zwar aufgrund des
Inhalts der JSP. Der JSP-Autor kann diese Methode nicht überschreiben.
3
4
5
6
7
8
9
10
11
12
Abbildung 1.9 Abfolge der Methodenaufrufe
13
Da bei jeder Anfrage an eine bestimmte Instanz innerhalb des dafür verwendeten Threads dieselben Methoden verwendet werden, muss bei der Entwicklung einer JSP folglich darauf geachtet werden, dass sich der auszuführende
Code immer in derselben Weise verhält, egal ob nur eine Anfrage stattfindet
oder gleich mehrere. Der Code muss also Thread-sicher sein. Welche konkreten
Anforderung sich daraus ergeben, wird in Abschnitt 3.12 erläutert.
14
Initialisierung
Die erste Methode jspInit() wird beim Laden des Servlets genau einmal aufgerufen, und zwar noch vor der Bearbeitung der ersten Anfrage. Bei weiteren
Anfragen wird sie also nicht mehr aufgerufen. Sie tut in der Vorgabe zunächst
gar nichts. Durch Überschreiben dieser Methode hat der JSP-Autor aber die
Möglichkeit, bestimmte Initialisierungen vorzunehmen, etwa das Laden und
Erzeugen von Objekten, die für jede Anfrage benötigt werden. Auch lassen sich
hier Datenbankverbindungen aufbauen, die von mehreren Anfragen gemeinsam genutzt werden sollen. Dazu können entsprechende Parameter in den Deskriptor-Dateien der jeweiligen Webanwendung abgelegt werden. Die Parame-
Allgemeine Merkmale von JSP
53
ter lassen sich an dieser Stelle einlesen und wenn nötig in Instanzvariablen
speichern, die während der gesamten Ausführungszeit zur Verfügung stehen.
Ist die jspInit()-Methode einmal aufgerufen, sollte die JSP-Implementierung
sicherstellen, dass anschließend mit der Methode getServletConfig()auf die
Initialisierungs- und Startparameter des Servlets zugegriffen werden kann.
Seitenverarbeitung
Die eigentliche Arbeit, nämlich aus der JSP-Anfrage eine entsprechende Antwortseite zu erzeugen, wird über die _jspService()-Methode erledigt. Diese
Methode wird für jede Anfrage aufgerufen und auf der Basis der Inhalte der JSP
automatisch generiert. Die Methode kann, wie schon gesagt, nicht durch
Skriptelemente in der JSP überschrieben werden.
Um die Kommunikation nach dem Muster Anfrage/Antwort zu steuern, werden entsprechende Parameter verwendet. Der formale Typ der Anfrageparameter – in der JSP 2.0-Spezifikation als <ServletRequestSubtype> bezeichnet –
ist durch ein Interface bestimmt, das javax.servlet.ServletRequest erweitert. Entsprechend gilt für die Antwortparameter – <ServletResponseSubtype> - ein Interface, das javax.servlet.ServletResponse erweitert.
Diese Interfaces werden durch die Interfaces javax.servlet.http.HttpServletRequest und javax.servlet.http.HttpServletResponse noch um
Methoden bereichert, die für das HTTP-Protokoll spezifisch sind. Sie können
vor allem protokollspezifische Daten liefern. Das betrifft z.B. das Abfragen der
Request-Header mit getHeader() oder von Cookies mit getCookies(). Während HttpServletRequest der Anwendung das Parsen und Dekodieren der
HTTP-Anfrage abnimmt, erlaubt HttpServletResponse einen einfachen
Zusammenbau der HTTP-Antwort, das Puffern der Ausgabe und das Setzen von
Headern und Cookies. Für die Ausgabe werden Stream-Klassen für Textdaten
und für binäre Daten zur Verfügung gestellt.
Freigabe der Ressourcen
Das Servlet kann so lange Anfragen verarbeiten, bis es explizit vom Container
aus dem Speicher entfernt wird. Dies geschieht, wenn dieser ein shutdown-Signal erhält. Vor dem Entladen ruft der Container aber noch die Methode jspDestroy() auf. Die Methode jspDestroy() kann überschrieben werden, um
Dinge zu veranlassen, die geschehen sollen, bevor die Servlet-Instanz dem Garbage Collector überlassen wird, etwa Einträge in Log-Dateien. Häufig geht es
auch um die Freigabe von Ressourcen oder das Schließen von offenen Verbindungen zu Datenbanken. Außerdem können Statusinformationen aus dem
54
JavaServer Pages im Überblick
1
2
ServletContext gespeichert werden, die bis zum nächsten Aufruf des Servlets
erhalten bleiben sollen.
3
Die Methode wird in jedem Fall erst ausgeführt, wenn alle Threads, die _jspservice()-Methoden ausführen, beendet sind, also spätestens, wenn der Server heruntergefahren wird.
4
5
Während die jspInit()-Methode, falls der JSP-Autor sie überschreibt, in
jedem Fall zum Zuge kommt, ist das bei der jspDestroy()-Methode nicht so
sicher. Es kann vorkommen, dass der Server crashed und es nicht mehr zur
Ausführung der Methode kommt.
6
1.6.7
8
7
Quellcode des Beispiels
Der Quellcode des Servlets, das der JSP-Container aus der kleinen JSP erzeugt,
zeigt die Umsetzung des Inhalts der JSP in den Java-Code einer Servlet-Klasse.
Die Datei wird unter Tomcat zusammen mit der kompilierten Klasse in einem
Unterverzeichnis von $CATILINA/work abgelegt.
9
10
Der Name der Java-Datei übernimmt dabei den Dateinamen der JSP-Datei und
erweitert ihn um das Suffix _jsp, aus zeitAnsage.jsp wird also zeitAnsage_
jsp.java und zeitAnsage_jsp.class.
11
12
package org.apache.jsp.Kapitel1;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;
public final class zeitAnsage_jsp
extends org.apache.jasper.runtime.HttpJspBase
implements org.apache.jasper.runtime.JspSourceDependent {
private static java.util.Vector _jspx_dependants;
public java.util.List getDependants() {
return _jspx_dependants;
}
public void _jspService(HttpServletRequest request,
HttpServletResponse response)
throws java.io.IOException, ServletException {
JspFactory _jspxFactory = null;
PageContext pageContext = null;
HttpSession session = null;
ServletContext application = null;
ServletConfig config = null;
JspWriter out = null;
Allgemeine Merkmale von JSP
13
14
55
Object page = this;
JspWriter _jspx_out = null;
try {
_jspxFactory = JspFactory.getDefaultFactory();
response.setContentType("text/html");
pageContext =
_jspxFactory.getPageContext(this, request, response,
null, true, 8192, true);
application = pageContext.getServletContext();
config = pageContext.getServletConfig();
session = pageContext.getSession();
out = pageContext.getOut();
_jspx_out = out;
out.write('\r');
out.write('\n');
out.write("<html>\r\n\t");
out.write("<head>\r\n\t\t");
out.write("<title>Say the time");
out.write("</title>\r\n\t");
out.write("</head>\r\n\t");
out.write("<body>\r\n\t\t");
java.util.GregorianCalendar now = null;
synchronized (pageContext) {
now =
(java.util.GregorianCalendar)
pageContext.getAttribute("now",
PageContext.PAGE_SCOPE);
if (now == null){
try {
now = (java.util.GregorianCalendar)
java.beans.Beans.instantiate(this.getClass().getClassLoader(),
"java.util.GregorianCalendar");
} catch (ClassNotFoundException exc) {
throw
new InstantiationException(exc.getMessage());
} catch (Exception exc) {
throw new ServletException("Cannot create bean
of class " + "java.util.GregorianCalendar",
exc);
56
JavaServer Pages im Überblick
1
2
}
pageContext.setAttribute("now",
now, PageContext.PAGE_SCOPE);
3
4
}
}
out.write("\r\n\t\t");
out.write("<p>The time is: ");
out.write("</p>\r\n\t\t");
out.write((java.lang.String) org.apache.jasper.runtime.PageContextImpl.proprietaryEvaluate("${now.time}",
java.lang.String.class,
(PageContext)pageContext, null, false));
out.write('\r');
out.write('\n');
out.write(' ');
out.write("</body>\r\n");
out.write("</html> \t\r\n \t\r\n \r\n ");
} catch (Throwable t) {
if (!(t instanceof SkipPageException)){
out = _jspx_out;
if (out != null && out.getBufferSize() != 0)
out.clearBuffer();
if (pageContext != null)
pageContext.handlePageException(t);
}
} finally {
if (_jspxFactory != null)
_jspxFactory.releasePageContext(pageContext);
}
}
}
5
6
7
8
9
10
11
12
13
14
Die Implementierungsklasse des Beispiels wird in der Tomcat-Umgebung als
Erweiterung der Klasse HttpJspBase erzeugt, die zu dem Paket org.apache.jasper.runtime gehört. Diese Klasse wird für alle Servlets verwendet, die
aus einer JSP generiert werden. Sie implementiert die schon angesprochenen
Interfaces javax.servlet.jsp.HttpJspPage, javax.servlet.jsp.JspPage,
javax.servlet. Servlet, javax.servlet.ServletConfig und zusätzlich
java.io.Serializable.
Allgemeine Merkmale von JSP
57
Da in der JSP keine Überschreibungen für die Methoden jspinit() und jspdestroy() vorhanden sind, wird nur die Methode _jspService() verwendet,
um die Antwort auf die Anfrage zu erzeugen.
Zunächst werden eine Reihe von Objekten initialisiert, die die JSP als implizite
Objekte für Skriptelemente anbietet. Dann wird die getDefaultFactory()Methode verwendet, um Instanzen für die Interfaces und Klassen zu erzeugen,
die für die Implementierung des JSP-Objekts benötigt werden. Die in der ersten Zeile der JSP enthaltene page-Direktive, die hier den MIME-Typ der Seite
bestimmt, legt in diesem Fall das Argument der setContenType()-Methode
des response-Objekts fest.
Ist das Objekt pageContext gebildet, werden Methoden dieses Objekts
benutzt, um andere Objekte zu erzeugen:
application = pageContext.getServletContext();
config = pageContext.getServletConfig();
session = pageContext.getSession();
out = pageContext.getOut();
Die Bedeutung dieser Objekte wird in Abschnitt 3.6 näher erläutert.
Anschließend werden die in der JSP vorkommenden Template-Elemente und
die verschiedenen JSP-Elemente in der dort gegebenen Reihenfolge verwertet,
um den Datenstrom zusammenzufügen, der die Antwort des Servers auf die
Anfrage erzeugt. Mit Hilfe der getOut()-Methode des PageContext-Objekts
wird der aktuelle Wert des impliziten out-Objekts festgestellt, das eine Instanz
der JspWriter-Klasse ist, mit der die Ausgaben an den Browser erzeugt werden. Der Jspwriter arbeitet ähnlich wie ein PrintWriter, kann aber Daten
auch zwischenspeichern.
Um aus den vorhandenen Anfrageobjekten die entsprechenden Antwortobjekte zu gewinnen, werden bestimmte Umwandlungen vorgenommen.
Für jedes Template-Element wird eine Java-Anweisung, wie z.B.
out.write("<html>\r\n\t");
verwendet, um es in die Antwortseite einzubauen.
Die in der Seite vorkommenden Standardaktionen, die hier die Verwendung
einer JavaBean betreffen, werden durch den entsprechenden Java-Code ersetzt.
Aus dem EL-Ausdruck
${now.time}
wird beispielsweise der Java-Code:
58
JavaServer Pages im Überblick
1
2
out.write((java.lang.String) org.apache.jasper.runtime.PageContextImpl.proprietaryEvaluate("${now.time}",
java.lang.String.class,
(PageContext)pageContext, null, false));
3
4
Der Vergleich zwischen dem Code der JSP und dem Code des daraus generierten Servlets dürfte die Einschätzung bestätigen, dass es für die Entwicklung von
Webanwendungen durchaus vorteilhaft ist, wo möglich von der Kodierung von
Servlets zum Editieren von JSPs überzuwechseln.
5
6
Da die Übersetzung der JSP in den Java-Code des entsprechenden Servlets
automatisch abläuft, muss sich der JSP-Autor um das Ergebnis in der Regel
auch nicht unbedingt kümmern. Zum Lernen oder bei der Suche nach Fehlern,
die bei der Ausführung der Seite gemeldet werden, ist es aber häufig sinnvoll,
sich den generierten Code anzusehen, um dort Hinweise auf die Ursachen des
Fehlers zu finden.
7
Werden andere JSP-Implementierungen verwendet, kann es zu leichten Abweichungen in der Übersetzung kommen. Bei anderen Containern muss eventuell
die Option zum Speichern des Quellcodes erst eingeschaltet werden.
10
8
9
11
12
13
14
Allgemeine Merkmale von JSP
59
Index
A
B
<auth-constraint> 404
<auth-method> 404
Accept 24
Accept-Charset 24
Accept-Charset-Header 320
Accept-Encoding 24
Accept-Language 24
Accept-Language-Header 316, 320
Accept-Ranges 28
Achsenbezeichner 218
Active Server Pages 35
addCookie() 293
Aktion 557
benutzerdefiniert 557
Standard 557
Aktionen 90
<jsp:attribute> 180
<jsp:body> 182
<jsp:doBody> 185
<jsp:element> 178
<jsp:fallback> 178
<jsp:forward> 169
<jsp:getProperty> 196
<jsp:include> 162
<jsp:invoke> 183
<jsp:param> 172
<jsp:params> 178
<jsp:plugin> 173
<jsp:setProperty> 197
<jsp:text> 185
<jsp:useBean> 190
ancestor 219
Anfrage 21, 557
Parameter 25
Antwort 21
Antwort-Header 26
Apache 557
Apache Jakarta Project 64
API 557
Applet 176
application 140, 144, 290, 491
applicationScope 152, 492
Applikationsserver 557
at-end scoped variables 202
Attribut 557
Attribute 91
attribute-Direktive 465
Attributwerte 162
Ausdruck 131, 557
Ausdrücke 115
Authentifizierung 401
autoFlush 147
Autorisierung 401
<body-content> 420
<button> 263
BodyTag 432
BodyTag-Interface 427
BodyTagSupport 433
BodyTagSupport-Klasse 428
Browser. 21
Bytecode 557
C
<c:catch> 209, 511
<c:choose> 210, 515
<c:forEach> 211, 358, 516
<c:forTokens> 212, 517
<c:if> 210, 514
<c:import> 109, 213, 518
<c:otherwise> 210, 516
<c:out> 206, 358, 511
<c:param> 213, 521
<c:redirect> 213, 520
<c:remove> 206, 513
<c:set> 207, 291, 512
<c:url> 301, 519
<c:when> 210, 515
<Connector> 73
<Context> 75, 76
<context-param> 144, 394
CallableStatement 368
Cascading Stylesheets 558
CATALINA_HOME 68
CGI 29, 30, 558
CGI-Skript 558
child 219
Class.forName() 349
CLASSPATH 424
Client 21
Common Gateway Interface 29
config 140, 148, 491
conf-Verzeichnis 350
Connection 24
Connection Pooling 384
Container-Element 558
Content-Length 28
Content-Type 28
contentType 314, 485
Controller 40
Cookie 558
getCookies() 295
setMaxAge() 295
cookie 152, 492
Cookie-Header 293
Cookies 292
CREATE TABLE 329
Index
569
createStatement() 341, 364
CSS 558
D
<DefaultContext> 352
<distributable> 394
DatabaseMetaData 380, 381
DataSource 347
Datenquellen 347
DDL 328
defaultHost 73
Deklaration 487, 558
Deklarationen 115, 116
deleteRow() 373
Deployment Descriptor 352
descendant 219
DHTML 35, 559
Direktive 483, 558
include 105, 108
page 95, 483
page autoFlush 98
page buffer 98
page charset 105
page contentType 103
page errorPage 100
page extends 96
page import 97
page info 99
page isELIgnored 105
page isErrorPage 100
page isThreadSafe 99
page pageEncoding 105
page session 97
taglib 110
taglib prefix 112
taglib tagdir 110
taglib uri 110
Direktiven 90, 95
dirty read 379
distributed container 558
DML 328
doAfterBody() 431, 433
doEndTag() 428, 430
doInitBody() 432
Dokumenttyp-Definition 559
doStartTag() 423, 429
doTag() 428, 438, 439
Dynamic HTML 559
Dynamisches Attribut 559
E
<el-ignored> 407
<embed> 178
<Engine> 73
<env-entry> 408
<error-page> 101, 400
ECMA 560
ECMAScript 149, 493
570
Index
einfache Tag-Handler 438
EJB 47, 559
EL 42, 149, 491
API 150
deaktivieren 159
Delimiter 151
Empty Operator 494
empty-Operator 155
fn:contains 158, 547
fn:containsIgnoreCase 158, 547
fn:endsWith 158, 548
fn:escapeXml 158, 548
fn:indexOf 158, 549
fn:join 158, 549
fn:length 158, 550
fn:replace 158, 550
fn:split 158, 551
fn:startsWith 158, 551
fn:substring 158, 552
fn:substringAfter 158, 552
fn:substringBefore 159, 553
fn:toLowerCase 159, 554
fn:toUpperCase 159, 554
fn:trim 159, 554
Funktionen 157, 453, 495
Implizite Objekte 152, 492
in Attributen 151
JSTL-Funktionen 158
Literale 492
Operatoren 155, 493
Syntax 154, 492
Template-Text 149
Typumwandlung 160
Zugriff auf JavaBeans 149
EL-API 43
EL-Ausdruck 91, 149, 559
Element 559
Elemente 91
ELExection 160
ELParseException 160
encodeRedirectURL() 300
encodeURL() 300
End-Tag 90
Enterprise JavaBeans 559
Entität 560
Entitätsreferenz 560
Entity 560
errorPage 387
exception 101, 140, 148, 491
execute() 364
executeBatch() 364
Expression 150
Expression Language 42, 491
ExpressionEvaluator 150
F
<filter> 312, 397
<filter-mapping> 310, 398
<fmt:bundle> 232, 322, 543
<fmt:formatDate> 228, 539
<fmt:formatNumber> 228, 535
<fmt:message> 232, 323, 545
<fmt:param> 232, 323, 546
<fmt:parseDate> 228, 540
<fmt:parseNumber> 228, 537
<fmt:requestEncoding> 232, 546
<fmt:setBundle> 232, 323, 544
<fmt:setLocale> 232, 322, 544
<fmt:setTimeZone> 228, 542
<fmt:timeZone> 228, 542
<form> 254
action 259
method 259
<form-login-config> 404
Fehlermeldungen 386
Fehlerseite 101, 400
Filter 309, 397
FilterChain 310
FilterConfig 310
Filter-Kette 309
Filterkette 398
findAncestorWithClass() 438
findAttribute() 143
findColumn() 374
flush() 147
following 219
Formular 560
Formularauswertung 264
Formulare 254, 266
versteckte Felder 301
Fragmentbezeichner 560
Framework 560
FunctionMapper 150
G
Geltungsbereich 138, 289
application 139
page 138
request 138
session 139
GenericServlet 32, 286
getAttribute() 143, 290
getAttributeNames() 144, 290
getBeanInfo() 273
getContext() 94
getEnclosingWriter() 435
getErrorData() 102
getInitParameter() 148
getJspBody() 438
getLocales() 320
getOut() 58
getPageContext() 143
getParameter() 264
getRequest() 143
getResponse() 143
getResultSet() 365
getServletConfig() 54
getServletContext() 148, 310
getSession() 304
getString() 347
getUpdateCount() 365
getVariableResolver() 151
getWriter() 146
H
<Host> 73
header 152, 492
headerValues 152, 492
Host 24
HTML 35, 561
Formulare 133
htmlf 108
HTTP 20, 560
GET-Methode 23
Header 22, 23
POST-Methode 23
request-line 23
Ressourcen 23
Statuscodes 27
status-line 23
verbindungsloses Protokoll 21
zustandsloses Protokoll 22
HTTP/1.0 20
HTTP/1.1 20, 315
HTTP-Authentifizierung 404
HTTP-Port 21
HTTP-Protokoll 20, 297
HTTPServlet 32
HttpServlet 286
HttpServletRequest 293
HttpServletResponse 293
HttpSession 302
Objekte anbinden 304
HttpSessionBindingListener 305
HTTP-Statuscode 102
I
I18N 316
<include-prelude> 109
<include-coda> 109, 408
<include-prelude> 408
<init-param> 394
<input> 262
<is-xml> 407
IANA 314
IETF 561
IETF) 20
IIS) 31
Implizites Objekt 139, 490, 561
Include-Direktive 485
Inhaltsmodell 561
initParam 152, 492
insertRow(), 373
Instanzvariable 117
Index
571
Interface 561
Introspektion 272
invalidate() 306
invoke() 184, 439
ISAPI 31
isELIgnored 464, 485
isErrorPage 387
ISO/IEC 10646 313
ISO-639 317
ISO-8859 105, 313, 314
isUserInRole() 403
IterationTag 431
IterationTag-Interface 427
J
J2EE 45, 561
J2EE 1.4 47
j2ee_1_4.xsd 392
J2EE-Blueprints 46
J2EE-Spezifikation 46
J2ME 46, 561
J2SE 45, 63
_jspService() 119
<jsp:attribute> 44, 245, 507
<jsp:body> 44, 508
<jsp:declaration> 116, 247
<jsp:directive.attribute> 247
<jsp:directive.tag> 247
<jsp:directive.variable> 247
<jsp:doBody> 462, 509
<jsp:element> 245, 506
<jsp:expression> 131
<jsp:fallback> 176, 503
<jsp:forward> 398, 497
<jsp:getProperty> 504
<jsp:include> 498
<jsp:invoke> 462
<jsp:output> 245, 510
<jsp:param> 499
<jsp:params> 502
<jsp:plugin> 500
<jsp:root> 241, 460, 496
<jsp:setProperty> 505
<jsp:text> 244, 497
<jsp:useBean> 138, 503
<jsp-config> 109, 405
<jsp-file> 395
<jsp-property-group> 405, 407
JAAS 47, 562
JAF 47
Jakarta-Projekt 562
jar 412
JAR-Archiv 562
Java 562
Java Community Process 42, 562
Java RMI 562
Java Server Faces, 417
Java Server Pages 36, 562
572
Index
java.lang.reflect 273
java.sql 333
java.util.locale 317
JAVA_HOME 63
JavaBean 186
JavaBeans 91, 271, 562
Designmuster 274
kompilieren 284
Konstruktor 275
package 284
Plazierung 284
Serialisierung 275
Zugriffsmethoden 273
javac 63
Java-Code 115
Javadoc 422
JavaMail 47, 562
JavaScript 562
JavaServer Pages Standard Tag Library 42
javax.servlet.Filter 309
javax.servlet.jsp.tagext 427
javax.servlet.Servlet 50, 286
javax.sql 333, 335
JAX 563
JAXP 47
JAXR 47
JAX-RPC 47
JCA 47, 563
JCP 41, 203, 562
JDBC 47, 328, 330, 563
close() 377
commit() 378
DataSource 338
Datenübernahme 374
DriverManager 338
executeQuery() 341
executeUpdate() 341
getConnection() 339
Isolierungsgrade 379
rollback() 378
setAutoCommit() 379
statement 341
Typkonvertierung 376
URL-Syntax 340
JDBC 3.0 337
JDBC 3.0 Spezifikation 335
JDBC-API 330
JDBC-ODBC-Brücke 332
JDBC-Treiber 330
JDNI-Pfad 409
JMS 47
JNDI 47, 348, 408, 563
java:comp/env 408
Ressourcenfabrik 350
JNDI API 350
JSP 36, 38, 562
Aktionen 161
Anwendungsgebiete 39
Ausführungsphase 51
Implementierungsklasse 50, 57
Initialisierung 53
Komponenten 105
Laufzeitumgebung 44
Lebenszyklus 52
relative Pfade, 94
Servlet-Klasse 55
Standardsyntax 87
Syntax 48
Tools 83
Übersetzungsphase 49
Verzeichnisstruktur 78
XML-Ansicht 249
XML-Syntax 87
JSP 1.2 41
JSP 2.0 42, 392
JSP 2.0-Spezifikation 45
JSP Implementierungsklasse 563
jsp_2_0.xsd. 392
JSP-API 43
jsp-api.jar 424
JSP-Container 44, 183, 563
JspContext 151, 431
JSP-Datei 563
jspDestroy() 53, 54, 119
JSP-Dokument 232, 314, 563
Template-Text 243
Wurzelelement 241
xmlns-Attribut 242
JSP-Dokumente 43, 241
JSP-Element 138
JSP-Elemente 88
jspf 108
JSP-Fragment 183, 439, 563
JSP-Fragmente 183
jspInit() 53, 119
JSP-Konfiguration 405
JspPage 53
JSP-Segment 563
jspService() 53
JSP-Spezifikation 417
JspWriter 58
JSR 563
JSR 152 41
JSTL 42, 201, 357, 510, 566
Format-Tags 228
SQL-Tags 227
JSTL 1.0 203
JSTL 1.1 203
JTA 47
JVM 34, 564
Konstruktor 564
Kontextknoten 218, 220
Kontextpfad 77
L
<listener> 397
<load-on-startup> 396
<locale-encoding-mapping> 401
<Logger> 74
<login-config> 404
Ländercodes 318
Last-Modified 28
Listener 397, 564
Locale 317
localhost 71
log() 146
Log-Dateien 71, 120
Lokalisierungsstufe 218
M
<mime-mapping> 399
<mime-type> 399
Markup 564
Maskierungen 481
Metadaten 564
META-INF 111
MIME-Typ 104, 399, 564
Model 40
Model-View-Controller 39, 276, 564
Multithreading oder 251
MySQL 342
CREATE DATABASE 342
CREATE TABLE 342
Treiber 343, 352
N
name-from-attribute 466
name-given 466
Namensraum 565
Nebenläufigkeit genannt 251
nested scoped variables 202
node() 220
node-set 216
NSAPI 31
NullPointerException 160
O
<object> 178
Objekt 565
Objekte 138
ODBC 331, 565
out 140, 146, 491
out.print() 122
K
Klasse 564
Klassenvariable 117
Knotenmenge 216, 218
Kommentare 91, 482
P
<page-encoding> 407
page 140, 148, 491
PageContext 58, 138, 290, 429
Index
573
pageContext 140, 143, 152, 490, 492
page-Direktive
errorPage 485
import 484
isErrorPage 485
session 484
pageEncoding 314, 464, 485
pageScope 152, 492
param 152, 492
ParameterMetaData 381, 382
paramValues 152, 492
parent 219
Parser 565
PATH 63
PCDATA 565
Perl 565
phantom reads 379
PHP 565
PL/SQL 368
Plug-In 565
PooledConnection 384
Pooling 336
Port-Nummer 565
preceding 219
PreparedStatement 366
prepareStatement() 366
Principal 565
Property-Datei 323
PropertyEditor 162
R
<resource-ref> 352
<Realm> 74
<res-auth> 409
<Resource> 352
<ResourceParams> 352
<resource-ref> 409
<res-type> 409
<role-link> 403
<role-name> 403
<rtexprvalue> 420
Referenzimplementierung 565
removeAttribute() 144, 277, 305
Renderer 566
request 21, 139, 141, 289, 490, 557
request.getHeaderNames() 141
request.getParameter() 141
request.getRequestURI() 141
RequestDispatchern 398
requestScope 152, 492
ResourceBundle 321
response 21, 140, 142, 490
response.getOutputStream() 142
response.getWriter() 142
Ressourcenbündel 321
ResultSet 334, 347, 364, 370, 373
resultSetConcurrency 371
ResultSetMetaData 381, 382
574
Index
resultSetType 370
RFC 2109 294
RowSet 336, 378
S
<scripting-invalid> 407
<security-constraint> 402
<security-role> 402
<security-role-ref> 403
<Server> 73
<Service> 73
<servlet> 394, 395
<servlet-class> 395
<servlet-mapping> 396
<servlet-name> 396
<session-config> 394
<session-timeout> 306, 394
<sql:dateParam> 227, 533
<sql:param> 227, 362, 533
<sql:query> 227, 358, 530
<sql:setDataSource> 228, 358, 529
<sql:transaction> 227, 534
<sql:update> 227, 532
SAAJ 48
scope 138, 184, 194
scoped variables 202
scriptless 464
self 219
sendRedirect() 300
Serializable 275
Server 28
server.xml 71, 350, 405
Servererweiterung 31
Servlet 31, 286, 566
CLASSPATH 287
destroy()-Methode 286
init()-Methode 286
kompilieren 286
Lebenszyklus 286
plazieren 287
service()-Methode 286
Servlet-API 31, 47, 286, 290
servlet-api.jar 286, 424
Servlet-Container 32
ServletContext 55, 94, 304
Servlet-Spezifikation 32, 393
Servlet-Spezifikation 2.4 42
Session 298
JSESSIONID 299
session 140, 143, 289, 490
getID() 304
invalidate() 303, 308
isNew() 303
Session-ID 300
sessionScope 152, 492
setAttribute() 143, 290
setBodyContent() 428, 432
setContentType() 103, 322
Set-Cookie-Header 293
setJspBody() 439
setLocale() 322
setPageContext() 429
setParent() 429
SGML 566
Simple Tag-Handler 43
SimpleTag-Interface 427, 438
SimpleTagSupport 438
SimpleTagSupport-Klasse 428
SingleThreadModel 117, 251
Sitzung
eröffnen 303
Sitzungs-ID 302
Sitzungsverfolgung 298
Skriptausdruck 488
Skriptelement 90, 114, 487, 566
Skriptlet 120, 489, 566
Schleifen 126
Template-Text 122
Variable 121
Verzweigung 125
Skriptlets 115
SOAP 566
Sprachcodes 317
SQL 328
Batch-Updates 365
INSERT 353
SQL-Anweisung 329
SQLException 366, 383
SQL-Operator 362
sql-Skript 343
SQL-Typen 334
SSL 302
Standardaktionen 161
Start-Tag 90
stored procedures, 367
Struts 476
Synchronisierung 252
T
<tag> 110
<tag-class> 111, 420
<taglib> 110, 405, 420
<taglib-uri> 406
<textarea> 263
Tag 566
Tag Library Descriptor 110, 417, 445, 566
Tag-Bibliothek 418, 566
Tag-Datei 43, 418, 459
Direktiven 463
installieren 461
JSP-Fragmente 475
Syntax 462
tag-Direktive 463
Variablensynchronisierung 467
tagdir 487
TagExtraInfo 446
Tag-Handler 418, 421, 426, 566
Tag-Interface 427
taglib-Direktive 446, 455, 486
TagLibraryValidator 249, 446, 458
Tags
benutzerdefinierte 417
TagSupport-Klasse 428
TCP/IP 20
TCP/IP-Socket 21
Template-Daten 88, 566
Template-Element 58
Template-Text 91
text() 220
Thread 33, 566
Throwable 387
Throwable-Objekt 102
TLD 110, 417, 442, 445, 446, 566
<attribute> 451
<body-content> 450
<dynamic-attributes> 452
<fragment> 452
<function> 495
<rtexprvalue> 451
<tag-class> 449
<tag-file> 461
<taglib> 447
<tlib-version> 448
<uri> 448
<variable> 450
impliziter Deskriptor 461
installieren 454
TLD-Datei 419
Token 567
Tomcat 64
installieren 65
konfigurieren 66
Manager-Anwendung 413
Verzeichnisse. 67
webapps-Verzeichnis 411
tomcat-users.xml 405
toString() 229
Transaktionsverarbeitung 378
try/catch-Blöcke 124
T-SQL 368
U
<url-pattern> 396, 407
<user-data-constraint> 403
Unicode 313, 567
Uniform Resource Identifier 567
Uniform Resource Locator 567
updateRow() 373
URI 567
uri 487
URL 23, 567
Escape-Codes 25
URL-Kodierung 261
URL-Rewriting 304
Index
575
URL-Syntax 25
URL-Umschreibung 299
User-Agent 24
UTF-16 313
UTF-32 313
UTF-8 105, 313
V
Validierung 248, 567
valueBound() 305
valueUnbound() 305
var 184
Variable 138
variable-Direktive 466
VariableResolver 150
varReader 184
Vererbung 567
verteilte Webanwendung 567
Verzeichnis 336
View 40
Vorbereitetes SQL 365
W
<web-app> 393
<web-resource-collection> 402
<welcome-file-list> 400
WAR 74, 568
archivieren 412
installieren 413
WAR-Archiv 391, 411
wasNull() 377
Web Application Archive 74, 568
Web services 568
web.xml 75, 76, 111, 204, 306, 352, 391,
409
Webanwendung 44, 567
web-app_2_4.xsd 392
webapps 77
Web-Dienste 568
WEB-INF 111, 421
WEB-INF/tags 461
Webseite 568
Webserver 568
Website 568
Wohlgeformtes XML 568
work-Verzeichnis 386
Wrapper-Klasse 291
Wurzelverzeichnis 78
X
X/Open SQL CLI, 331
<x:choose> 225, 524
<x:forEach> 224, 225, 525
<x:if> 225, 524
<x:otherwise> 225, 525
<x:out> 224, 523
<x:param> 226, 528
<x:parse> 223, 522
<x:set> 225, 523
576
Index
<x:transform> 223, 225, 526
<x:when> 225, 525
XHTML 560
XML 214, 560
Datentypen 558
Document Object Model 559
Dokumentelement 558
Dokumentinstanz 558
Dokumentmodell 559
Dokumenttyp-Deklaration 559
DOM 559
DOM-Schnittstelle 240
DTD 239, 559
Infoset 561
Knoten 564
Komplexer Datentyp 564
Markup 234
Namensräume 237
Namensraum-URI 237
Parser 240
QName 565
QNames 237
Syntax 236, 557
Tags- 236
Transformationen 225
Wohlgeformtheit 239
Wurzelelement 393, 568
Wurzelknoten 568
XML Schema 568
XML-Deklaration 569
XML-Dokument 232, 569
XML-Dokumente 215
XML-Elemente 246
xmlns 113
xmlns-Attribute 393
XML-Prozessor 569
XML-Schema 42, 239, 392
XPath 43, 91, 149, 215, 569
Achsen 219
Attributknoten 216
DOM 216
Elementknoten 216
Funktionen 220
Knotenmengenfunktionen 221
Knotentest 219
Kommentarknoten 217
Logische Functionen 222
Lokalisierungspfad 217
Namensraumknoten 217
Numerische Funktionen 222
Prädikate 220
Prozessoren 220
Schreibweise 218
String-Funktionen 221
Textknoten 216
Verarbeitungs-anweisungsknoten 217
Wurzelknoten 216
XSL 569
XSLT 240, 569
Herunterladen