7 Cours ENPC, printemps 2001
Java, objets, interfaces et Internet

Le Web

Le World Wide Web est un système d'information hypermédia distribué multiprotocole.

Un système d'information multimédia est composé de plusieurs formats de données : texte, son, image fixes ou animées, bases de données. Un système d'information hypermédia est un ensemble de documents multimédias organisé pour pouvoir naviguer d'un document à un autre par un simple pointage sur une partie d'un document (en général avec une souris).

Le caractère distribué signifie qu'un ensemble de documents peut être réparti physiquement sur plusieurs machines, dites serveuses.

Le Web est un système multiprotocole dans la mesure où il intègre le protocole HTTP et d'autres protocoles d'application (FTP, Gopher, Telnet, Wais, etc).

Un document WWW est composé de pages HTML (Hyper Text Marking Language) et d'autres documents non-textuels.

[Manuel de référence HTML]

La visualisation d'un document Web, et la navigation d'un document à un autre se fait à l'aide d'un programme appelé navigateur comme Netscape, MS Explorer ou Lynx. Le navigateur communique avec d'autres programmes, dits serveurs, qui résident sur les machines serveuses.

[W3 Consortium]

Désignation des documents Web par leur URL

Un Uniform Resource Locator (URL) permet de désigner un document accessible sur le WWW ; il est composé de plusieurs parties :

  • le protocole d'accès : les plus utiles sont http, ftp, telnet, file
  • le chemin d'accès à cette ressource, spécifié par le chemin d'accès à la machine serveuse, éventuellement le port, et le chemin d'accès au document sur cette serveuse

Par exemple http://cermics.enpc.fr/cours/java/index.html désigne un document accessible par le protocole http sur la machine cermics.enpc.fr, dans le fichier de chemin /cours/java/index.html ; ce chemin est relatif à un répertoire particulier, appelé racine WWW du serveur, où sont regroupés les documents WWW publics sur cette machine.

Les URL sont représentées par la classe URL du paquet java.net dont les méthodes et constructeurs peuvent déclencher l'exception MalformedURLException :


import java.net.URL;
...
  URL u1 = new URL("http://cermics.enpc.fr/cours/java/index.html");
  URL u2 = new URL("http", "cermics.enpc.fr", "/cours/java/index.html");
  URL u3 = new URL(u1, "eleves.html");

Acquisition d'un document Web

Il suffit de connecter un flot d'entrée à une ressource Web spécifiée par son URL. Ce flot est obtenu par la méthode openStream() invoquée sur l'objet URL.

[notes 6]

Code mobile

Java a été conçue de manière à permettre la mobilité du code à travers le Web : une classe peut être chargée depuis une machine distante, à travers le Web, et exécutée localement, à l'intérieur d'un navigateur. Ces classes forment des applettes.

Une applette est incluse dans une page HTML par le marquage <APPLET> (dans la future version HTML 4, ce marquage sera remplacé par le marquage plus général <OBJECT>). Si le code doit être chargé à partir du même répertoire que le document, on écrira :

<APPLET
  CODE="ButtonDemo.class"
  WIDTH=500
  HEIGHT=500
  ALIGN=right
  NAME="bouton">
  Texte qui est affiché par un navigateur ignorant les applettes
</APPLET>

Si le code se trouve dans un autre répertoire :

<APPLET
  CODEBASE="http://cermics.enpc.fr/cours/java/applets/"
  CODE="ButtonDemo.class"
  WIDTH="500"
  HEIGHT="500">
  Texte qui est affiché par un navigateur ignorant les applettes
</APPLET>

Les applettes

Une applette doit être définie comme un objet d'une classe publique dérivée de la classe Applet, définie dans le paquet java.applet. La classe Applet dérive de Panel :

Applet -> Panel -> Container -> Component -> Object

Cette classe définit une vingtaine de méthodes qu'une classe dérivée peut redéfinir. Les méthodes les plus importantes, qui par défaut, ne font rien, sont init(), start(), stop() et destroy(). Celles-ci ne sont normalement pas appelées à partir des autres méthodes définies par l'utilisateur, de façon analogue aux méthodes de traitement d'événement (actionPerformed, mouseClicked, etc). Elles spécifient ce qui doit être exécuté quand un certain événement est reçu :

  • La méthode init() est appelée quand l'applette est chargée dans le navigateur
  • La méthode start() est appelée par le navigateur à chaque fois qu'il affiche la page contenant l'applette
  • La méthode stop() est appelée quand le navigateur quitte la page
  • La méthode destroy() est appelée avant le déchargement de l'applette par le navigateur

[Voir le source]

Ces quatre méthodes sont appelées par un thread, distinct des autres threads s'exécutant déjà dans le navigateur, et dédié à cette applette (son comportement n'est pas toujours celui attendu) . La définition de la classe dérivée a la forme :

import java.applet.Applet;

public class A extends Applet {
 public void init() { ... }
 public void start() { ... }
 public void stop() { ... }
 public void destroy() { ... }
}

Les classes d'applette ne comportent en général pas de constructeur ; les initialisations qui figurent normalement dans un constructeur doivent être placées dans la méthode init(). Il est fréquent que les trois dernières méthodes ne soient pas redéfinies.

Trois autres méthodes, héritées de la classe Component, sont essentielles à la visualisation de l'applette :

 public void repaint() { ... }
 public void update(Graphics g) { ... }
 public void paint(Graphics g) { ... }

Le fonctionnement de ces trois méthodes se comprend aussi en termes d'événements. Une invocation de la méthode repaint() exprime l'émission d'un événement "cette composante doit être repeinte". Le traitement de ces événements est délégué à un thread spécialisé, qui invoque la méthode update(Graphics) de la composante. Celle-ci commence par effacer (en repeignant le fond), puis invoque la méthode paint(Graphics) (celle-ci est aussi invoquée initialement). La méthode paint(Graphics) joue le même rôle que les méthodes de traitement d'événement comme actionPerformed, mouseClicked, etc : elle dit ce qui doit être exécuté (après l'effacement) quand l'événement "cette composante doit être repeinte" est émis : instructions de tracé, etc. Un tel événement est aussi émis quand un réaffichage de la page est rendu nécessaire, par exemple à cause du masquage par une autre fenêtre.

Pour éviter l'effet de "flash" dû à l'effacement à chaque invocation de repaint(), il suffit de redéfinir update(Graphics) ainsi :

 public void update(Graphics g) {
   paint(g);
 }

La méthode repaint(int x, int y, int width, int height) permet de repeindre seulement le rectangle spécifié par ses arguments. Les méthodes repaint sont invoquées, soit par le programme (par exemple pour réaliser une animation), soit par l'environnement, pour un réaffichage de l'applette (si la fenêtre du navigateur a cessé d'être visible, etc).

Les dimensions de l'applette sont définies dans le marquage HTML <APPLET>, par ses attributs oligatoires WIDTH et HEIGHT. Ces dimensions peuvent être obtenues par la méthode getSize() de la classe Component, qui retourne un objet de type Dimension, qui a les deux champs width et height.

Paramètres d'une applette

Une applette reçoit les paramètres spécifiés par le marquage HTML <PARAM> à l'aide de la méthode getParameter(), qui est appelée à l'intérieur de init(). Par exemple, au marquage HTML

<APPLET ...>
<PARAM NAME=vitesse VALUE=100>
</APPLET>

correspond la définition, en Java, d'une variable de type String :

 String vs = getParameter("vitesse");

qui sera probablement convertie en un nombre entier avant d'être utilisée par init(), à l'aide de parseInt(String). Il est bon de prévoir des valeurs par défaut si le fichier HTML ne définit pas la valeur d'un paramètre :

 int v = (vs == null) ? 100 : parseInt(v);

Applette ou application ?

Ces deux alternatives ne sont pas incompatibles. Pour qu'une applette se comporte comme une application standard, il suffit d'ajouter à la classe (disons MonApplet) qui étend Applet une méthode main() définie schématiquement ainsi
public class MonApplet extends Applet {

public void init() { ... }

public void start() { ... }

 ...

public static void main(String args[]) {
    MonApplet applet = new MonApplet();
    Frame appletFrame = new Frame();

    applet.init();
    applet.start(); /* s'il y a lieu */
    appletFrame.add(applet);
    appletFrame.setSize(appletWidth,appletHeight);
    appletFrame.setVisible(true);
  }
}
où le paramètre appletWidth (resp. appletHeight) sera remplacé par la valeur de l'attribut width (resp. height) de la balise <APPLET> qui demande le chargement de MonApplet. La transformation inverse (d'une application vers une applette) est moins systématique. Il faut se rappeler que la méthode main() n'est pas appelée par une applette et qu'il convient donc d'en répartir le code entre les méthodes init et start. Il peut être nécessaire de supprimer la fenêtre principale (Frame) de l'application puisqu'une applette est, en général, affichée directement dans la fenêtre du browser.

Le contexte d'une applette

La classe AppletContext permet d'accéder à l'environnement d'exécution d'une applette, en particulier au navigateur, au document qui contient l'applette, aux autres applettes de ce document, etc.

On peut par exemple accéder à d'autres documents sur le même serveur ; voici comment donner une URL relative :

import java.net.*;

   try {
     getAppletContext().showDocument(new URL(getCodeBase(), 
                                             "eleves.html"));
   }
   catch (MalformedURLException e) {}

La méthode getAppletContext() renvoie le contexte d'exécution de l'applette. La méthode getCodeBase() donne l'URL de l'applette (l'unité objet en .class) ; il y a aussi une méthode getDocumentBase() qui renvoie l'URL du document HTML qui contient l'applette. On ne peut appeler ces méthodes que quand l'applette a été initialisée. La méthode showDocument(URL) permet d'afficher dans le navigateur un document spécifié par son URL.


[Cours Java] [Notes 6] [Notes 7bis]

Mise à jour :