Exercices

Lire le contenu d’une URL contenant du texte

Reprendre l’interface graphique Question-Réponse et lui associer le comportement suivant :

  • l’utilisateur saisit une chaîne de caractère

  • cette chaine doit représenter une URL (voir constructeur java.net.URL utilisé dans un exercice précédent) ouvrir un Stream avec la méthode openStream() et si cette ouverture réussit lire le contenu et l’afficher

  • par facilité on ne tiendra pas compte du mode de codage caractère (donc le mode de codage local par défaut sera suffisant -bien qu’en pratique cela ne soit pas vrai!-).

Pour réaliser correctement l’exercice nous vous conseillons les étapes suivantes:

  • Rechercher dans la documentation la méthode qui permet de lire un texte ligne à ligne.

  • Tenter d’ouvrir le flot , lire la première ligne et l’afficher

  • Lire toutes les lignes et les afficher

Note

Si vous êtes derrière un proxy utilisez les "propriétés" suivantes passées à la machine virtuelle : java -Dhttp.proxyHost=hote -D http.proxyPort=port TestURL. (on peut également avoir besoin des propriétés http.proxyUser et http.proxyPassword.).

Une autre possibilité est d’avoir un système qui donne la configuration du proxy (ProxySelector) dans ce cas utiliser la propriété: -Djava.net.useSystemProxies

Vous pouvez:

  • passer ces propriétés comme argument de lancement

  • fixer ces propriétés dans votre code par System.setProperty

  • fixer ces propriétés dans jre/libs/net.properties

Lecture des données d’un catalogue dans un fichier texte

Exercice d’approfondissement: créer un catalogue (de Vehicules ou de Livres) dont les éléments sont lus dans un fichier texte.

Pour simplifier on supposera que ce fichier texte se trouve dans le répertoire courant (dans la réalité il s’agira d’une "ressource").

Chaque article sera décrit sur une ligne et il faudra "éclater" chacun des éléments de la ligne pour retrouver les données de construction de l’objet.

Dans un premier temps on pourra explorer les codes java.util.StringTokenizer, ou la méthode split de String ou les objets Scanner.

On pourra ensuite utiliser des descriptions sur plusieurs lignes et ultérieurement s’intéresser aux formats XML, JSON et YAML (et aux codes spécialisés dans la lecture de ces formats).

Lire le contenu d’une URL contenant du texte

package org.labs.io;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import org.labs.ihm.Repondeur;


public class RepondeurURL implements Repondeur {

    // peut être reécrite avec des try et AutoCloseable!
    @Override
    public String repondA(String question) throws Exception {
        URL url = new URL(question);
        InputStream is = url.openStream();
        BufferedReader bufr= new BufferedReader(new InputStreamReader(is));
        StringBuilder build = new StringBuilder() ;
        String ligne;
       while( null != (ligne = bufr.readLine())) {
          build.append(ligne).append('\n') ;
       }
       try{bufr.close();} catch(Exception e) { /* rapport */}
       return build.toString() ;
    }

}
package org.labs.io;

/**
 * Le répondeurURL est en fait limite par rapport au modèle du Répondeur.
 *
 * On accumule dans un Buffer ce que l'on lit et ici le modèle "synchrone"
 * avec accumulation de données en mémoire peut ne plus être adapté.
 *
 * Imaginons par exemple le modèle du Répondeur utilisé pour lire des requêtes
 * SQL: si la requête SQL est erronée et produit des milliers de réponses:
 *  - l'utilisateur va attendre longtemps
 *  - et la mémoire va souffrir!
 *
 * Il serait plus pertinent d'imaginer une interfaces graphique "paginée"
 * dans laquelle l'utilisateur lirait les résultats par blocs de X
 * (et s'il souhaire abandonne sa lecture les résultat suivants ne sont pas "lus")
 *
 * Plusieur modèles peuvent répondre à ce besoin: à la base ce sont des variations
 * sur la notion d'itérateur. on pourrait donc avoir un modèle défini comme
 *
 *   public interface Repondant {
 *      Iterator<String> repondA(String question) throws Exception
 * }
 *
 * L'interface RepondeurRequete est une généralisation ....
 * mais d'autres types paramétrés plus sophistiqués sont possibles
 * comme :
 *  X requete(Requete<X> req)
 *  et dans de futures version de Java l'Exception pourrait être elle même
 * paramétrée ....
 *
 * TRES IMPORTANT:
 * Une solution plus standard s'appuierai sur les interfaces associée à
 * java.util.concurent.Flow que nous verrons plus tard
 * (principe des "reactive streams")
 */
public interface RepondeurRequete<X> {
    X requete(String req) throws Exception ;
}