8. Anhänge
8.1. Tools für die Webentwicklung
Hier zeigen wir Ihnen, wo Sie die für die Webentwicklung erforderlichen Werkzeuge finden und wie Sie diese installieren. Bei einigen Werkzeugen haben sich die Versionen weiterentwickelt, und es kann sein, dass die hier gegebenen Erläuterungen für die neuesten Versionen nicht mehr zutreffen. Der Leser muss sich dann entsprechend anpassen... Im Webprogrammierungskurs werden wir im Wesentlichen die folgenden Werkzeuge verwenden, die alle kostenlos verfügbar sind:
- einen aktuellen Browser, der XML anzeigen kann. Die Beispiele des Kurses wurden mit Internet Explorer 6 getestet.
- ein aktuelles JDK (Java Development Kit). Die Beispiele des Kurses wurden mit dem JDK 1.4 getestet. Dieses JDK enthält das Java-Plug-in 1.4 für Browser, wodurch diese Java-Applets anzeigen können, die das JDK 1.4 nutzen.
- Eine Java-Entwicklungsumgebung zum Schreiben von Java-Servlets. In diesem Fall ist es JBuilder 7.
- Webserver: Apache, PWS (Personal Web Server), Tomcat.
- Apache wird für die Entwicklung von Webanwendungen in PERL (Practical Extracting and Reporting Language) oder PHP (Personal Home Page) verwendet.
- PWS wird für die Entwicklung von Webanwendungen in ASP (Active Server Pages) oder PHP verwendet
- Tomcat wird für die Entwicklung von Webanwendungen mithilfe von Java-Servlets oder JSP-Seiten (Java Server Pages) verwendet
- eine Datenbankverwaltungsanwendung: MySQL
- EasyPHP: ein Tool, das den Apache-Webserver, die Sprache PHP und das SGBD MySQL zusammenführt
8.1.1. Webserver, Browser, Skriptsprachen
- Gängige Webserver
- Apache (Linux, Windows)
- Internet Information Server IIS (NT), Personal Web Server PWS (Windows 9x)
- Wichtigste Browser
- Internet Explorer (Windows)
- Netscape (Linux, Windows)
- Serverseitige Skriptsprachen
- VBScript (IIS, PWS)
- JavaScript (IIS, PWS)
- Perl (Apache, IIS, PWS)
- PHP (Apache, IIS, PWS)
- Java (Apache, Tomcat)
- Sprachen .NET
- Browser-seitige Skriptsprachen
- VBScript (IE)
- JavaScript (IE, Netscape)
- PerlScript (IE)
- Java (IE, Netscape)
8.1.2. Wo finden Sie die Tools?
http://www.netscape.com/ (Link zu den Downloads) | |
http://www.microsoft.com/windows/ie/default.asp | |
http://www.php.net http://www.php.net/downloads.php (Windows-Binärdateien) | |
http://www.activestate.com http://www.activestate.com/Products/ http://www.activestate.com/Products/ActivePerl/ | |
http://msdn.microsoft.com/scripting (dem Link „Windows Script“ folgen) | |
http://java.sun.com/ http://java.sun.com/downloads.html (JSE) http://java.sun.com/j2se/1.4/download.html | |
http://www.apache.org/ http://www.apache.org/dist/httpd/binaries/win32/ | |
enthalten in NT 4.0 Option Pack für Windows 95 enthalten in CD für Windows 98 http://www.microsoft.com/ntserver/nts/downloads/recommended/NT4OptPk/win95.asp | |
http://www.microsoft.com | |
http://jakarta.apache.org/tomcat/ | |
http://www.borland.com/jbuilder/ http://www.borland.com/products/downloads/download_jbuilder.html | |
http://www.easyphp.org/ http://www.easyphp.org/telechargements.php3 |
8.1.3. EasyPHP
Diese Anwendung ist sehr praktisch, da sie in einem einzigen Paket Folgendes vereint:
- den Apache-Webserver (1.3.x)
- die Sprache PHP (4.x)
- das SGBD MySQL (3.23.x)
- ein Verwaltungstool für MySQL: PhpMyAdmin
Die Installationsanwendung sieht wie folgt aus:

Die Installation von EasyPHP verläuft problemlos, und im Dateisystem wird eine Verzeichnisstruktur angelegt:

die ausführbare Datei der Anwendung | |
die Verzeichnisstruktur des Apache-Servers | |
die Verzeichnisstruktur von SGBD MySQL | |
Verzeichnisstruktur der Anwendung phpMyAdmin | |
Verzeichnisstruktur von PHP | |
Stammverzeichnis der vom Apache-Server bereitgestellten Webseiten von EasyPHP | |
Verzeichnisbaum, in dem Skripte vom Typ CGI für den Apache-Server abgelegt werden können |
Der Hauptvorteil von EasyPHP besteht darin, dass die Anwendung vorkonfiguriert geliefert wird. Somit sind Apache, PHP und MySQL bereits für die Zusammenarbeit konfiguriert. Wenn man EasyPhp über die Verknüpfung im Programmmenü startet, erscheint unten rechts auf dem Bildschirm ein Symbol.
![]() |
Das „E“ mit dem roten Punkt sollte blinken, wenn der Webserver Apache und die Datenbank MySQL betriebsbereit sind. Wenn man mit der rechten Maustaste darauf klickt, werden folgende Menüoptionen angezeigt:

Mit der Option Administration können Einstellungen vorgenommen und Funktionstests durchgeführt werden:

8.1.3.1. Verwaltung PHP
Über die Schaltfläche „PHP-Infos“ können Sie die ordnungsgemäße Funktion des Apache-PHP-Paares überprüfen: Es sollte eine Informationsseite mit der Bezeichnung PHP erscheinen:

Die Schaltfläche „Erweiterungen“ zeigt eine Liste der für PHP installierten Erweiterungen an. Dabei handelt es sich eigentlich um Funktionsbibliotheken.

Der obige Bildschirm zeigt beispielsweise, dass die für die Nutzung der Datenbank „MySQL“ erforderlichen Funktionen vorhanden sind.
Über die Schaltfläche „Einstellungen“ werden die login/motdepasse des Datenbankadministrators MySQL angezeigt.

Die Verwendung der Datenbank MySQL würde den Rahmen dieser kurzen Einführung sprengen, aber es ist hier klar, dass für den Datenbankadministrator ein Passwort festgelegt werden müsste.
8.1.3.2. Apache-Verwaltung
Ebenfalls auf der Verwaltungsseite von EasyPHP können Sie über den Link „Ihre Aliase“ Aliase definieren, die einem Verzeichnis zugeordnet sind. Auf diese Weise können Webseiten an anderen Orten als im Verzeichnis „www“ der Verzeichnisstruktur von easyPhp abgelegt werden.

Wenn man auf der oben genannten Seite die folgenden Angaben macht:

und die Schaltfläche valider verwendet wird, werden die folgenden Zeilen zur Datei <easyphp>\apache\conf\httpd.conf hinzugefügt:
Alias /st/ "e:/data/serge/web/"
<Directory "e:/data/serge/web">
Options FollowSymLinks Indexes
AllowOverride None
Order deny,allow
allow from 127.0.0.1
deny from all
</Directory>
<easyphp> bezeichnet das Installationsverzeichnis von EasyPHP. httpd.conf ist die Konfigurationsdatei des Apache-Servers. Man kann dies also auch erreichen, indem man diese Datei direkt bearbeitet. Eine Änderung an der Datei httpd.conf wird normalerweise sofort von Apache übernommen. Sollte dies nicht der Fall sein, müsste man den Server beenden und anschließend neu starten, jeweils über das EasyPHP-Symbol:

Um unser Beispiel abzuschließen, können wir nun Webseiten im Verzeichnisbaum e:\data\serge\web ablegen:
und diese Seite über den Alias „st“ aufrufen:

In diesem Beispiel wurde der Apache-Server so konfiguriert, dass er auf Port 81 läuft. Sein Standardport ist 80. Dies wird durch die folgende Zeile in der bereits erwähnten Datei httpd.conf gesteuert:
8.1.3.3. Die Apache-Konfigurationsdatei htpd.conf
Wenn man Apache etwas genauer konfigurieren möchte, muss man seine Konfigurationsdatei httpd.conf, die sich hier im Ordner <easyphp>\apache\conf befindet, „von Hand“ bearbeiten:

Hier sind einige wichtige Punkte aus dieser Konfigurationsdatei:
Rolle | |
Gibt den Ordner an, in dem sich die Apache-Verzeichnisstruktur befindet | |
gibt an, auf welchem Port der Webserver arbeiten wird. Standardmäßig ist dies Port 80. Durch Ändern dieser Zeile kann der Webserver auf einem anderen Port betrieben werden | |
die E-Mail-Adresse des Apache-Serveradministrators | |
der Name des Rechners, auf dem der Apache-Server „läuft“ | |
das Installationsverzeichnis des Apache-Servers. Wenn in der Konfigurationsdatei relative Dateinamen vorkommen, beziehen sie sich auf diesen Ordner. | |
Das Stammverzeichnis der vom Server bereitgestellten Webseiten. Hier entspricht die URL http://machine/rep1/fic1.html der Datei E:\Program Files\EasyPHP\www\rep1\fic1.html | |
legt die Eigenschaften des vorherigen Ordners fest | |
Log-Ordner, also eigentlich <ServerRoot>\logs\error.log: E:\Program Files\EasyPHP\apache\logs\error.log. Diese Datei sollten Sie überprüfen, wenn Sie feststellen, dass der Apache-Server nicht funktioniert. | |
E:\Program Files\EasyPHP\cgi-bin ist das Stammverzeichnis des Verzeichnisbaums, in dem Skripte mit dem Namen CGI abgelegt werden können. Somit lautet die URL des Skripts CGI E:\http://machine/cgi-bin/rep1/script1.pl: URL E:\Program Files\EasyPHP\cgi-bin\rep1\script1.pl. | |
legt die Eigenschaften des oben genannten Ordners fest | |
Ladezeilen für die Module, die es Apache ermöglichen, mit PHP4 zu arbeiten. | |
Legt die Dateiendungen fest, die als von PHP zu verarbeitende Dateien gelten sollen |
8.1.3.4. Verwaltung von MySQL mit PhpMyAdmin
Auf der Verwaltungsseite von EasyPhp klicken Sie auf die Schaltfläche PhpMyAdmin:

Über die Dropdown-Liste unter Accueil können die . | ![]() |
Die Zahl in Klammern gibt die Anzahl der Tabellen an. Wenn man eine Datenbank auswählt, werden deren Tabellen angezeigt: | ![]() |
Die Webseite bietet eine Reihe von Funktionen für die Datenbank:

Wenn man auf den Link Afficher von user klickt:

Hier gibt es nur einen einzigen Benutzer: root, der Administrator von MySQL. Über den Link Modifier könnte man sein Passwort ändern, das derzeit leer ist, was für einen Administrator jedoch nicht empfehlenswert ist.
Wir werden nicht weiter auf PhpMyAdmin eingehen, da es sich um eine umfangreiche Software handelt, deren Beschreibung mehrere Seiten füllen würde.
8.1.4. PHP
Wir haben gesehen, wie man PHP über die Anwendung EasyPhp erhält. Um PHP direkt zu erhalten, ruft man die Website http://www.php.net auf.
PHP ist nicht nur im Web einsetzbar. Man kann es auch als Skriptsprache unter Windows verwenden. Erstellen Sie das folgende Skript und speichern Sie es unter dem Namen date.php:
<?
// PHP-Skript, das die Uhrzeit anzeigt
$maintenant=date("j/m/y, H:i:s",time());
echo "Nous sommes le $maintenant";
?>
Wechseln Sie in einem Fenster mit der Nummer DOS in das Verzeichnis von date.php und führen Sie es aus:
E:\data\serge\php\essais>"e:\program files\easyphp\php\php.exe" date.php
X-Powered-By: PHP/4.2.0
Content-type: text/html
Nous sommes le 18/07/02, 09:31:01
8.1.5. PERL
Es ist empfehlenswert, dass der Internet Explorer bereits installiert ist. Ist dies der Fall, konfiguriert Active Perl ihn so, dass er PERL-Skripte in HTML-Seiten akzeptiert, die dann von IE selbst auf der Client-Seite ausgeführt werden. Die Website von Active Perl ist unter URL http://www.activestate.comA zu finden. Nach der Installation wird PERL in einem Verzeichnis installiert, das wir <perl> nennen. Es enthält die folgende Verzeichnisstruktur:
DEISL1 ISU 32 403 23/06/00 17:16 DeIsL1.isu
BIN <REP> 23/06/00 17:15 bin
LIB <REP> 23/06/00 17:15 lib
HTML <REP> 23/06/00 17:15 html
EG <REP> 23/06/00 17:15 eg
SITE <REP> 23/06/00 17:15 site
HTMLHELP <REP> 28/06/00 18:37 htmlhelp
Die ausführbare Datei perl.exe befindet sich in <perl>\bin. Perl ist eine Skriptsprache, die unter Windows und Unix läuft. Sie wird außerdem bei der Programmierung von WEB verwendet. Schreiben wir ein erstes Skript:
# PERL-Skript, das die Uhrzeit anzeigt
# Module
use strict;
# Programm
my ($secondes,$minutes,$heure)=localtime(time);
print "Il est $heure:$minutes:$secondes\n";
Speichern Sie dieses Skript in einer Datei mit dem Namen heure.pl. Öffnen Sie ein Fenster mit dem Namen DOS, wechseln Sie in das Verzeichnis des oben genannten Skripts und führen Sie es aus:
8.1.6. VBScript, JavaScript, PerlScript
Diese Sprachen sind Skriptsprachen für Windows. Sie können in verschiedenen Containern wie
- Windows Scripting Host für den direkten Einsatz unter Windows, insbesondere zum Schreiben von Skripten zur Systemadministration
- Internet Explorer. Dort wird es in HTML-Seiten verwendet, denen es eine gewisse Interaktivität verleiht, die mit der Sprache HTML allein nicht zu erreichen wäre.
- Internet Information Server (IIS), dem Webserver von Microsoft unter NT/2000, und dessen Entsprechung, dem Personal Web Server (PWS), unter Win9x. In diesem Fall wird VBScript für die serverseitige Programmierung verwendet, eine Technologie, die von Microsoft als ASP (Active Server Pages) bezeichnet wird.
Die Installationsdatei URL wird unter http://msdn.microsoft.com/scripting heruntergeladen, und man folgt den Links zu „Windows Script“. Installiert werden:
- der Windows Scripting Host, ein Container, der die Verwendung verschiedener Skriptsprachen wie VBScript und JavaScript, aber auch anderer Sprachen wie PerlScript ermöglicht, das mit Active Perl mitgeliefert wird.
- ein VBscript-Interpreter
- ein JavaScript-Interpreter
Führen wir einige kurze Tests durch. Erstellen wir das folgende Programm „vbscript“:
' eine Klasse
class personne
Dim nom
Dim age
End class
' Erstellung eines Personenobjekts
Set p1=new personne
With p1
.nom="dupont"
.age=18
End With
' Anzeige der Eigenschaften der Person p1
With p1
wscript.echo "nom=" & .nom
wscript.echo "age=" & .age
End With
Dieses Programm verwendet Objekte. Nennen wir es objets.vbs (die Endung „vbs“ steht für eine VBScript-Datei). Wechseln wir in das Verzeichnis, in dem es sich befindet, und führen wir es aus:
E:\data\serge\windowsScripting\vbscript\poly\objets>cscript objets.vbs
Microsoft (R) Windows Script Host Version 5.6
Copyright (C) Microsoft Corporation 1996-2001. All rights reserved.
nom=dupont
age=18
Nun erstellen wir das folgende JavaScript-Programm, das Arrays verwendet:
// Array in einer Variante
// leeres Array
tableau=new Array();
affiche(tableau);
// Array wächst dynamisch
for(i=0;i<3;i++){
tableau.push(i*10);
}
// Anzeige des Arrays
affiche(tableau);
// nochmals
for(i=3;i<6;i++){
tableau.push(i*10);
}
affiche(tableau);
// mehrdimensionale Tabellen
WScript.echo("-----------------------------");
tableau2=new Array();
for(i=0;i<3;i++){
tableau2.push(new Array());
for(j=0;j<4;j++){
tableau2[i].push(i*10+j);
}//for j
}// for i
affiche2(tableau2);
// Ende
WScript.quit(0);
// ---------------------------------------------------------
function affiche(tableau){
// Tabellenanzeige
for(i=0;i<tableau.length;i++){
WScript.echo("tableau[" + i + "]=" + tableau[i]);
}//für
}//Funktion
// ---------------------------------------------------------
function affiche2(tableau){
// Tabellenanzeige
for(i=0;i<tableau.length;i++){
for(j=0;j<tableau[i].length;j++){
WScript.echo("tableau[" + i + "," + j + "]=" + tableau[i][j]);
}// für j
}//für i
}//Funktion
Dieses Programm verwendet Arrays. Nennen wir es tableaux.js (die Endung „js“ steht für eine JavaScript-Datei). Wechseln wir in das Verzeichnis, in dem es sich befindet, und führen wir es aus:
E:\data\serge\windowsScripting\javascript\poly\tableaux>cscript tableaux.js
Microsoft (R) Windows Script Host Version 5.6
Copyright (C) Microsoft Corporation 1996-2001. Tous droits réservés.
tableau[0]=0
tableau[1]=10
tableau[2]=20
tableau[0]=0
tableau[1]=10
tableau[2]=20
tableau[3]=30
tableau[4]=40
tableau[5]=50
-----------------------------
tableau[0,0]=0
tableau[0,1]=1
tableau[0,2]=2
tableau[0,3]=3
tableau[1,0]=10
tableau[1,1]=11
tableau[1,2]=12
tableau[1,3]=13
tableau[2,0]=20
tableau[2,1]=21
tableau[2,2]=22
tableau[2,3]=23
Zum Abschluss noch ein letztes Beispiel in Perlscript. Um auf Perlscript zugreifen zu können, muss Active Perl installiert sein.
<job id="PERL1">
<script language="PerlScript">
# klassisches Perl
%dico=("maurice"=>"juliette","philippe"=>"marianne");
@cles= keys %dico;
for ($i=0;$i<=$#Schlüssel;$i++){
$cle=$cles[$i];
$valeur=$dico{$cle};
$WScript->echo ("clé=".$cle.", valeur=".$valeur);
}
# Perl-Skript unter Verwendung von Windows-Script-Objekten
$dico=$WScript->CreateObject("Scripting.Dictionary");
$dico->add("maurice","juliette");
$dico->add("philippe","marianne");
$WScript->echo($dico->item("maurice"));
$WScript->echo($dico->item("philippe"));
</script>
</job>
Dieses Programm veranschaulicht die Erstellung und Verwendung von zwei Wörterbüchern: eines im klassischen Perl-Stil, das andere mit dem „Scripting Dictionary“-Objekt von Windows Script. Speichern wir diesen Code in der Datei dico.wsf (wsf ist die Dateiendung für Windows-Script-Dateien). Wechseln wir in den Ordner dieses Programms und führen wir es aus:
E:\data\serge\windowsScripting\perlscript\essais>cscript dico.wsf
Microsoft (R) Windows Script Host Version 5.6
Copyright (C) Microsoft Corporation 1996-2001. Tous droits réservés.
clé=philippe, valeur=marianne
clé=maurice, valeur=juliette
juliette
marianne
Perlscript kann auf die Objekte des Containers zugreifen, in dem es ausgeführt wird. In diesem Fall handelte es sich um Objekte des Windows-Script-Containers. Im Kontext der Webprogrammierung können die Skripte VBscript, JavaScript- und Perlscript-Skripte entweder im Browser IE oder auf einem Server PWS bzw. IIS ausgeführt werden. Ist das Skript etwas komplexer, kann es sinnvoll sein, es außerhalb des Webkontexts im Windows-Script-Container zu testen, wie zuvor beschrieben. Auf diese Weise lassen sich jedoch nur die Funktionen des Skripts testen, die keine browser- oder servereigenen Objekte verwenden. Trotz dieser Einschränkung bleibt diese Möglichkeit interessant, da es in der Regel recht umständlich ist, Skripte zu debuggen, die auf Webservern oder in Browsern ausgeführt werden.
8.1.7. JAVA
Java ist unter der URL verfügbar: http://www.sun.com und wird in einem Verzeichnisbaum installiert, den wir <java> nennen und der folgende Elemente enthält:
22/05/2002 05:51 <DIR> .
22/05/2002 05:51 <DIR> ..
22/05/2002 05:51 <DIR> bin
22/05/2002 05:51 <DIR> jre
07/02/2002 12:52 8 277 README.txt
07/02/2002 12:52 13 853 LICENSE
07/02/2002 12:52 4 516 COPYRIGHT
07/02/2002 12:52 15 290 readme.html
22/05/2002 05:51 <DIR> lib
22/05/2002 05:51 <DIR> include
22/05/2002 05:51 <DIR> demo
07/02/2002 12:52 10 377 848 src.zip
11/02/2002 12:55 <DIR> docs
Im Verzeichnis „bin“ befinden sich javac.exe, der Java-Compiler, und java.exe, die Java-Virtual-Machine. Folgende Tests können durchgeführt werden:
- Schreiben Sie das folgende Skript:
//Java-Programm zur Anzeige der Uhrzeit
import java.io.*;
import java.util.*;
public class heure{
public static void main(String arg[]){
// Datum und Uhrzeit abrufen
Date maintenant=new Date();
// Anzeige
System.out.println("Il est "+maintenant.getHours()+
":"+maintenant.getMinutes()+":"+maintenant.getSeconds());
}//main
}//Klasse
- Speichern Sie dieses Programm unter dem Namen heure.java. Öffnen Sie ein Fenster mit dem Namen DOS. Wechseln Sie in das Verzeichnis der Datei heure.java und kompilieren Sie sie:
D:\data\java\essais>c:\jdk1.3\bin\javac heure.java
Note: heure.java uses or overrides a deprecated API.
Note: Recompile with -deprecation for details.
In dem obigen Befehl muss c:\jdk1.3\bin\javac durch den genauen Pfad zum Compiler javac.exe ersetzt werden. Im selben Verzeichnis wie heure.java muss sich eine Datei namens heure.class befinden. Dabei handelt es sich um das Programm, das nun von der virtuellen Maschine java.exe ausgeführt wird.
- Führen Sie das Programm aus:
8.1.8. Apache-Server
Wir haben gesehen, dass man den Apache-Server mit der Anwendung EasyPhp erhalten kann. Um ihn direkt zu beziehen, rufen wir die Apache-Website auf: http://www.apache.org. Bei der Installation wird ein Verzeichnisbaum erstellt, in dem sich alle für den Server erforderlichen Dateien befinden. Nennen wir dieses Verzeichnis <apache>. Es enthält einen Verzeichnisbaum, der in etwa wie folgt aussieht:
UNINST ISU 118 805 23/06/00 17:09 Uninst.isu
HTDOCS <REP> 23/06/00 17:09 htdocs
APACHE~1 DLL 299 008 25/02/00 21:11 ApacheCore.dll
ANNOUN~1 3 000 23/02/00 16:51 Announcement
ABOUT_~1 13 197 31/03/99 18:42 ABOUT_APACHE
APACHE EXE 20 480 25/02/00 21:04 Apache.exe
KEYS 36 437 20/08/99 11:57 KEYS
LICENSE 2 907 01/01/99 13:04 LICENSE
MAKEFI~1 TMP 27 370 11/01/00 13:47 Makefile.tmpl
README 2 109 01/04/98 6:59 README
README NT 3 223 19/03/99 9:55 README.NT
WARNIN~1 TXT 339 21/09/98 13:09 WARNING-NT.TXT
BIN <REP> 23/06/00 17:09 bin
MODULES <REP> 23/06/00 17:09 modules
ICONS <REP> 23/06/00 17:09 icons
LOGS <REP> 23/06/00 17:09 logs
CONF <REP> 23/06/00 17:09 conf
CGI-BIN <REP> 23/06/00 17:09 cgi-bin
PROXY <REP> 23/06/00 17:09 proxy
INSTALL LOG 3 779 23/06/00 17:09 install.log
Ordner mit den Apache-Konfigurationsdateien | |
Ordner mit den Apache-Protokolldateien (Überwachung) | |
Die ausführbaren Dateien von Apache |
8.1.8.1. Configuration
Im Ordner <Apache>\conf befinden sich die folgenden Dateien: httpd.conf, srm.conf, access.conf. In den neuesten Apache-Versionen wurden die drei Dateien in httpd.conf zusammengefasst. Wir haben bereits die wichtigsten Punkte dieser Konfigurationsdatei vorgestellt. In den folgenden Beispielen diente die Apache-Version von EasyPhp als Testgrundlage und somit auch deren Konfigurationsdatei. Darin ist DocumentRoot, das den Stammordner der Webseiten angibt, e:\program files\easyphp\www.
8.1.8.2. Link zu PHP – Apache
Erstellen Sie zum Testen die Datei „intro.php“ mit der folgenden einzigen Zeile:
<? phpinfo() ?>
und legen Sie sie im Stammverzeichnis des Apache-Servers ab (DocumentRoot oben). Rufen Sie die Seite URL unter http://localhost/intro.php auf. Es sollte eine Liste mit Informationen zu php angezeigt werden:

Das folgende Skript PHP zeigt die Uhrzeit an. Wir sind ihm bereits begegnet:
<?php
// Zeit: Anzahl der Millisekunden seit dem 01.01.1970
// „Anzeigeformat für Datum und Uhrzeit“
// d: Tag, zweistellig
// m: zweistelliger Monat
// y: zweistelliges Jahr
// H: Stunde 0,23
// i: Minuten
// s: Sekunden
print "Nous sommes le " . date("d/m/y H:i:s",time());
?>
Legen wir diese Textdatei im Stammverzeichnis des Apache-Servers ab (DocumentRoot) und nennen wir sie date.php. Rufen wir mit einem Browser die Seite URL unter http://localhost/date.php auf. Wir erhalten folgende Seite:

8.1.8.3. Link PERL-APACHE
Er wird mithilfe einer Zeile der Form: ScriptAlias /cgi-bin/ "E:/Program Files/EasyPHP/cgi-bin/" aus der Datei <apache>\conf\httpd.conf erstellt. Die Syntax lautet ScriptAlias /cgi-bin/ "<cgi-bin>", wobei <cgi-bin> der Ordner ist, in dem CGI-Skripte abgelegt werden können. CGI (Common Gateway Interface) ist ein Standard für die Kommunikation zwischen dem Server WEB und Anwendungen. Ein Client fordert vom Webserver eine dynamische Seite an, c.a.d, d. h. eine Seite, die von einem Programm generiert wird. Der Server WEB muss daher ein Programm auffordern, die Seite zu generieren. CGI definiert die Kommunikation zwischen dem Server und dem Programm, insbesondere die Art und Weise, wie Informationen zwischen diesen beiden Einheiten übertragen werden.
Ändern Sie bei Bedarf die Zeile ScriptAlias /cgi-bin/ „<cgi-bin>“ und starten Sie den Apache-Server neu. Führen Sie anschließend folgenden Test durch:
- Schreiben Sie das Skript:
#!c:\perl\bin\perl.exe
# Skript PERL zur Anzeige der Uhrzeit
# Module
use strict;
# Programm
my ($secondes,$minutes,$heure)=localtime(time);
print <<FINHTML
Content-Type: text/html
<html>
<head>
<title>heure</title>
</head>
<body>
<h1>Il est $heure:$minutes:$secondes</h1>
</body>
FINHTML
;
- Legen Sie dieses Skript in <cgi-bin>\heure.pl ab, wobei <cgi-bin> der Ordner ist, in dem Skripte vom Typ CGI abgelegt werden können (siehe httpd.conf). Die erste Zeile #!c:\perl\bin\perl.exe gibt den Pfad zur ausführbaren Datei perl.exe an. Ändern Sie diesen bei Bedarf.
- Starten Sie Apache, falls dies noch nicht geschehen ist
- Rufen Sie mit einem Browser die Seite URL unter http://localhost/cgi-bin/heure.pl auf. Es wird folgende Seite angezeigt:

8.1.9. Der Server PWS
8.1.9.1. Installation
Der Server PWS (Personal Web Server) ist eine persönliche Version des Servers IIS (Internet Information Server) von Microsoft. Letzterer ist auf den Systemen NT und 2000 verfügbar. Auf Win9x-Rechnern ist PWS normalerweise im Internet Explorer-Installationspaket enthalten. Er wird jedoch nicht standardmäßig installiert. Man muss eine benutzerdefinierte Installation von IE durchführen und die Installation von PWS anfordern. Es ist außerdem im NT 4.0 Option Pack für Windows 95 enthalten.
8.1.9.2. Erste Tests
Der Stammordner der Webseiten des Servers PWS lautet „Laufwerk:\inetpub\wwwroot“, wobei „Laufwerk“ das Laufwerk ist, auf dem Sie PWS installiert haben. Im Folgenden gehen wir davon aus, dass es sich bei diesem Laufwerk um D handelt. Somit entspricht die URL http://machine/rep1/page1.html der Datei d:\inetpub\wwwroot\rep1\page1.html. Der Server PWS interpretiert jede Datei mit der Endung .asp (Active Server Pages) als Skript, das er ausführen muss, um eine Seite HTML zu erzeugen.
PWS läuft standardmäßig auf Port 80. Der Apache-Webserver ebenfalls... Sie müssen daher Apache beenden, um mit PWS arbeiten zu können, wenn Sie beide Server haben. Die andere Lösung besteht darin, Apache so zu konfigurieren, dass er auf einem anderen Port läuft. Dazu ersetzt man in der Apache-Konfigurationsdatei httpd.conf die Zeile „Port 80“ durch „Port 81“. Apache läuft nun auf Port 81 und kann gleichzeitig mit PWS verwendet werden. Wenn PWS gestartet wurde und man die Seite http://localhost aufruft, erhält man eine Seite, die in etwa wie folgt aussieht:

8.1.9.3. Link PHP – PWS
- Nachfolgend finden Sie eine .reg-Datei zur Änderung der Registrierungsdatenbank. Doppelklicken Sie auf diese Datei, um die Registrierung zu ändern. Hier befindet sich die benötigte dll in d:\php4 zusammen mit der PHP-Ausführungsdatei. Nehmen Sie bei Bedarf Änderungen vor. Die Backslashes (\) im Pfad zur DLL müssen verdoppelt werden.
REGEDIT4
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\w3svc\parameters\Script Map]
".php"="d:\\php4\\php4isapi.dll"
- Starten Sie den Rechner neu, damit die Änderung in der Registrierungsdatenbank übernommen wird.
- Erstellen Sie einen PHP-Ordner in d:\inetpub\wwwroot, dem Stammverzeichnis des Servers PWS. Aktivieren Sie anschließend PWS und wechseln Sie zur Registerkarte „Erweitert“. Klicken Sie auf die Schaltfläche „Hinzufügen“, um einen virtuellen Ordner zu erstellen:
- Bestätigen Sie alles und starten Sie PWS neu. Fügen Sie in d:\inetpub\wwwroot\php die Datei intro.php ein, die ausschließlich die folgende Zeile enthält:
- Fordern Sie vom Server PWS die Datei URL „http://localhost/php/intro.php“ an. Es sollte die Liste der PHP-Informationen angezeigt werden, die bereits mit Apache dargestellt wurden.
8.1.10. Tomcat: Java-Servlets und JSP-Seiten (Java Server Pages)
Tomcat ist ein Webserver, mit dem sich HTML-Seiten mithilfe von Servlets (vom Webserver ausgeführte Java-Programme) oder JSP-Seiten (Java Server Pages) erstellen lassen, bei denen Java-Code und HTML-Code miteinander kombiniert werden. Dies entspricht den ASP-Seiten (Active Server Pages) des Microsoft-Servers IIS/PWS, bei denen VBScript-Code oder JavaScript mit HTML-Code vermischt wird.
8.1.10.1. Installation
Tomcat ist unter der Adresse URL verfügbar: http://jakarta.apache.org. Man lädt eine .exe-Installationsdatei herunter. Wenn man dieses Programm startet, gibt es zunächst an, welche Java-Version es verwenden wird. Tatsächlich benötigt Tomcat eine Java-Version, um sich zu installieren und anschließend die Java-Servlets zu kompilieren und auszuführen. Sie müssen daher vor der Installation von Tomcat eine Java-Version installiert haben. Es wird die aktuellste Version empfohlen. Die Installation erstellt einen Ordnerbaum <tomcat>:

Die Installation besteht lediglich darin, dieses Archiv in ein Verzeichnis zu entpacken. Wählen Sie ein Verzeichnis, dessen Pfad ausschließlich Namen ohne Leerzeichen enthält (also beispielsweise nicht „Program Files“), da es einen Fehler im Installationsprozess von Tomcat gibt. Verwenden Sie beispielsweise C:\tomcat oder D:\tomcat. Nennen wir dieses Verzeichnis <tomcat>. Darin befindet sich ein Ordner namens jakarta-tomcat, der wiederum die folgende Verzeichnisstruktur enthält:
LOGS <REP> 15/11/00 9:04 logs
LICENSE 2 876 18/04/00 15:56 LICENSE
CONF <REP> 15/11/00 8:53 conf
DOC <REP> 15/11/00 8:53 doc
LIB <REP> 15/11/00 8:53 lib
SRC <REP> 15/11/00 8:53 src
WEBAPPS <REP> 15/11/00 8:53 webapps
BIN <REP> 15/11/00 8:53 bin
WORK <REP> 15/11/00 9:04 work
8.1.10.2. Starten/Beenden des Tomcat-Webservers
Tomcat ist ein Webserver, genau wie Apache oder PWS. Um ihn zu starten, stehen im Programmmenü folgende Verknüpfungen zur Verfügung:
zum Starten von Tomcat | |
zum Beenden |
Beim Starten von Tomcat wird ein DOS-Fenster mit folgendem Inhalt angezeigt:

Dieses DOS-Fenster kann minimiert werden. Es bleibt so lange sichtbar, wie Tomcat aktiv ist. Anschließend können die ersten Tests durchgeführt werden. Der Tomcat-Webserver läuft auf Port 8080. Sobald Tomcat gestartet ist, öffnen Sie einen Webbrowser und rufen Sie die Adresse URL http://localhost:8080 auf. Sie sollten die folgende Seite sehen:

Folgen Sie dem Link „Servlet Examples“:

Klicken Sie auf den Link Execute von RequestParameters und anschließend auf den Link von Source. So erhalten Sie einen ersten Einblick in die Funktionsweise eines Java-Servlets. Das Gleiche können Sie mit den Links auf den Seiten JSP tun.
Um Tomcat zu beenden, verwenden Sie den Link „Stop Tomcat“ im Programmmenü.
8.1.11. JBuilder
JBuilder ist eine Entwicklungsumgebung für Java-Anwendungen. Um Java-Servlets zu erstellen, bei denen keine grafischen Benutzeroberflächen vorhanden sind, ist eine solche Umgebung nicht unbedingt erforderlich. Ein Texteditor und ein JDK reichen aus. Lediglich JBuilder bietet gegenüber der vorherigen Methode einige Vorteile:
- Einfache Fehlersuche: Der Compiler zeigt fehlerhafte Zeilen in einem Programm an, und es ist einfach, die entsprechende Stelle zu finden
- Code-Vorschläge: Bei der Verwendung eines Java-Objekts zeigt JBuilder inline eine Liste der Eigenschaften und Methoden dieses Objekts an. Das ist sehr praktisch, da die meisten Java-Objekte sehr viele Eigenschaften und Methoden haben, die man sich nur schwer merken kann.
JBuilder ist auf der Website http://www.borland.com/jbuilder zu finden. Um die Software zu erhalten, muss ein Formular ausgefüllt werden. Ein Aktivierungsschlüssel wird per E-Mail zugesandt. Zur Installation von JBuilder 7 wurde beispielsweise wie folgt vorgegangen:
- Es wurden drei ZIP-Dateien heruntergeladen: für die Anwendung, für die Dokumentation und für die Beispiele. Für jede dieser ZIP-Dateien gibt es einen separaten Link auf der Website von JBuilder.
- Zuerst wurde die Anwendung installiert, dann die Dokumentation und schließlich die Beispiele
- Beim ersten Start der Anwendung wird ein Aktivierungsschlüssel abgefragt: Dies ist der Schlüssel, der Ihnen per E-Mail zugesandt wurde. In Version 7 besteht dieser Schlüssel tatsächlich aus dem gesamten Inhalt einer Textdatei, die Sie beispielsweise im Installationsordner von JB7 ablegen können. Wenn der Schlüssel abgefragt wird, wählen Sie einfach die betreffende Datei aus. Sobald dies geschehen ist, wird der Schlüssel nicht mehr abgefragt.
Es sind einige nützliche Konfigurationen vorzunehmen, wenn man JBuilder zum Erstellen von Java-Servlets verwenden möchte. Die sogenannte „Jbuilder Personal“-Version ist nämlich eine abgespeckte Version, die insbesondere nicht alle Klassen enthält, die für die Webentwicklung in Java erforderlich sind. Man kann dafür sorgen, dass JBuilder die von Tomcat bereitgestellten Klassenbibliotheken verwendet. Dazu geht man wie folgt vor:
- Starten Sie JBuilder

- die Option „Tools/Configure JDKs“ aktivieren

Im obigen Bereich „JDK Settings“ steht normalerweise im Feld „Name“ ein Eintrag wie „JDK 1.3.1“. Wenn Sie eine neuere Version von JDK haben, verwenden Sie die Schaltfläche „Change“, um das Installationsverzeichnis dieser Version anzugeben. Oben wurde das Verzeichnis E:\Program Files\jdk14 angegeben, in dem ein JDK 1.4 installiert war. Von nun an wird JBuilder dieses JDK für seine Kompilierungen und Ausführungen verwenden. Im Bereich (Class, Source, Documentation) finden Sie die Liste aller Klassenbibliotheken, die von JBuilder durchsucht werden, in diesem Fall die Klassen von JDK 1.4. Die darin enthaltenen Klassen reichen für die Webentwicklung in Java nicht aus. Um weitere Klassenbibliotheken hinzuzufügen, verwendet man die Schaltfläche „Add“ und wählt die zusätzlichen .jar-Dateien aus, die man verwenden möchte. Die .jar-Dateien sind Klassenbibliotheken. Tomcat 4.x enthält bereits alle für die Webentwicklung erforderlichen Klassenbibliotheken. Diese befinden sich unter <tomcat>\common\lib, wobei <tomcat> das Installationsverzeichnis von Tomcat ist:

Mit der Schaltfläche „Add“ fügen wir diese Bibliotheken nacheinander zur Liste der von JBuilder durchsuchten Bibliotheken hinzu:

Ab sofort können Java-Programme gemäß dem Standard J2EE kompiliert werden, insbesondere Java-Servlets. JBuilder dient lediglich der Kompilierung; die Ausführung erfolgt anschließend durch Tomcat gemäß den im Kurs erläuterten Modalitäten.
8.2. Quellcode von Programmen
8.2.1. Der generische Client TCP
Viele Dienste, die zu Beginn des Internets entstanden sind, funktionieren nach dem zuvor behandelten Echo-Server-Modell: Der Austausch zwischen Client und Server erfolgt über den Austausch von Textzeilen. Wir werden einen generischen TCP-Client schreiben, der wie folgt gestartet wird: java cltTCPgenerique Server Port
Dieser Client TCP stellt eine Verbindung zum Port port des Servers serveur her. Anschließend erstellt er zwei Threads:
- einen Thread, der die über die Tastatur eingegebenen Befehle liest und an den Server sendet
- ein Thread, der die Antworten des Servers liest und auf dem Bildschirm anzeigt
Warum zwei Threads? Jeder TCP-IP-Dienst hat sein eigenes Protokoll, und manchmal treten folgende Situationen auf:
- Der Client muss mehrere Textzeilen senden, bevor er eine Antwort erhält
- Die Antwort eines Servers kann mehrere Textzeilen umfassen
Daher ist die Schleife „Senden einer einzelnen Zeile an den Server – Empfangen einer einzelnen Zeile vom Server“ nicht immer geeignet. Wir erstellen daher zwei voneinander getrennte Schleifen:
- eine Schleife zum Einlesen der über die Tastatur eingegebenen Befehle, die an den Server gesendet werden sollen. Der Benutzer signalisiert das Ende der Befehle mit dem Schlüsselwort fin.
- eine Schleife zum Empfangen und Anzeigen der Antworten des Servers. Dabei handelt es sich um eine Endlosschleife, die nur durch das Schließen der Netzwerkverbindung durch den Server oder durch den Benutzer über die Tastatur unterbrochen wird, indem dieser den Befehl fin eingibt.
Um diese beiden Schleifen voneinander zu trennen, benötigen wir zwei unabhängige Threads. Betrachten wir ein Ausführungsbeispiel, bei dem sich unser generischer TCP-Client mit einem Dienst namens SMTP (SendMail Transfer Protocol) verbindet. Dieser Dienst ist für die Weiterleitung von E-Mails an ihre Empfänger zuständig. Er läuft auf Port 25 und verwendet ein Dialogprotokoll, bei dem Textzeilen ausgetauscht werden.
Dos>java clientTCPgenerique istia.univ-angers.fr 25
Commandes :
<-- 220 istia.univ-angers.fr ESMTP Sendmail 8.11.6/8.9.3; Mon, 13 May 2002 08:37:26 +0200
help
<-- 502 5.3.0 Sendmail 8.11.6 -- HELP not implemented
mail from: machin@univ-angers.fr
<-- 250 2.1.0 machin@univ-angers.fr... Sender ok
rcpt to: serge.tahe@istia.univ-angers.fr
<-- 250 2.1.5 serge.tahe@istia.univ-angers.fr... Recipient ok
data
<-- 354 Enter mail, end with "." on a line by itself
Subject: test
ligne1
ligne2
ligne3
.
<-- 250 2.0.0 g4D6bks25951 Message accepted for delivery
quit
<-- 221 2.0.0 istia.univ-angers.fr closing connection
[fin du thread de lecture des réponses du serveur]
fin
[fin du thread d'envoi des commandes au serveur]
Erläutern wir diesen Client-Server-Austausch:
- Der Dienst SMTP sendet eine Begrüßungsnachricht, wenn sich ein Client bei ihm anmeldet:
- Einige Dienste verfügen über den Befehl help, der Hinweise zu den mit dem Dienst verwendbaren Befehlen gibt. Hier ist dies nicht der Fall. Die im Beispiel verwendeten Befehle SMTP lauten wie folgt:
- mail from: expéditeur, um die E-Mail-Adresse des Absenders der Nachricht anzugeben
- rcpt to: destinataire, um die E-Mail-Adresse des Empfängers der Nachricht anzugeben. Bei mehreren Empfängern wird der Befehl „rcpt to:“ so oft wie nötig für jeden einzelnen Empfänger wiederholt.
- data, das dem Server SMTP signalisiert, dass die Nachricht gesendet wird. Wie in der Antwort des Servers angegeben, handelt es sich dabei um eine Folge von Zeilen, die mit einer Zeile endet, die ausschließlich das Zeichen „.“ enthält. Eine Nachricht kann Kopfzeilen enthalten, die durch eine Leerzeile vom Nachrichtentext getrennt sind. In unserem Beispiel haben wir einen Betreff mit dem Schlüsselwort Subject: angegeben
- Sobald die Nachricht gesendet wurde, kann man dem Server mit dem Befehl „quit“ mitteilen, dass man fertig ist. Der Server schließt daraufhin die Netzwerkverbindung. Der Lesethread kann dieses Ereignis erkennen und sich beenden.
- Der Benutzer gibt dann „fin“ über die Tastatur ein, um auch den Thread zum Lesen der über die Tastatur eingegebenen Befehle zu beenden.
Wenn man die empfangene E-Mail überprüft, sieht man Folgendes (Outlook):

Es ist zu beachten, dass der Dienst „SMTP“ nicht erkennen kann, ob ein Absender gültig ist oder nicht. Daher darf man dem Feld „from“ einer Nachricht niemals vertrauen. In diesem Fall existierte der Absender „machin@univ-angers.fr“ nicht.
Dieser generische TCP-Client ermöglicht es uns, das Kommunikationsprotokoll von Internetdiensten zu ermitteln und auf dieser Grundlage spezialisierte Klassen für Clients dieser Dienste zu erstellen. Sehen wir uns das Kommunikationsprotokoll des Dienstes POP (Post Office Protocol) an, mit dem man seine auf einem Server gespeicherten E-Mails abrufen kann. Er läuft auf Port 110.
Dos> java clientTCPgenerique istia.univ-angers.fr 110
Commandes :
<-- +OK Qpopper (version 4.0.3) at istia.univ-angers.fr starting.
help
<-- -ERR Unknown command: "help".
user st
<-- +OK Password required for st.
pass monpassword
<-- +OK st has 157 visible messages (0 hidden) in 11755927 octets.
list
<-- +OK 157 visible messages (11755927 octets)
<-- 1 892847
<-- 2 171661
...
<-- 156 2843
<-- 157 2796
<-- .
retr 157
<-- +OK 2796 octets
<-- Received: from lagaffe.univ-angers.fr (lagaffe.univ-angers.fr [193.49.144.1])
<-- by istia.univ-angers.fr (8.11.6/8.9.3) with ESMTP id g4D6wZs26600;
<-- Mon, 13 May 2002 08:58:35 +0200
<-- Received: from jaume ([193.49.146.242])
<-- by lagaffe.univ-angers.fr (8.11.1/8.11.2/GeO20000215) with SMTP id g4D6wSd37691;
<-- Mon, 13 May 2002 08:58:28 +0200 (CEST)
...
<-- ------------------------------------------------------------------------
<-- NOC-RENATER2 Tl. : 0800 77 47 95
<-- Fax : (+33) 01 40 78 64 00 , Email : noc-r2@cssi.renater.fr
<-- ------------------------------------------------------------------------
<--
<-- .
quit
<-- +OK Pop server at istia.univ-angers.fr signing off.
[fin du thread de lecture des réponses du serveur]
fin
[fin du thread d'envoi des commandes au serveur]
Die wichtigsten Befehle lauten wie folgt:
- user login, wobei man seinen Benutzernamen auf dem Rechner angibt, auf dem sich die E-Mails befinden
- pass password, wobei man das zum vorherigen Login gehörende Passwort eingibt
- list, um eine Liste der Nachrichten in Form von Nummer und Größe in Byte zu erhalten
- retr i, um die Nachricht Nr. i zu lesen
- quit, um die Verbindung zu beenden.
Sehen wir uns nun das Dialogprotokoll zwischen einem Client und einem Webserver an, der in der Regel auf Port 80 läuft:
Dos> java clientTCPgenerique istia.univ-angers.fr 80
Commandes :
GET /index.html HTTP/1.0
<-- HTTP/1.1 200 OK
<-- Date: Mon, 13 May 2002 07:30:58 GMT
<-- Server: Apache/1.3.12 (Unix) (Red Hat/Linux) PHP/3.0.15 mod_perl/1.21
<-- Last-Modified: Wed, 06 Feb 2002 09:00:58 GMT
<-- ETag: "23432-2bf3-3c60f0ca"
<-- Accept-Ranges: bytes
<-- Content-Length: 11251
<-- Connection: close
<-- Content-Type: text/html
<--
<-- <html>
<--
<-- <head>
<-- <meta http-equiv="Content-Type"
<-- content="text/html; charset=iso-8859-1">
<-- <meta name="GENERATOR" content="Microsoft FrontPage Express 2.0">
<-- <title>Bienvenue a l'ISTIA - Universite d'Angers</title>
<-- </head>
....
<-- face="Verdana"> - Dernire mise jour le <b>10 janvier 2002</b></font></p>
<-- </body>
<-- </html>
<--
[fin du thread de lecture des réponses du serveur]
fin
[fin du thread d'envoi des commandes au serveur]
Ein Webclient sendet seine Befehle nach folgendem Schema an den Server:
Erst nach Erhalt der leeren Zeile antwortet der Webserver. In diesem Beispiel haben wir nur einen Befehl verwendet:
der den Server nach URL /index.html abfragt und angibt, dass er mit dem Protokoll HTTP Version 1.0 arbeitet. Die aktuellste Version dieses Protokolls ist 1.1. Das Beispiel zeigt, dass der Server mit dem Inhalt der Datei index.html geantwortet und anschließend die Verbindung geschlossen hat, da der Thread zum Lesen der Antworten beendet wurde. Vor dem Senden des Inhalts der Datei index.html hat der Webserver eine Reihe von Headern gesendet, die mit einer Leerzeile endeten:
<-- HTTP/1.1 200 OK
<-- Date: Mon, 13 May 2002 07:30:58 GMT
<-- Server: Apache/1.3.12 (Unix) (Red Hat/Linux) PHP/3.0.15 mod_perl/1.21
<-- Last-Modified: Wed, 06 Feb 2002 09:00:58 GMT
<-- ETag: "23432-2bf3-3c60f0ca"
<-- Accept-Ranges: bytes
<-- Content-Length: 11251
<-- Connection: close
<-- Content-Type: text/html
<--
<-- <html>
Die Zeile <html> ist die erste Zeile der Datei /index.html. Das Vorstehende wird als HTTP-Header (HyperText-Übertragungsprotokoll) bezeichnet. Wir werden hier nicht näher auf diese Header eingehen, aber man sollte bedenken, dass unser generischer Client Zugriff darauf gewährt, was zum Verständnis hilfreich sein kann. Die erste Zeile zum Beispiel:
gibt an, dass der angesprochene Webserver das Protokoll HTTP/1.1 versteht und die angeforderte Datei erfolgreich gefunden hat (200 OK), wobei 200 ein HTTP-Antwortcode ist. Die Zeilen
teilen dem Client mit, dass er 11251 Bytes empfangen wird, die den Text HTML (HyperText Markup Language) darstellen, und dass die Verbindung nach Abschluss der Übertragung geschlossen wird.
Wir haben hier also einen sehr praktischen TCP-Client. Er kann zweifellos weniger als das offizielle Programm telnet, aber es war interessant, ihn selbst zu schreiben. Das Programm für den generischen TCP-Client lautet wie folgt:
// importierte Pakete
import java.io.*;
import java.net.*;
public class clientTCPgenerique{
// erhält als Parameter die Merkmale eines Dienstes in der Form
// Server-Port
// stellt eine Verbindung zum Dienst her
// erstellt einen Thread zum Einlesen von über die Tastatur eingegebenen Befehlen
// diese werden an den Server gesendet
// erstellt einen Thread zum Lesen der Antworten vom Server
// diese werden auf dem Bildschirm angezeigt
// Das Ganze endet mit dem über die Tastatur eingegebenen Befehl „fin“
// Instanzvariable
private static Socket client;
public static void main(String[] args){
// Syntax
final String syntaxe="pg serveur port";
// Anzahl der Argumente
if(args.length != 2)
erreur(syntaxe,1);
// Hier wird der Name des Servers notiert
String serveur=args[0];
// Der Port muss eine ganze Zahl > 0 sein
int port=0;
boolean erreurPort=false;
Exception E=null;
try{
port=Integer.parseInt(args[1]);
}catch(Exception e){
E=e;
erreurPort=true;
}
erreurPort=erreurPort || port <=0;
if(erreurPort)
erreur(syntaxe+"\n"+"Port incorrect ("+E+")",2);
client=null;
// Es können Probleme auftreten
try{
// Verbindung zum Dienst herstellen
client=new Socket(serveur,port);
}catch(Exception ex){
// Fehler
erreur("Impossible de se connecter au service ("+ serveur
+","+port+"), erreur : "+ex.getMessage(),3);
// Ende
return;
}//catch
// Lese-/Schreib-Threads werden erstellt
new ClientSend(client).start();
new ClientReceive(client).start();
// Ende des Haupt-Threads
return;
}// main
// Anzeige der Fehler
public static void erreur(String msg, int exitCode){
// Fehleranzeige
System.err.println(msg);
// Beenden mit Fehler
System.exit(exitCode);
}//Fehler
}//Klasse
class ClientSend extends Thread {
// Klasse zum Lesen von über die Tastatur eingegebenen Befehlen
// und diese über einen als Parameter übergebenen TCP-Client an einen Server zu senden
private Socket client; // der TCP-Client
// Konstruktor
public ClientSend(Socket client){
// Hier wird der TCP-Client notiert
this.client=client;
}//Konstruktor
// Run-Methode des Threads
public void run(){
// lokale Daten
PrintWriter OUT=null; // Netzwerk-Schreibstrom
BufferedReader IN=null; // Tastatur-Datenstrom
String commande=null; // von der Tastatur gelesener Befehl
// Fehlerbehandlung
try{
// Erstellung des Netzwerk-Schreibstroms
OUT=new PrintWriter(client.getOutputStream(),true);
// Erstellung des Tastatureingabestroms
IN=new BufferedReader(new InputStreamReader(System.in));
// Schleife für die Eingabe und das Senden von Befehlen
System.out.println("Commandes : ");
while(true){
// Auslesen des über die Tastatur eingegebenen Befehls
commande=IN.readLine().trim();
// Fertig?
if (commande.toLowerCase().equals("fin")) break;
// Befehl an den Server senden
OUT.println(commande);
// Nächster Befehl
}//while
}catch(Exception ex){
// Fehler
System.err.println("Envoi : L'erreur suivante s'est produite : " + ex.getMessage());
}//catch
// Ende – Streams werden geschlossen
try{
OUT.close();client.close();
}catch(Exception ex){}
// das Ende des Threads wird gemeldet
System.out.println("[Envoi : fin du thread d'envoi des commandes au serveur]");
}//run
}//Klasse
class ClientReceive extends Thread{
// Klasse, die für das Einlesen der Textzeilen zuständig ist, die für einen
// als Parameter übergebenen TCP-Client bestimmt sind
private Socket client; // der TCP-Client
// Konstruktor
public ClientReceive(Socket client){
// Der TCP-Client wird notiert
this.client=client;
}//Konstruktor
// Run-Methode des Threads
public void run(){
// lokale Daten
BufferedReader IN=null; // Netzwerk-Lese-Stream
String réponse=null; // Serverantwort
// Fehlerbehandlung
try{
// Erstellung des Netzwerk-Lesestreams
IN=new BufferedReader(new InputStreamReader(client.getInputStream()));
// Schleife zum Einlesen von Textzeilen aus dem Datenstrom IN
while(true){
// Lesen des Netzwerkstroms
réponse=IN.readLine();
// Datenstrom geschlossen?
if(réponse==null) break;
// Anzeige
System.out.println("<-- "+réponse);
}//while
}catch(Exception ex){
// Fehler
System.err.println("Réception : L'erreur suivante s'est produite : " + ex.getMessage());
}//catch
// Ende – die Datenströme werden geschlossen
try{
IN.close();client.close();
}catch(Exception ex){}
// das Ende des Threads wird gemeldet
System.out.println("[Réception : fin du thread de lecture des réponses du serveur]");
}//run
}//Klasse
8.2.2. Der generische TCP-Server
Nun wenden wir uns einem Server zu,
- , der die von seinen Clients gesendeten Befehle auf dem Bildschirm anzeigt
- und ihnen als Antwort die Textzeilen zurücksendet, die ein Benutzer über die Tastatur eingegeben hat. Letzterer fungiert also als Server.
Das Programm wird gestartet mit: java serveurTCPgenerique portEcoute, wobei portEcoute der Port ist, über den sich die Clients verbinden müssen. Die Bedienung der Clients wird von zwei Threads übernommen:
- ein Thread, der sich ausschließlich dem Einlesen der vom Client gesendeten Textzeilen widmet
- ein Thread, der sich ausschließlich dem Einlesen der vom Benutzer über die Tastatur eingegebenen Antworten widmet. Dieser signalisiert mit dem Befehl „fin“, dass er die Verbindung zum Client beendet.
Der Server erstellt zwei Threads pro Client. Bei n Clients sind somit 2n Threads gleichzeitig aktiv. Der Server selbst wird niemals beendet, es sei denn, der Benutzer drückt die Tastenkombination Strg+C. Sehen wir uns einige Beispiele an.
Der Server wird auf Port 100 gestartet, und wir verwenden den generischen Client, um mit ihm zu kommunizieren. Das Client-Fenster sieht wie folgt aus:
E:\data\serge\MSNET\c#\Netzwerk\generischer TCP-Client> java clientTCPgenerique localhost 100
Commandes :
commande 1 du client 1
<-- réponse 1 au client 1
commande 2 du client 1
<-- réponse 2 au client 1
fin
L'erreur suivante s'est produite : Impossible de lire les données de la connexion de transport.
[fin du thread de lecture des réponses du serveur]
[fin du thread d'envoi des commandes au serveur]
Die Zeilen, die mit <-- beginnen, sind vom Server an den Client gesendet worden, die anderen vom Client an den Server. Das Serverfenster sieht wie folgt aus:
Dos> java serveurTCPgenerique 100
Serveur générique lancé sur le port 100
Thread de lecture des réponses du serveur au client 1 lancé
1 : Thread de lecture des demandes du client 1 lancé
<-- commande 1 du client 1
réponse 1 au client 1
1 : <-- commande 2 du client 1
réponse 2 au client 1
1 : [fin du Thread de lecture des demandes du client 1]
fin
[fin du Thread de lecture des réponses du serveur au client 1]
Die mit <-- beginnenden Zeilen sind diejenigen, die vom Client an den Server gesendet wurden. Die Zeilen N: sind die Zeilen, die vom Server an den Client Nr. N gesendet wurden. Der oben genannte Server ist noch aktiv, während Client 1 beendet wurde. Wir starten einen zweiten Client für denselben Server:
Dos> java clientTCPgenerique localhost 100
Commandes :
commande 3 du client 2
<-- réponse 3 au client 2
fin
L'erreur suivante s'est produite : Impossible de lire les données de la connexion de transport.
[fin du thread de lecture des réponses du serveur]
[fin du thread d'envoi des commandes au serveur]
Das Serverfenster sieht dann wie folgt aus:
Dos> java serveurTCPgenerique 100
Serveur générique lancé sur le port 100
Thread de lecture des réponses du serveur au client 1 lancé
1 : Thread de lecture des demandes du client 1 lancé
<-- commande 1 du client 1
réponse 1 au client 1
1 : <-- commande 2 du client 1
réponse 2 au client 1
1 : [fin du Thread de lecture des demandes du client 1]
fin
[fin du Thread de lecture des réponses du serveur au client 1]
Thread de lecture des réponses du serveur au client 2 lancé
2 : Thread de lecture des demandes du client 2 lancé
<-- commande 3 du client 2
réponse 3 au client 2
2 : [fin du Thread de lecture des demandes du client 2]
fin
[fin du Thread de lecture des réponses du serveur au client 2]
^C
Simulieren wir nun einen Webserver, indem wir unseren generischen Server auf Port 88 starten:
Dos> java serveurTCPgenerique 88
Serveur générique lancé sur le port 88
Öffnen wir nun einen Browser und rufen wir die Seite URL http://localhost:88/exemple.html auf. Der Browser stellt dann eine Verbindung zum Port 88 des Rechners localhost her und fordert anschließend die Seite /exemple.html an:

Sehen wir uns nun das Fenster unseres Servers an:
Dos>java serveurTCPgenerique 88
Serveur générique lancé sur le port 88
Thread de lecture des réponses du serveur au client 2 lancé
2 : Thread de lecture des demandes du client 2 lancé
<-- GET /exemple.html HTTP/1.1
<-- Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/msword, */*
<-- Accept-Language: fr
<-- Accept-Encoding: gzip, deflate
<-- User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; .NET CLR 1.0.3705; .NET CLR 1.0.2
914)
<-- Host: localhost:88
<-- Connection: Keep-Alive
<--
So entdecken wir die vom Browser gesendeten Header HTTP. Dies ermöglicht es uns, das Protokoll HTTP nach und nach zu entschlüsseln. In einem früheren Beispiel hatten wir einen Web-Client erstellt, der lediglich den Befehl GET sendete. Das hatte ausgereicht. Hier sehen wir, dass der Browser weitere Informationen an den Server sendet. Diese dienen dazu, dem Server mitzuteilen, um welche Art von Client es sich handelt. Wir sehen auch, dass die Header HTTP mit einer leeren Zeile enden.
Erstellen wir eine Antwort für unseren Client. Der Benutzer an der Tastatur ist hier der eigentliche Server und kann eine Antwort manuell erstellen. Erinnern wir uns an die Antwort eines Webservers aus einem früheren Beispiel:
<-- HTTP/1.1 200 OK
<-- Date: Mon, 13 May 2002 07:30:58 GMT
<-- Server: Apache/1.3.12 (Unix) (Red Hat/Linux) PHP/3.0.15 mod_perl/1.21
<-- Last-Modified: Wed, 06 Feb 2002 09:00:58 GMT
<-- ETag: "23432-2bf3-3c60f0ca"
<-- Accept-Ranges: bytes
<-- Content-Length: 11251
<-- Connection: close
<-- Content-Type: text/html
<--
<-- <html>
Versuchen wir, eine ähnliche Antwort zu geben:
...
<-- Host: localhost:88
<-- Connection: Keep-Alive
<--
2 : HTTP/1.1 200 OK
2 : Server: serveur tcp generique
2 : Connection: close
2 : Content-Type: text/html
2 :
2 : <html>
2 : <head><title>Serveur generique</title></head>
2 : <body>
2 : <center>
2 : <h2>Reponse du serveur generique</h2>
2 : </center>
2 : </body>
2 : </html>
2 : fin
L'erreur suivante s'est produite : Impossible de lire les données de la connexion de transport.
[fin du Thread de lecture des demandes du client 2]
[fin du Thread de lecture des réponses du serveur au client 2]
Zeilen, die mit „2:“ beginnen, werden vom Server an Client Nr. 2 gesendet. Der Befehl fin beendet die Verbindung vom Server zum Client. Wir haben uns in unserer Antwort auf die folgenden HTTP-Header beschränkt:
HTTP/1.1 200 OK
2 : Server: serveur tcp generique
2 : Connection: close
2 : Content-Type: text/html
2 :
Wir geben die Größe der Datei, die wir senden werden (Content-Length), nicht an, sondern geben lediglich an, dass wir die Verbindung (Connection: close) nach dem Senden dieser Datei schließen werden. Das reicht für den Browser aus. Sobald der Browser sieht, dass die Verbindung geschlossen wurde, weiß er, dass die Antwort des Servers abgeschlossen ist, und zeigt die Seite HTML an, die ihm gesendet wurde. Diese lautet wie folgt:
2 : <html>
2 : <head><title>Serveur generique</title></head>
2 : <body>
2 : <center>
2 : <h2>Reponse du serveur generique</h2>
2 : </center>
2 : </body>
2 : </html>
Der Benutzer beendet anschließend die Verbindung zum Client, indem er den Befehl fin eingibt. Der Browser erkennt daraufhin, dass die Antwort des Servers abgeschlossen ist, und kann sie nun anzeigen:

Wenn man oben den Befehl View/Source eingibt, um zu sehen, was der Browser empfangen hat, erhält man:

Das ist genau das, was vom generischen Server gesendet wurde.
Der Code des generischen TCP-Servers lautet wie folgt:
// Pakete
import java.io.*;
import java.net.*;
public class serveurTCPgenerique{
// Hauptprogramm
public static void main (String[] args){
// empfängt über den Listening-Port Anfragen von Clients
// erstellt einen Thread zum Lesen der Client-Anfragen
// diese werden auf dem Bildschirm angezeigt
// erstellt einen Thread zum Einlesen von über die Tastatur eingegebenen Befehlen
// Diese werden als Antwort an den Kunden gesendet
// Das Ganze endet mit dem über die Tastatur eingegebenen Befehl „end“
final String syntaxe="Syntaxe : pg port";
// Instanzvariable
// Gibt es ein Argument?
if(args.length != 1)
erreur(syntaxe,1);
// Der Port muss eine ganze Zahl > 0 sein
int port=0;
boolean erreurPort=false;
Exception E=null;
try{
port=Integer.parseInt(args[0]);
}catch(Exception e){
E=e;
erreurPort=true;
}
erreurPort=erreurPort || port <=0;
if(erreurPort)
erreur(syntaxe+"\n"+"Port incorrect ("+E+")",2);
// Der Listening-Dienst wird erstellt
ServerSocket ecoute=null;
int nbClients=0; // Anzahl der bedienten Clients
try{
// Der Dienst wird erstellt
ecoute=new ServerSocket(port);
// Weiterverfolgung
System.out.println("Serveur générique lancé sur le port " + port);
// Schleife für die Kundenbetreuung
Socket client=null;
while (true){ // Endlosschleife – wird mit Strg+C beendet
// Warten auf einen Client
client=ecoute.accept();
// Der Dienst wird von separaten Threads ausgeführt
nbClients++;
// Lese-/Schreib-Threads werden erstellt
new ServeurSend(client,nbClients).start();
new ServeurReceive(client,nbClients).start();
// Es wird wieder auf Anfragen gewartet
}// Ende der while-Schleife
}catch(Exception ex){
// Der Fehler wird gemeldet
erreur("L'erreur suivante s'est produite : " + ex.getMessage(),3);
}//catch
}// Ende von „main“
// Anzeige der Fehler
public static void erreur(String msg, int exitCode){
// Fehleranzeige
System.err.println(msg);
// Beenden mit Fehler
System.exit(exitCode);
}//Fehler
}//Klasse
class ServeurSend extends Thread{
// Klasse zum Einlesen von über die Tastatur eingegebenen Antworten
// und diese über einen an den Konstruktor übergebenen TCP-Client an einen Client zu senden
Socket client; // der TCP-Client
int numClient; // Client-Nr.
// Konstruktor
public ServeurSend(Socket client, int numClient){
// wird der TCP-Client notiert
this.client=client;
// sowie dessen Nummer
this.numClient=numClient;
}//Hersteller
// Run-Methode des Threads
public void run(){
// lokale Daten
PrintWriter OUT=null; // Netzwerk-Schreibstrom
String réponse=null; // von der Tastatur gelesene Antwort
BufferedReader IN=null; // Tastatur-Datenstrom
// Überwachung
System.out.println("Thread de lecture des réponses du serveur au client "+ numClient + " lancé");
// Fehlerbehandlung
try{
// Erstellung des Netzwerk-Schreibstroms
OUT=new PrintWriter(client.getOutputStream(),true);
// Erstellung des Tastatur-Datenstroms
IN=new BufferedReader(new InputStreamReader(System.in));
// Schleife „Befehlseingabe und -übertragung“
while(true){
// Kundenidentifikation
System.out.print("--> " + numClient + " : ");
// Auslesen der über die Tastatur eingegebenen Antwort
réponse=IN.readLine().trim();
// Fertig?
if (réponse.toLowerCase().equals("fin")) break;
// Antwort an den Server senden
OUT.println(réponse);
// Nächste Antwort
}//while
}catch(Exception ex){
// Fehler
System.err.println("L'erreur suivante s'est produite : " + ex.getMessage());
}//catch
// Ende – Streams werden geschlossen
try{
OUT.close();client.close();
}catch(Exception ex){}
// das Ende des Threads wird gemeldet
System.out.println("[fin du Thread de lecture des réponses du serveur au client "+ numClient+ "]");
}//run
}//Klasse
class ServeurReceive extends Thread{
// Klasse, die für das Einlesen der an den Server gesendeten Textzeilen zuständig ist
// über einen an den Konstruktor übergebenen TCP-Client
Socket client; // der TCP-Client
int numClient; // Client-Nr.
// Konstruktor
public ServeurReceive(Socket client, int numClient){
// der TCP-Client wird notiert
this.client=client;
// sowie dessen Nummer
this.numClient=numClient;
}//Hersteller
// Run-Methode des Threads
public void run(){
// lokale Daten
BufferedReader IN=null; // Netzwerk-Lese-Stream
String réponse=null; // Serverantwort
// Nachverfolgung
System.out.println("Thread de lecture des demandes du client "+ numClient + " lancé");
// Fehlerbehandlung
try{
// Erstellung des Netzwerk-Lesestreams
IN=new BufferedReader(new InputStreamReader(client.getInputStream()));
// Schleife zum Einlesen der Textzeilen aus dem Datenstrom IN
while(true){
// Netzwerk-Stream lesen
réponse=IN.readLine();
// Datenstrom geschlossen?
if(réponse==null) break;
// Anzeige
System.out.println("<-- "+réponse);
}//while
}catch(Exception ex){
// Fehler
System.err.println("L'erreur suivante s'est produite : " + ex.getMessage());
}//catch
// Ende – die Datenströme werden geschlossen
try{
IN.close();client.close();
}catch(Exception ex){}
// das Ende des Threads wird gemeldet
System.out.println("[fin du Thread de lecture des demandes du client "+ numClient+"]");
}//run
}//Klasse
8.3. JAVASCRIPT
In diesem Abschnitt zeigen wir drei Beispiele für die Verwendung von JavaScript auf den Seiten WEB. Wir konzentrieren uns dabei auf die Formularverwaltung, doch JavaScript kann noch viel mehr.
8.3.1. Daten aus einem Formular abrufen
Das folgende Beispiel zeigt, wie die vom Benutzer in ein Formular eingegebenen Daten im Browser abgerufen werden können. Dies ermöglicht in der Regel eine Vorverarbeitung, bevor die Daten an den Server gesendet werden.
8.3.1.1. Das Formular
Wir haben ein Formular, das die gängigsten Komponenten enthält, sowie eine Schaltfläche „Anzeigen“, mit der die vom Benutzer vorgenommenen Eingaben angezeigt werden können.

8.3.1.2. Der Code
<html>
<head>
<title>Un formulaire traité par Javascript</title>
<script language="javascript">
function afficher(){
// zeigt die Formularinformationen in einer Liste an
// zuerst löschen
effacerInfos();
// man zeigt den Wert der # Felder an
with(document.frmExemple){
// verstecktes Feld
ecrire("champ caché="+cache.value);
// einfaches Textfeld
ecrire("champ textuel simple="+simple.value);
// Mehrfachtextfeld
ecrire("champ textuel multiple="+lignes.value);
// Optionsfelder
for(i=0;i<radio.length;i++){
texte="radio["+i+"]="+radio[i].value;
if(radio[i].checked) texte+=", coché";
ecrire(texte);
}//for
// Kontrollkästchen
for(i=0;i<qcm.length;i++){
texte="qcm["+i+"]="+qcm[i].value;
if(qcm[i].checked) texte+=", coché";
ecrire(texte);
}//für
//Dropdown-Liste
ecrire("index sélectionné dans le menu="+menu.selectedIndex);
for(i=0;i<menu.length;i++){
texte="menu["+i+"]="+menu.options[i].text;
if(menu.options[i].selected) texte+=",sélectionné";
ecrire(texte);
}//für
//Mehrfachauswahlliste
for(i=0;i<lstVoitures.length;i++){
texte="lstVoitures["+i+"]="+lstVoitures.options[i].text;
if(lstVoitures.options[i].selected) texte+=",sélectionné";
ecrire(texte);
}//für
//Passwort
ecrire("mot de passe="+passwd.value);
}//mit
}//Funktion
function ecrire(texte){
// schreibt Text in die Informationsliste
frmInfos.lstInfos.options[frmInfos.lstInfos.length]=new Option(texte);
}//schreiben
function effacerInfos(){
frmInfos.lstInfos.length=0;
}//effacerInfos
</script>
</head>
<body bgcolor="#C0C0C0" onload="afficher()">
<center>
<h2>Un formulaire traité par Javascript</h2>
<hr>
<form method="POST" name="frmExemple">
<input type="hidden" name="cache" value="secret">
<table border="0">
<tr>
<td align="center">Un champ textuel simple</td>
<td align="center" width="100"> </td>
<td align="center">Un champ textuel sur plusieurs lignes</td>
</tr>
<tr>
<td align="center"><input type="text" size="20" name="simple"></td>
<td align="center" width="100"> </td>
<td align="center">
<textarea name="lignes" rows="2" cols="40">Ce texte est modifiable</textarea>
</td>
</tr>
</table>
<table border="0">
<tr>
<td><strong>Des boutons radio :</strong></td>
<td>
<input type="radio" checked name="radio" value="FM">FM
</td>
<td>
<input type="radio" name="radio" value="GO">GO
</td>
<td>
<input type="radio" name="radio" value="PO">PO
</td>
<td> </td>
<td><strong>Des choix multiples :</strong></td>
<td>
<input type="checkbox" name="qcm" value="un">un
</td>
<td>
<input type="checkbox" name="qcm" value="deux">deux
</td>
<td>
<input type="checkbox" name="qcm" value="trois">trois
</td>
</tr>
</table>
<table border="0">
<tr>
<td>Un menu déroulant : </td>
<td>
<select name="menu" size="1">
<option>50 F</option>
<option>60 F</option>
<option>70 F</option>
<option>100 F</option>
</select>
</td>
<td>Une liste :</td>
<td>
<select name="lstVoitures" multiple size="3">
<option>Renault</option>
<option>Citroën</option>
<option>Peugeot</option>
<option>Fiat</option>
<option>Audi</option>
</select>
</td>
</tr>
</table>
<table border="0">
<tr>
<td>Un mot de passe : </td>
<td><input type="password" size="21" name="passwd"></td>
<td> </td>
<td>Un champ de contexte caché : </td>
</tr>
</table>
</form>
<hr>
<h2>Informations du formulaire</h2>
<form name="frmInfos">
<table>
<tr>
<td><input type="button" value="Effacer" onclick="effacerInfos()"></td>
<td>
<select name="lstInfos" multiple size="3">
</select>
</td>
<td>
<input type="button" name="cmdAfficher" value="Afficher" onclick="afficher()">
</td>
</tr>
</form>
</body>
</html>
8.3.2. Reguläre Ausdrücke in JavaScript
Auf der Browserseite kann JavaScript verwendet werden, um die Gültigkeit der vom Benutzer eingegebenen Daten zu überprüfen, bevor diese an den Server gesendet werden. Hier ist ein Programm zum Testen dieser regulären Ausdrücke.
8.3.2.1. Die Testseite

8.3.2.2. Der Code der Seite
<html>
<head>
<title>Les expressions régulières en Javascript</title>
<script language="javascript">
function afficherInfos(){
with(document.frmRegExp){
// Gibt es etwas zu tun?
if (! verifier()) return;
// Alles klar – die vorherigen Ergebnisse werden gelöscht
effacerInfos();
// Überprüfung der Vorlage
modele=new RegExp(txtModele.value);
champs=modele.exec(txtChaine.value);
if(champs==null)
// Keine Übereinstimmung zwischen Muster und Zeichenfolge
ecrireInfos("pas de correspondance");
else{
// Übereinstimmung – die Ergebnisse werden angezeigt
ecrireInfos("Il y a correspondance");
for(i=0;i<champs.length;i++)
ecrireInfos("champs["+i+"]=["+champs[i]+"]");
}//sonst
}//mit
}//Funktion
function ecrireInfos(texte){
// schreibt Text in die Informationsliste
document.frmRegExp.lstInfos.options[document.frmRegExp.lstInfos.length]=new Option(texte);
}//schreiben
function effacerInfos(){
frmRegExp.lstInfos.length=0;
}//effacerInfos
function jouer(){
// prüft die Vorlage anhand der Zeichenfolge im ausgewählten Beispiel
with(document.frmRegExp){
txtModele.value=lstModeles.options[lstModeles.selectedIndex].text
txtChaine.value=lstChaines.options[lstChaines.selectedIndex].text
afficherInfos();
}//mit
}//abspielen
function ajouter(){
//fügt den aktuellen Test zu den Beispielen hinzu
with(document.frmRegExp){
// Gibt es etwas zu tun?
if (! verifier()) return;
// Hinzufügen
lstModeles.options[lstModeles.length]=new Option(txtModele.value);
lstChaines.options[lstChaines.length]=new Option(txtChaine.value);
// Eingaben löschen
txtModele.value="";
txtChaine.value="";
}//mit
}//hinzufügen
function verifier(){
// Prüft, ob die Eingabefelder nicht leer sind
with(document.frmRegExp){
champs=/^\s*$/.exec(txtModele.value);
if(champs!=null){
alert("Vous n'avez pas indiqué de modèle");
txtModele.focus();
return false;
}//if
champs=/^\s*$/.exec(txtChaine.value);
if(champs!=null){
alert("Vous n'avez pas indiqué de chaîne de test");
txtChaine.focus();
return false;
}//wenn
// alles in Ordnung
return true;
}//mit
}//prüfen
</script>
</head>
<body bgcolor="#C0C0C0">
<center>
<h2>Les expressions régulières en Javascript</h2>
<hr>
<form name="frmRegExp">
<table>
<tr>
<td>Expression régulière</td>
<td>Chaîne de test</td>
</tr>
<tr>
<td><input type="text" name="txtModele" size="20"></td>
<td><input type="text" name="txtChaine" size="20"></td>
</tr>
<tr>
<td>
<input type="button" name="cmdAfficher" value="Jouer le test" onclick="afficherInfos()">
</td>
<td>
<input type="button" name="cmdAjouter" value="Ajouter aux exemples" onclick="ajouter()">
</td>
</tr>
</table>
<hr>
<h2>Résultats de l'instruction champs=expression régulière.exec(chaine)</h2>
<table>
<tr>
<td>
<select name="lstInfos" size="3">
</select>
</td>
</tr>
</table>
<hr>
<h2>Exemples</h2>
<table>
<tr>
<td align="center">Modèles</td>
<td align="center">Chaînes</td>
</tr>
<tr>
<td>
<select name="lstModeles" size="1">
<option>^\d+$</option>
<option>^(\d+) (\d+)$</option>
<option>^(\d+)(.*)(\d+)$</option>
<option>^(\d+)(\s+)(\d+)$</option>
</select>
</td>
<td>
<select name="lstChaines" size="1">
<option>67</option>
<option>56 84</option>
<option>45abcd67</option>
<option>45 67</option>
</select>
</td>
<td>
<input type="button" name="cmdJouer" value="Jouer l'exemple" onclick="jouer()">
</td>
</tr>
</form>
</body>
</html>
8.3.3. Listenverwaltung in JavaScript
8.3.3.1. Das Formular

8.3.3.2. Der Code
<html>
<head>
<title>Les listes en Javascript</title>
<script language="javascript">
// hinzufügen
function ajouter(L1,L2,T){
// fügt den Wert des Feldes T zu den Listen L1 und L2 hinzu
// Muss etwas unternommen werden?
champs=/^\s*$/.exec(T.value);
if(champs!=null){
// Das Feld ist leer
alert("Vous n'avez pas indiqué la valeur à ajouter");
txtElement.focus();
return;
}//if
// wird das Element hinzugefügt
L1.options[L1.length]=new Option(T.value);
L2.options[L2.length]=new Option(T.value);
T.value="";
}//Hinzufügen
//leeren
function vider(L){
// leert die Liste L
L.length=0;
}//leeren
//übertragen
function transfert(L1,L2,simple){
//überträgt die in der Liste L1 ausgewählten Elemente in L2
// Muss etwas getan werden?
// Index des in L1 ausgewählten Elements
index1=L1.selectedIndex;
if(index1==-1){
alert("Vous n'avez pas sélectionné d'élément");
return;
}//if
// Wie erfolgt die Auswahl der Elemente aus den Listen?
if(simple){ // Einfache Auswahl
element1=L1.options[index1].text;
//Hinzufügen in L2
L2.options[L2.length]=new Option(element1);
//Löschen in L1
L1.options[index1]=null;
}//einfach
if(! simple){ //Mehrfachauswahl
//Liste 1 in umgekehrter Reihenfolge durchlaufen
for(i=L1.length-1;i>=0;i--){
//Element ausgewählt?
if(L1.options[i].selected){
//wird zu L2 hinzugefügt
L2.options[L2.length]=new Option(L1.options[i].text);
//aus L1 entfernen
L1.options[i]=null;
}//if
}//für i
}//if ! einfach
}//Übertragung
</script>
</head>
<body bgcolor="#C0C0C0">
<center>
<h2>Les listes en Javascript</h2>
<hr>
<form name="frmListes">
<table>
<tr>
<td>
<input type="button" name="cmdAjouter" value="Ajouter" onclick="ajouter(lst1A,lst1B,txtElement)">
</td>
<td>
<input type="text" name="txtElement">
</td>
</tr>
</table>
<table>
<tr>
<td align="center">liste 1</td>
<td align="center"><input type="button" value=">>" onclick="transfert(lst1A,lst2A,true)"</td>
<td align="center"><input type="button" value="<<" onclick="transfert(lst2A,lst1A,true)"</td>
<td align="center">liste 2</td>
<td width="30"></td>
<td align="center">liste 1</td>
<td align="center"><input type="button" value=">>" onclick="transfert(lst1B,lst2B,false)"</td>
<td align="center"><input type="button" value="<<" onclick="transfert(lst2B,lst1B,false)"</td>
<td align="center">liste 2</td>
</tr>
<tr>
<td></td>
<td align="center">
<select name="lst1A" size="5">
</select>
</td>
<td align="center">
<select name="lst2A" size="5">
</select>
</td>
<td></td>
<td></td>
<td></td>
<td align="center">
<select name="lst1B" size="5" multiple >
</select>
</td>
<td align="center">
<select name="lst2B" size="5" multiple>
</select>
</td>
</tr>
<tr>
<td></td>
<td align="center"><input type="button" value="Vider" onclick="vider(lst1A)"</td>
<td align="center"><input type="button" value="Vider" onclick="vider(lst2A)"</td>
<td></td>
<td></td>
<td></td>
<td align="center"><input type="button" value="Vider" onclick="vider(lst1B)"</td>
<td align="center"><input type="button" value="Vider" onclick="vider(lst2B)"</td>
<td></td>
</tr>
<tr>
<td></td>
<td colspan="2"><strong>Sélection simple</strong></td>
<td></td>
<td></td>
<td></td>
<td colspan="2"><strong>Sélection multiple</strong></td>
<td></td>
</tr>
</table>
<hr>
</form>
</body>
</html>


