un petit annuaire

j'ai crée un petit annuaire : vous pouvez le visiter

2006/1/19

un autre petit tutorial en java

@ 09:18 AM (42 months, 1 day ago)
Programmation de servlets Java
Les servlets sont des programmes écrits en Java qui permettent de traiter et de répondre à des requètes passées la plupart du temps à un serveur web les abritant. Ils peuvent donc être utilisés pour traiter des données issues d'un formulaire au sein d'une page HTML, pour la génération de pages HTML dynamiques en y incluant par exemples des informations issues de base de données. Ils sont donc probablement une réponse pertinente à la croissante complexité des sites web, notamment ceux de commerce éléctronique.
Ce tutorial, loin d'être exhaustif, a pour objectif de présenter de la manière la plus claire possible les fonctions de bases mises à disposition par l'API Servlet.
 
Plan:
Installation
Architecture de base d'un servlet
Exemple: traitement de formulaires
Maintien de sessions
Cookies
Problèmes de threading
JDBC: Java DataBase Connectivity
Servlets et transformations XSLT avec Xalan-J
Un servlet évolué: Cocoon
Upload de fichiers
1 Installation


Les sections suivants supposent que le JDK de SUN, ainsi que Apache 1.2 et spérieur ont été préalablement installé.

1.1 Installation du Kit de Développement de Servlets : le JSDK

La première étape consiste à télécharger le JSDK2.0 sur le site de SUN (ici), le décompresser puis à copier (cp -R) le répertoire JSDK2.0 dans le répertoire de votre choix (on prendra /usr/lib/ pour la suite de ce tutorial). Il faut alors mettre à jour le path en incluant /usr/lib/JSDK2.0/bin (export PATH=/usr/lib/JSDK2.0/bin:$PATH), ainsi que le classpath en y ajoutant le chemin de l'archive jsdk.jar contenant les classes (export CLASSPATH = /usr/lib/JSDK2.0/lib/jsdk.jar :$CLASSPATH sous bash).
Pour vérifier que tout s'est bien déroulé, on lance l'utilitaire servletrunner qui devrait afficher les lignes suivantes :


olly%>servletrunner
servletrunner starting with settings:
port = 8080
backlog = 50
max handlers = 100
timeout = 5000
servlet dir = ./examples
document dir = ./examples
servlet propfile = ./examples/servlet.properties

servletrunner permet de tester les servlets, c'est à dire qu'il va faire office de mini-serveur, écoutant sur un port spécifique (8080 par défaut). Il est possible de modifier les paramètres par défaut de servletrunner, notamment les flags -d suivi du répertoire contenant les servlets, et -s suivi du fichier de propriétés de la zone à considérer.
 

1.2 Installation du module côté serveur : ApacheJserv

La première étape consiste à télécharger le moteur de servlets d'Apache, ApacheJServ, puis à décompresser l'archive quelque part sur le disque, sous /tmp par exemple. Il y a ensuite deux façons de procéder pour rajouter le module mod_jserv. La première consiste à recompiler complètement Apache après lui avoir ajouté le source de mod_jserv. La seconde nécessite une version d'Apache 1.3.*, avec support des Dynamic Shared Objects (DSO) et permet d'ajouter le module mod_jserv de manière dynamique, c'est à dire sans avoir à recompiler Apache. Pour des raisons de temps, seule la deuxième procédure, plus "moderne",  est décrite ici.
Comme pour la plupart des packages fournis sous forme de code source, il est nécessaire dans un premier temps d'éxécuter le script de configuration avec configure. configure s'efforce de deviner le maximum de choses, et si l'ensemble des fichiers sont à leur place habituelle, tout se passeras parfaitement. Pour ma part, voici la ligne de commande que j'ai utilisé (avec succès sous SuSE) :

olly%>./configure -with-jsdk=/usr/lib/JSDK2.0/lib/jsdk.jar  -disable-debugging -with-apache-install=/usr

(La directive -with-apache-install=/usr est nécéssaire sous SuSE (mon cas) car configure croit que apxs est sous apache_dir/sbin/, alos qu'il  est en réalité sous /usr/sbin.)
Lors d'une seconde intallation sous Mandrake 7.0, la commande est devenue :

olly%>./configure --with-apxs=/usr/sbin/apxs --prefix=/usr/lib/jserv --with-jdk-home=/usr/lib/jdk1.2.2 --with-JSDK=/usr/lib/JSDK2.0/lib/jsdk.jar --disable-debugging --with-java-platform=2

olly%>make
olly%>make install
 

1.3 Configuration pour l'éxécution de servlets

L'environnement d'Apache JServ est divisé en zones, totalement indépendantes les unes des autres. Cela permet de séparer les servlets selon le possesseur, le mesures de sécurité désirées, ou encore les ressources allouées.  Toutefois, une unique zone suffit dans la plupart des utilisations.
Apache JServ possède un fichier de configuration nommé jserv.conf qui sert à définir son comportement au regard d'Apache. Le fichier de configuration d'Apache /etc/httpd/httpd.conf doit donc contenir une directive Include permettant d'inclure le fichier jserv.conf en son sein.

Exemple de ligne à inclure dans httpd.conf (après avoir copié le fichier jserv.conf à l'endroit indiqué):
Include /etc/httpd/jserv.conf

Le fichier jserv.conf contient à son tour une directive ApJServProperties /chemin/vers/jserv.properties pointant sur le fichier jserv.properties qui contient les propriétés des diférents servlets utilisés. jserv.properties permet entre autres choses de spécifier le nombre de zones souhaitées, le nom donné à chacune, ainsi que leur emplacement sur le disque.
Par exemple, si l'on souhaite deux zones nommées zone_a et zone_b, le fichier jserv.properties devra contenir les lignes suivantes :



# List of servlet zones Apache JServ manages
zone=zone_a, zone_b

Configuration : plusieurs zones. Chaque zone possède un fichier nom_zone.properties propre, dans lequel est entre autres indiqué le répertoire où trouver les servlets (repositories=/chemin/vers/classes).

Les zones disponibles doivent être indiquées dans le fichier jserv.properties. Les lignes zones=zone1, zone2, ... et le chemin des fichiers de propriété leur correspondant : zone1.properties=/chemin/vers/zone1.properties, zone2.properties=/chemin/vers/zone2.properties, etc..

Une fois JServ configuré, il est nécessaire de relancer Apache, avec une des commandes suivantes: rcapache restart, apachectl restart ou bien kill -NOHUP `cat var/httpd.pid`.
  2 Architecture de base d'un servletAvant de rentre dans les détails, examinons le code d'un servlet avec fonctionnalités minimale.

2.1 Exemple : Hello World!

Ce premier exemple de servlet effectue une tâche toute simple : il crée une page HTML intitulée "mon premier servlet", laquelle affiche simplement "Salut tout le monde".



import javax.servlet.*; //importe le package servlet
import javax.servlet.http.*; //importe servlet.http
import java.io.*; //importe les classes d'entrée-sortie
public class ExempleServlet extends HttpServlet { // ExempleServlet hérite de HttpServlet
    /* surcharge la méthode doGet */
    public void doGet (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        PrintWriter out;
        response.setContentType("text/html");          // then write the data of the response
        out = response.getWriter();
        out.println("<HTML>
                            <HEAD><TITLE> mon premier servlet </TITLE></HEAD>
                           <BODY><P>Salut tout le monde!</BODY></HTML>");
        out.close();
    }
}

Ce servlet hérite donc de la classe HttpServlet, et surcharge la méthode doGet, cette dernière étant appelée lorsqu'un client envoie une requète GET au serveur.

Pour éxécuter ce servlet, il suffit de placer le code compilé (ExempleServlet.class) dans l'un des répertoires correspondant aux zones configurées, par exemple ~/example/ puis d'ouvrir avec un browser l'URL http://localhost/example/ExempleServlet.
 

2.2 Contenu du package javax.servlet

Le coeur du package est la classe Servlet de laquelle tout servlet doit obligatoirement hériter. Un servlet n'utilise pas nécéssairement le protocole HTTP , c'est pourquoi il existe une interface HttpServlet héritant de la classe Servlet. Tous les servlets utilisés avec ApacheJserv devront bien sur hériter de l'interface HttpServlet et surcharger certaines de ses méthodes, par exemple les méthodes doGet ou doPost
Le package Servlet contient également deux classes qui permettent l'interaction avec les clients du serveur web, les classes ServletRequest et ServletResponse. La classe ServletRequest fournit des informations concernant la requète parvenue au serveur, notamment les noms et valeurs des paramêtres passés, l'adresse IP du client, ls cookies et donne également accès via un stream aux données encapsulées dans le corps de requètes HTTP, notamment lors de l'envoi de données au serveur via une méthode POST. La classe ServletResponse fournit des méthodes permettant de répondre aux clients, par exemple une méthode permettant de fixer le type MIME de la réponse, ainsi que des streams via lesquels il est possible d'envoyer des données au client. Les classes HttpServletRequest et HttpServletResponse sont des interfaces qui étendent un peu plus les classes ServletRequest et ServletResponse en permettant l'accès aux caractèristiques spécifiques des headers HTTP.
 
 
  • classe HttpServletRequest
Un objet de cette classe permet d'accéder aux éléments du header HTTP de la requète, tels que les cookies envoyés avec la requète, le type de méthode utilisée, aisni que les noms de paramètres et leur valeur passés avec la requète. La méthode getHeader permet de récupérer tout ou partie du header de la requète HTTP. Par exemple:
String useragent = request.getHeader("user-agent"); 
if (useragent.indexOf("Netscape")) {
   /** instructions éxécutées si le navigateur client est Netscape **/
}


La méthode getParameter retourne une chaîne de caractères contenant la valeur du paramètre passé en argument. Par exemple:
String bookId = request.getParameter("bookid");

Cette instruction stocke dans la variable bookId la valeur du paramètre nommé bookid (getParameter renvoie NULL si le paramètre n'existe pas).
Il est également possible d'obtenir une chaine de caractères unique contenant l'ensemble des paramètres et valeurs grâce à la méthode getQueryString, et de la parser soi-même par la suite.
Lors d'une requète POST, on utilisera pour lire les données contenues dans le corps de la requète la méthode getReader, qui renvoie un BufferedReader (cas de données texte)  ou  la méthode getInputStream qui renvoie un ServletInputStream.(données binaires).
 
  • classe HttpServletResponse
La classe HttpServletResponse fournit deux méthodes permettant de renvoyer des données à l'utilisateur : la méthode getWriter, qui renvoie un objet Writer permet de renvoyer des données de type texte, par exemple le contenu d'une page HTML.  La méthode getOutputStream retourne un ServletOutputStream grâce auquel il est possible de faire parvenir des données binaires au client. Dans les deux cas, il est important de fermer le stream après utilisation afin que le serveur sache que la réponse est complète.

    2.2 Cycle de vie d'un servlet

  • Initialisation
Lorsqu'une requète cliente porte sur un servlet non encore en mémoire, celui-ci est dans un premier temps chargé par le classLoader du moteur Jserv, puis sa méthode init() est appelée. C'est dans cette méthode que doivent donc être placée les commandes gourmandes en ressources ou celles prenant du temps (connection aux bases de données, par exemple). Il est important lorsque l'on surcharge la méthode init() de faire appel à la méthode init de la super classe, ce qui a pour effer de sauver la

Exemple de surcharge de la méthode init() :



public class MonServlet extends HttpServlet {
    public void init(ServletConfig config) throws ServletException {
        super.init(config);
        try {
            Class.forName("xxx");
        }
        catch(java.lang.ClassNotFoundException e) {
            ...
        }
    }
    public void doGet(...) {
    ...
    }
}

  • Fonctionnement
Après initialisation, le servlet est capable de recevoir une requète de la part d'un client. Lorsqu'une requète lui parvient, il appelle alors la méthode service(), qui reconnait le type de la requète HTTP (GET, POST, ...) et la fait parvenir à la méthode conçue pour traiter les requètes de ce même type (doGet(), doPost(), ...)
  • Destruction
Un servlet est normalement gardé en mémoire en prévision d'éxécutions futures, cependant pour des raisons diverses, notamment la configuration de Jserv et l'occupation des ressources, le moteur de servlet peut décider de détruire le servlet en appelant sa méthode destroy(). C'est donc ici que le concepteur de servlets doit inclure des instructions permettant par exemple de sauvegarder des données pour de futures sessions.
  3 Exemple : traitement de formulairesLes formulaires au sein d'une page HTML permettent l'interaction entre client et serveur web. Un formulaire contient généralement plusieurs éléments ou contrôles, comme par exemple des zones de saisie de texte, des boutons, des listes de choix, qu'il appartient à l'utilisateur de remplir, cliquer ou sélectionner selon ses désirs. Chacun des choix de l'utilisateur est stocké dans une paire NAME/VALUE.
Il existe deux méthodes pour faire parvenir les données de l'utilisateur au serveur. La première, dite méthode GET, transmet les données utilisateurs dans le header de la requète, tandis que la seconde, la méthode PUT, les transmet dans le corps de la requète, permettant de transférer des volumes de données beaucoup plus important.

3.1 Méthode GET


 
<form ACTION="/servlets/cherche" METHOD="GET">
<B>Chercher</B>
<input TYPE="text" NAME="query" VALUE="" SIZE=20>
<B>avec</B>
<select NAME="type">
<option VALUE="Google" SELECTED>Google
<option VALUE="Altavista">Altavista
<option VALUE="Metacrawler">Metacrawler
<option VALUE="Dictionnaire">Dictionnaire
</select> 
<input TYPE="submit" VALUE="Now!">
</form>
Chercher avec

Pour traiter une requète GET, il est nécessaire de surcharger la méthode doGet. A l'intérieur de cette méthode, la méthode getParameter permet de récupérer la valeur d'un paramètre passé au servlet avec la requète GET. Par exemple:

String bookId = request.getParameter("bookId"); //permet de récuperer la valeur du paramètre "bookid". La méthode renvoie null si le paramètre n'existe pas. Il est possible d'utiliser cela pour compacter les pages dynamique en un seul servlet:
 



String bookId = request.getParameter("bookId");
if (bookid == null) {

    //affiche le formulaire

} else {

    //traite le formulaire

}



 

3.2 Méthode PUT

La méthode PUT est généralement utilisée pour uploader des fichiers du disque de l'utilisateur vers le serveur. Elle peut par exemple être utilisée pour soumettre des images, ou encore des fichiers contenant des données à analyser par le serveur. 4 Maintien de sessions


HttpSession session = request.getSession(true);

Rien de plus pour l'instant. 5 Cookies


Bien que les classes et méthodes utilsées pour le maintien de session utilisent les cookies sans que l'on ai besoin d'y toucher directement, l'API Servlet comprends la classe javax.servlet.http.Cookie qui permet de manipuler des objets Cookies
 

    5.1 Envoyer un cookie

Pour créer un cookie:


Cookie c = new Cookie("login", str_login);
c.setVersion(1);
c.setDomain(".mon_domaine.com");
res.addCookie(authCookie);

    5.2 Récupérer un cookie


L'instruction suivante permet de récupèrer l'ensemble des cookies:

Cookie[] cookies = req.getCookies(); 

La classe Cookie possède alors les méthodes suivantes:
public String getName()  pour récupèrer le nom du cookie

public String getDomain() pour récupèrer le domaine

public String getValue() pour récupérer la valeur stockée dans le cookie


6 Problèmes de threadingUn serveur web pouvant servir plusieurs clients de manière concurrente, lorsqu'un servlet est conçu de manière à accèder à une ressource partagée, par exemple une base de données, il est parfois nécéssaire de prévenir l'accès simultané par plusieurs clients à cette même ressource. Afin d'obliger un servlet à ne traiter qu'une seule requète à tout moment, il existe deux possibilités : la première consiste à concevoir le servlet de façon à ce qu'il implémente l'interface SingleThreadModel.

Un exemple d'un tel servlet est le suivant :



public class ReceiptServlet extends HttpServlet implements SingleThreadModel {
    public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
    {
        ...
    }

    ...
}


Le serveur s'assure alors que la méthode service n'est pas appelée plus d'une seule fois simultanément.
Un moteur de base de données comporte bien souvent des systèmes de verrouillage d'accès et n'est donc pas un bon exemple. Prenons plutot l'exemple d'un fichier texte contenant un nombre plusieurs clients pourraient vouloir modifier simultanément

La deuxième possibilité est de synchroniser l'accès à la ressource. 7 Java DataBase ConnectivityIl serait difficile de parler de l'API Servlet sans également mentionner l'API JDBC. En effet, ce dernier permet à tout servlet d'accèder de manière directe à pratiquement n'importe quelle base de donnée externe, pourvu que celle ci possède un driver JDBC. Dans cet article, nous utilisons la base de données PostgreSQL, dont le driver JDBC est disponible à cette adresse. Il faut avant de commencer s'assurer que le chemin du driver JDBC est présent dans le $CLASSPATH. (au besoin faire un olly>export CLASSPATH=$CLASSPATH:/usr/lib/pgsql/jdbc6.5-1.2.jarou bien insérer la ligne wrapper.classpath=/usr/lib/pgsql/jdbc6.5-1.2.jardans le fichier jserv.properties)

Pour faire fonctionner l'example fourni, il est nécéssaire d'avoir une base de données (ici nommée test), et d'y insérer une table avec quelques données. Pour cela, il suffit de créer un fichier texte tout simple nommé par exemple jdbc.sql contenant les quelques commandes SQL suivantes :



create table stories (story_title varchar(100), story_url varchar(100), story_date date);
insert into stories values ('NASA Proposes Launch Solar Sail Vehicle For 2010', 'http://slashdot.org/article.pl?sid=00/05/15/058238', '2000-05-15');
insert into stories values ('Linuxcare Responds To Tim O'Reilly's Article', 'http://slashdot.org/article.pl?sid=00/05/15/0254252', '2000-05-15');
insert into stories values ('New Internet VCR Service', 'http://slashdot.org/article.pl?sid=00/05/14/2048217', '2000-05-15');


 

Ensuite la commande  olly>psql test< jdbc.sql permet d'éxécuter ces commandes (et donc de créer la table et d'y insérer les trois enregistrements).

    7.1 Connection à une base de donnée

Dans le monde JDBC, une base de données est représentée par une URL, par exemple jdbc:postgresql://host:port/base. En ce qui concerne le driver JDBC pour PostgreSQL, host est par défaut égal à localhost et port à 5432



import java.sql.*;
public class jdbctest {
   public static void main(String args[])
   {
        String url = "jdbc:postgresql:test";
        Connection con;
        Statement stmt;

        try
        {
           Class.forName("postgresql.Driver");
        }
        catch(java.lang.ClassNotFoundException e)
        {
           System.err.print("ClassNotFoundException: "); System.err.println(e.getMessage());
        }

        try
        {
           con = DriverManager.getConnection(url, "olly", "");
           stmt = con.createStatement(); 

            ResultSet rs = stmt.executeQuery("select * from stories");
           while (rs.next())
           {
               String s = rs.getString("story_title");
               System.out.println(s);
           }
           stmt.close();
           con.close();

        }
       catch (SQLException ex)
       {
           System.err.println("SQLException: " + ex.getMessage());
       }
   }
}

Read the rest of this entry ... (1450 words left)

un petit tutorial en java

@ 09:18 AM (42 months, 1 day ago)
Using the Xalan XSLT engine within a java servlet
IntroductionSeparation of style from content allows for the same data to be presented in different ways and is the clear answer to the multiplication of connected devices (Palm, Pocket PC, Interactive TV) that can access networked ressources using their own language (WML, WebClipping, HTML, XHTML, cHTML, etc..).
In this article, we show how to produce HTML and WML content from an XML data source, and the appropriate XSLT stylesheets. The XSLT transformation is done using the Xalan transformation engine, an open-source java project hosted by the Apache foundation. The Xalan engine is called from a java servlet, running in the Tomcat servlet engine.
  RequirementsIn this article, I will assume that you have installed the Tomcat servlet engine, and the Xalan XSLT engine. Both are available from java.apache.org and xml.apache.org. I also assume that xalan.jar, xerces.jar (the XML parser bundled with Xalan) and the servlet classes are present in your classpath. If not, try something like:

XALAN_HOME=/path/to/xalan.jar
XERCES_HOME=/path/to/xerces.jar
export CLASSPATH=$CLASSPATH:$XALAN_HOME:$XERCES_HOME
 
  Creating a new web application within TomcatAlthough you could install your java classes in an existing web application (the one called "examples", for instance), it is probably better to create a new web application.  This is nicely explained in "Deploying web applications to Tomcat" by James Goodwill.
Assuming $TOMCAT_HOME is the path to the Tomcat directory, first change directory to webapps (the root of all web applications) and create the following directories:

/xslt
/xslt/WEB-INF
/xslt/WEB-INF/classes

To do so, type the following commands:
> cd $TOMCAT_HOME/webapps
> mkdir xslt
> cd xslt
> mkdir WEB-INF
> cd WEB-INF
> mkdir classes
> cd classes

The /xslt/WEB-INF/classes directory is the place where you will store all the servlets classes described below.

Once the directories are created, you should install a servlet context, by editing the file $TOMCAT_HOME/conf/server.xml, and adding the following lines:

<Context path="/xslt" docBase="webapps/xslt" debug="0" reloadable="true" >
</Context>

path="/xslt" tells Tomcat that all requests starting with /onjava belong to the onjava web application.
docBase="webapps/xslt" tells the servlet container that the web application is located on webapps/xslt"
 

Once you have done these operations, you need to restart Tomcat.
  Xalan-J : a Java XSLT engineWe use Xalan as our XSLT engine. While we embed Xalan within our servlet, Xalan-J can also be used in a command line way to perform XSLT transformation and produce static output files. For example, imagine you want to produce a static HTML file called slashdot.html from a XML file called slashdot.xml.
You just need to type the following line:
> java org.apache.xalan.xslt.Process -in slashdot.xml -xsl slashdot.xsl -out slashdot.html

If you want the output to be displayed on the screen, simply omit the -out flag and argument. The XSLT processor classXalan-J implements the TrAX (Transformation API for XML) interface. From the Xalan documentation: "A TRaX TransformerFactory is an object that processes transformation instructions, and produces Templates (in the technical terminology). A Templates object provides a Transformer, which transforms one or more Sources into one or more Results. To use the TRaX interface, you create a TransformerFactory, which may directly provide a Transformers, or which can provide Templates from a variety of Sources. The Templates object is a processed or compiled representation of the transformation instructions, and provides a Transformer. The Transformer processes a Source according to the instructions found in the Templates, and produces a Result".
In the code below, the XSLT processor class contains a method that takes as input a XML source, a XSL source, a servlet request (it is not used here) and a servlet response, and it returns the output of the transformation to the servlet output stream.



import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

import org.xml.sax.SAXException;

import javax.xml.transform.*;
import javax.xml.transform.stream.*;

public class XalanXslProcessorBean {

    TransformerFactory tFactory;

    //the constructor simply gets a new TransformerFactory instance
    public XalanXslProcessorBean() {
        tFactory = TransformerFactory.newInstance();
    }

    //this method takes as input a XML source, a XSL source, and returns the output of the transformation to the servlet output stream
    public void process(StreamSource xmlSource,
                                  StreamSource xslSource,
                                  HttpServletRequest request,
                                  HttpServletResponse response)
             throws ServletException, IOException, SAXException {
        try {
            Templates templates = tFactory.newTemplates(xslSource);
            Transformer transformer = templates.newTransformer();
             transformer.transform(xmlSource, new StreamResult(response.getOutputStream()));
        }
        catch (Exception e) {
           //should log some message here
        }
    }
}



 
  The XML dataThe XML file we will use was grabbed from the slashdot.org site, and contains the slashdot news in XML form. It needs to be saved to your disk (and called slashdot.xml for example).


<?xml version="1.0"?><backslash xmlns:backslash="http://slashdot.org/backslash.dtd">

 <story>
  <title>NASA Proposes Launch Solar Sail Vehicle For 2010</title>
  <url>http://slashdot.org/article.pl?sid=00/05/15/058238</url>
  <time>2000-05-15 07:54:15</time>
  <author>timothy</author>
  <department>ralph-nader-will-have-to-hire-a-chase-car</department>
  <topic>space</topic>
  <comments>99</comments>
  <section>articles</section>
  <image>topicspace.gif</image>
 </story>

 <story>
  <title>Linuxcare Responds To Tim O'Reilly's Article</title>
  <url>http://slashdot.org/article.pl?sid=00/05/15/0254252</url>
  <time>2000-05-15 02:57:07</time>
  <author>timothy</author>
  <department>consider-source-horses-mouth-grain-of-salt</department>
  <topic>linuxbiz</topic>
  <comments>142</comments>
  <section>articles</section>
  <image>topiclinuxbiz.gif</image>
 </story>

 <story>
  <title>New Internet VCR Service</title>
  <url>http://slashdot.org/article.pl?sid=00/05/14/2048217</url>
  <time>2000-05-14 20:51:57</time>
  <author>timothy</author>
  <department>this-is-cool-but-can-they-do-that?</department>
  <topic>news</topic>
  <comments>189</comments>
  <section>articles</section>
  <image>topicnews.gif</image>
 </story>

 <story>
  <title>Google Releases WAP Search Tool</title>
  <url>http://slashdot.org/article.pl?sid=00/05/14/1240252</url>
  <time>2000-05-14 17:49:11</time>
  <author>emmett</author>
  <department>wireless</department>
  <topic>internet</topic>
  <comments>141</comments>
  <section>articles</section>
  <image>topicinternet.jpg</image>
 </story>

 <story>
  <title>No More Unreal Ports For Linux?</title>
  <url>http://slashdot.org/article.pl?sid=00/05/14/1439224</url>
  <time>2000-05-14 16:32:11</time>
  <author>timothy</author>
  <department>one-web-one-program-happy-mothers-day</department>
  <topic>games</topic>
  <comments>250</comments>
  <section>articles</section>
  <image>topicgames.jpg</image>
 </story>

 <story>
  <title>Pioneer Introduces 1st DVD Recorder (In Japan)</title>
  <url>http://slashdot.org/article.pl?sid=00/05/14/152210</url>
  <time>2000-05-14 15:50:48</time>
  <author>CmdrTaco</author>
  <department>steam-rising-from-the-riaas-forehead</department>
  <topic>tv</topic>
  <comments>98</comments>
  <section>articles</section>
  <image>topictv.jpg</image>
 </story>

 <story>
  <title>QuakeForge And QuakeWorld Forever Merge</title>
  <url>http://slashdot.org/article.pl?sid=00/05/14/1447248</url>
  <time>2000-05-14 15:07:27</time>
  <author>CmdrTaco</author>
  <department>and-then-there-was-one</department>
  <topic>quake</topic>
  <comments>57</comments>
  <section>articles</section>
  <image>topicquake.gif</image>
 </story>

 <story>
  <title>What Happens When Open Source And Work Collide?</title>
  <url>http://slashdot.org/article.pl?sid=00/05/09/016208</url>
  <time>2000-05-14 14:04:07</time>
  <author>Cliff</author>
  <department>sticky-situations</department>
  <topic>programming</topic>
  <comments>170</comments>
  <section>askslashdot</section>
  <image>topicprogramming.gif</image>
 </story>

 <story>
  <title>Black Holes Don't Exist???</title>
  <url>http://slashdot.org/article.pl?sid=00/05/14/1339252</url>
  <time>2000-05-14 13:39:24</time>
  <author>Roblimo</author>
  <department>pop-science-can-be-fun</department>
  <topic>science</topic>
  <comments>162</comments>
  <section>articles</section>
  <image>topicscience.gif</image>
 </story>

 <story>
  <title>Los Alamos Lab: We're OK, You're OK</title>
  <url>http://slashdot.org/article.pl?sid=00/05/14/0143228</url>
  <time>2000-05-14 04:44:44</time>
  <author>timothy</author>
  <department>sir-please-step-*away*-from-the-plutonium-bin</department>
  <topic>news</topic>
  <comments>278</comments>
  <section>articles</section>
  <image>topicnews.gif</image>
 </story>

</backslash>



  The XSLT stylesheetAn XSL stylesheet basically consists of a set of templates. Each template "matches" some set of elements in the original XML data and then describes the contribution that the matched element makes to the final output.
An XSLT template is defined by a xsl:template tag, whose "match" parameter determines where this template applies. For example <xsl:template match="/"> ... </xsl:template> applies to the root element of the XML document, while <xsl:template match="backslash/story"> matches every story element that has backslash as father. Templates are generally applied recursively, i.e. a template calls another templates using the xsl:apply-templates tag.
<xsl:value-of> inserts the value of an expression to the final output. Note that {element} can also be used to insert the value of element.

Here is the HTML stylesheet (named slashdot.xsl) we will use:



<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">

<xsl:template match="/">
<html>
<body>
<xsl:apply-templates select="backslash/story"/>
</body>
</html>
</xsl:template>

<xsl:template match="backslash/story">
  <li><a href="{url}"><xsl:value-of select="title"/></a></li>
</xsl:template>

</xsl:stylesheet>


Outputting HTML with a servletThis java code implements a basic servlet, which uses the XalanXslProcessorBean class defined above. It sets the Content-Type portion of the HTTP header to text/html, creates two StreamSources objects from both the xml and the xsl files, and perform the transformation


import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;

import javax.xml.transform.stream.*;

public class XslProcessorServlet extends HttpServlet {

    XalanXslProcessorBean processor;

    public void init(ServletConfig config) {
        processor = new XalanXslProcessorBean();
    }

    public void doGet (HttpServletRequest request,
                                HttpServletResponse response)
             throws ServletException, IOException {

        //sets the Content-Type portion of the HTTP header to text/html
        response.setContentType("text/html");
        try {
            processor.process(new StreamSource("slashdot.xml"), new StreamSource("slashdot.xsl"), request, response);
        }
        catch (Exception e) {

        }
    }
}


Since slashdot.xml is often updated,  you may prefer to fetch it directly from the slashdot.org site:  you then need to change the processor.process(...) line to: processor.process(new StreamSource(new InputStreamReader((new URL("http://slashdot.org/slashdot.xml")).openStream())), new StreamSource("slashdot.xsl"), request, response);
Then restart your servlet container if needed, and reload the page.
  Outputting HTML and WML with a servlet


Suppose that you want to make your content available to both HTML and WML navigators. Basically, you just need a XSLT stylesheet that can transform XML to HTML, and another one that can transform XML to WML (Wireless Meta Language). You then need to implement a mechanism that can use the appropriate stylesheet, depending on the navigator information contained in the HTTP request header.

Here is the WML stylesheet. Note the xsl:output tag, which is the only way to produce the <!DOCTYPE wml PUBLIC "-//WAPFORUM//DTD WML 1.1//EN" "http://www.wapforum.org/DTD/wml_1.1.xml"> string in the WML output.



<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
<xsl:output method="xml"
                  doctype-public="-//WAPFORUM//DTD WML 1.1//EN"
                  media-type="text/vnd.wap.wml"
                  doctype-system="http://www.wapforum.org/DTD/wml_1.1.xml"
                  encoding="ISO-8859-1"/>

<xsl:template match="/">
<wml>

    <template>
        <do type="prev" name="Previous" label="Back">
            <prev/>
        </do>
    </template>

    <card id="card1" title="Slashdot news">
        <p>
            <xsl:apply-templates select="backslash/story"/>
        </p>
    </card>

</wml>
</xsl:template>
 

<xsl:template match="backslash/story">
  <a href="{url}"><xsl:value-of select="title"/></a><br/>
</xsl:template>

</xsl:stylesheet>


Note that the following servlet code now contains some code to fetch the user agent from the HTTP header, and uses the WML stylesheet when the user agent string contains the word (Nokia). Obviously, this only works with a Nokia phone or with some Nokia emulator.



import java.io.*;
import java.net.*;
import javax.servlet.*;
import javax.servlet.http.*;

import javax.xml.transform.stream.*;

public class XslProcessorServlet extends HttpServlet {

    XalanXslProcessorBean processor;

    public void init(ServletConfig config) {
        processor = new XalanXslProcessorBean();
    }

    public void doGet (HttpServletRequest request,
                                HttpServletResponse response)
        throws ServletException, IOException {

        //fetch the user agent part of the HTTP header
        String useragent = request.getHeader("user-agent");

        //if the user agent contains the string "Nokia", then use the WML stylesheet, otherwise use the HTML one
        StreamSource xslsource;
        if (useragent.indexOf("Nokia") >= 0) {
            //send the correct Content-Type
            response.setContentType("text/vnd.wap.wml");
            xslsource = new StreamSource("slashdot_wml.xsl");
        } else {
            response.setContentType("text/html");
            xslsource = new StreamSource("slashdot_html.xsl");
        }

        try {
            processor.process(new StreamSource("slashdot.xml"), xslsource, request, response);
        }
        catch (Exception e) {

        }
    }
}


Read the rest of this entry ... (90 words left)

les categories de mon petit annuaire

@ 09:17 AM (42 months, 1 day ago)
de audio
de autor
de autos
de avellaneda
de aventura
de aves
de aviación
de ayuda
de azahar
de azulejos
de bébé
de bébé
de béziers
de béziers
de baño
de bach
de bach
de bach
de badajoz
de baie
de baie
de baile
de bain
de bain
de bains
de bains
de balaguer
de baloncesto
de bancos
de band
de banners
de barbarie
de barbarie
de barcelona
de barcos
de bariloche
de barrameda
de barras
de base
de base
de basket
de basket
de basse
de basse
de bateau
de bateau
de bateaux
de bateaux
de bayonne
de bayonne
de beauce
de beauce
de beauté
de beauté
de beauvoir
de beauvoir
de belenistas
de belfort
de belfort
de belgique
de belgique
de belgique
de belgische
de bellas artes
de bellas
de belle
de belle
de belleza
de bellota
de benasque
de benelux
de benidorm
de berger
de berger
de bergerac
de bergerac
de berlin
de berlin
de besançon
de besançon
de beste
de beurs
de bibliotecarios
de bibliotecas
de bien
de bien
de bienes
de biens
de biens
de bijbel
de bijoux
de bijoux
de bilbao
de billetes
de bilt
de biología
de biologie
de biologie
de birmanie
de birmanie
de bizkaia
de blaye
de blaye
de blois
de blois
de boda
de bodas
de boer
de bogotá
de bois
de bois
de boisson
de boisson
de boissons
de boissons
de bolivia
de bolsas
de bomberos de
de bomberos
de bord
de bord
de bordeaux
de bordeaux
de borges
de borja
de boulogne
de boulogne
de bourg
de bourg
de bourgogne
de bourgogne
de bourse
de bourse
de bouw
de boxeo
de brest
de brest
de bretagne
de bretagne
de bricolage
de bricolage
de bridge
de bridge
de broderie
de broderie
de bruxelles
de bruxelles
de buceo
de buen amor
de buen
de buenos aires
de buenos
de bureau
de bureau
de bureautique
de bureautique
de bureaux
de bureaux
de burgos
de cádiz
de córdoba
de cañones
de caballos
de cabo
de cabrales
de cada
de cadeaux
de cadeaux
de cadiz
de cadres
de cadres
de caen
de caen
de café
de café
de café
de cahors
de cahors
de caisse
de caisse
de calais
de calais
de calcuta
de cali
de calidad
de calles
de calpe
de calzado
de camargue
de camargue
de cambio
de campagne
de campagne
de camping
de camping
de camping
de campo
de campos
de canard
de canard
de canarias
de canciones
de cangas
de cantabria
de canto
de cao
de cao
de capacitación
de caracas
de caractère
de caractère
de caractères
de caractères
de carga
de carrera
de carrière
de carrière
de carros
de cartagena
de cartas
de carte
de carte
de cartes
de cartes
de cartouche
de cartouche
de casa
de casas en
de casas
de cassis
de cassis
de castellón
de castellon
de castilla y
de castilla
de casting
de casting
de castings
de castings
de castro
de catalunya
de cave à
de cave à
de cave
de cave
de caza
de cazorla
de cd
de cd
de cd
de ce
de ce
de celebraciones
de cergy
de cergy
de cervantes
de ceuta
de château
de château
de chalco
de chalet
de chalet
de chalets
de chalets
de chaleur
de chaleur
de chambéry
de chambéry
de chambly
de chambly
de chambord
de chambord
de chambre de
de chambre de
de chambre
de chambre
de chambres
de chambres
de chamonix
de chamonix
de champagne
de champagne
de champignons
de champignons
de chansons
de chansons
de chant
de chant
de chantier
de chantier
de charge
de charge
de charleroi
de charleroi
de charme en
de charme en
de charme
de charme
de charpente
de charpente
de chartres
de chartres
de chasse
de chasse
de chat
de chat
de chats
de chats
de chauffage
de chauffage
de chevaux de
de chevaux de
de chevaux
de chevaux
de cheveux
de cheveux
de chez
de chez
de chiapas
de chiclayo
de chien
de chien
de chiens
de chiens
de chihuahua
de chile
de chile
de chile
de chile
de chiloé
de chimie
de chimie
de chine
de chine
de chirico
de chirurgie
de chirurgie
de chocolat
de chocolat
de chocolate
de ciclismo
de ciencia ficción
de ciencia y
de ciencia
de ciencias biológicas
de ciencias económicas
de ciencias sociales
de ciencias
de cinéma
de cinéma
de cine
de cirque
de cirque
de cirugía
de ciudad
de classe
de classe
de claude
de claude
de clermont
de clermont
de climatisation
de climatisation
de clubes
de co
de co
de coches en
de coches
de cocina
de cocktail
de cocktail
de cocktails
de cocktails
de cognac
de cognac
de coiffure
de coiffure
de colchones
de colima
de colis
de colis
de collection
de collection
de cologne
de cologne
de colomb
de colomb
de colombia
de colonia
de combat
de combat
de comercio de
de comercio e
de comercio
de commande
de commande
de commerce de
de commerce de
de commerce et
de commerce et
de commerce
de commerce
de commissie
de communes de
de communes de
de communes du
de communes du
de communes
de communes
de communication
de communication
de compétences
de compétences
de compagnie
de compagnie
de componentes
de composants
de composants
de compostela
de compostelle
de compostelle
de compra
de compras
de comptabilité
de comptabilité
de computación y
de computación
de computadoras
de computadores
de computer
de computo
de comunicación
de comunicacion
de comunicaciones
de concepción
de concreto
de conduire
de conduire
de conduite
de conduite
de congrès
de congrès
de congresos
de conseil en
de conseil en
de conseil
de conseil
de construcción
de construccion
de construction
de construction
de construire
de construire
de contabilidad
de contact
de contact
de contacto
de contenidos
de contenu
de contenu
de contrôle
de contrôle
de control de
de control
de copas
de copropriété
de copropriété
de cordoba
de correo
de correos
de corse
de corse
de corte
de costa blanca
de costa rica
de costa
de costa
de couleurs
de couleurs
de cours
de cours
de course
de course
de courses
de courses
de coutances
de coutances
de couverture
de couverture
de créance
de créance
de créances
de créances
de création de
de création de
de création
de création
de crédit
de crédit
de crédito
de crédits
de crédits
de credit
de credit
de cristal
de cristiandad
de cristo
de croisière
de croisière
de croissance
de croissance
de croix
de croix
de crozon
de crozon
de cruz
de cuadros
de cuba
de cuba
de cuba
de cuenca
de cuentas
de cuero
de cuisine
de cuisine
de cuisines
de cuisines
de cultura
de culture
de culture
de cursillos
de cv
de cv
de cv
de dã
de dã
de décoration
de décoration
de découpe
de découpe
de défense
de défense
de déménagement
de déménagement
de développement
de développement
de dôme
de dôme
de dag
de danse
de danse
de danza
de datos
de deauville
de deauville
de debate
de decisiones
de decoración
de defensa del
de defensa
de deportes
de derecho
de derechos humanos
de derechos
de dermatologie
de dermatologie
de desarrollo
de design
de design
de dessin
de dessin
de dessins
de dessins
de devis
de devis
de dibujos
de diciembre de
de diciembre del
de diciembre
de didonne
de didonne
de dieu
de dieu
de diffusion
de diffusion
de digitale
de dijon
de dijon
de dinamarca
de dinan
de dinan
de dinard
de dinard
de dinero
de dios
de direction
de direction
de discussion
de discussion
de diseño web
de diseño
de disque
de disque
de distribución
de divx
de djibouti
de djibouti
de document
de document
de documentación
de documentation
de documentation
de documents
de documents
de dolfijn
de domaine
de domaine
de domaine
de domaine
de domaine
de domaines
de domaines
de dominio
de dominios
de donnã
de donnã
de donnée
de donnée
de données
de données
de donnees
de donnees
de dood
de dos
de dos
de dos
de douarnenez
de douarnenez
de down
de down
de dragon ball
de dragon
de dragon
de dragon
de drapeaux
de drapeaux
de droit
de droit
de droits
de droits
de duero
de duplication
de duplication
de dvd
de dvd
de ebro
de economía y
de economía
de edificios
de educación
de eerste
de efteling
de egipto
de ejercicio de
de ejercicio
de el salvador
de el
de elche
de elearning
de electrónica
de electricidad
de embarcaciones de
de embarcaciones
de emergencia
de empleo
de empresa
de empresarios de
de empresarios
de empresas de
de empresas
de encuentro
de energía
de enero de
de enero del
de enero
de enfermería
de enlaces
de enseñanza
de entrenamiento
de episodios
de equipos
de escritorio
de escritura
de escuelas
de españa en
de españa
de español en
de español
de español
de español
de esperanto
de esquí
de esta
de estadística
de estado
de estados
de este
de estilo
de estructuras
de estudiantes de
de estudiantes
de estudio
de estudios de
de estudios
de eu
de europa
de europese unie
de europese
de eventos
de exportación
de extremadura
de fátima
de fête
de fête
de física
de fútbol
de fabricantes
de fabrication
de fabrication
de fachadas
de faire
de faire
de familia
de familie
de famille
de famille
de fans
de fantasía
de farmacia
de fatiga crónica
de fatiga
de febrero de
de febrero
de felipe
de femme
de femme
de fer de
de fer de
de fer
de fer
de fete
de fete
de feu
de feu
de fichier
de fichier
de fichiers
de fichiers
de fidélité
de fidélité
de fiesta
de fiestas
de fiets
de film
de film
de film
de films
de films
de filología
de filosofía
de financement
de financement
de fincas
de fitness
de fitness
de flandre
de flandre
de flash
de fleurs
de fleurs
de flores
de foie gras
de foie gras
de foie
de foie
de fomento
de fond
de fond
de fonds de
de fonds de
de fonds
de fonds
de fontenay
de fontenay
de foot
de foot
de football
de football
de forja
de formación
de formation des
de formation des
de formation professionnelle
de formation professionnelle
de formation
de formation
de fortune
de fortune
de fotografía
de fotos
de frais
de frais
de français
de français
de france à
de france à
de france
de france
de france au
de france au
de france de
de france de
de france en
de france en
de france et
de france et
de france
de france
de france
de france
de france
de france
de franche
de franche
de franchise
de franchise
de francia
de franquicias
de franse
de fribourg
de fribourg
de fruits
de fruits
de fumar
de fumer
de fumer
de futbol
de généalogie
de généalogie
de género
de géographie
de géographie
de géologie
de géologie
de gîtes
de gîtes
de galicia
de gamme
de gamme
de gandia
de garage
de garage
de garantie
de garantie
de garde
de garde
de gas
de gascogne
de gascogne
de gata
de gaulle
de gaulle
de gemeente
de genève
de genève
de genealogía
de genre
de genre
de georges
de georges
de gernika
de geschiedenis van
de geschiedenis
de gestión
de gestion de
de gestion de
de gestion des
de gestion des
de gestion
de gestion
de gestion
de getafe
de gex
de gex
de gezondheidszorg
de gipuzkoa
de girona
de gite
de gite
de gites
de gites
de glace
de glace
de gnu
de go
de go
de go
de goede herder
de goede
de golf de
de golf
de golf
de golf
de gouden
de graaf
de gracia
de grado
de graduados
de gran canaria
de gran
de granada
de grand
de grand
de grande
de grande
de gravure
de gravure
de gredos
de grenoble
de grenoble
de groene
de groot
de grootste
de gros
de gros
de grossesse
de grossesse
de grote
de groupe
de groupe
de groupes
de groupes
de guérande
de guérande
de guías
de guadalajara
de guadalupe
de guadeloupe
de guadeloupe
de guatemala
de guayaquil
de guerre
de guerre
de guinea ecuatorial
de guinea
de guitare
de guitare
de guyane
de guyane
de gymnastique
de gymnastique
de haagse
de haan
d

2006/1/18

j'ai créé un petit annuaire : vous pouvez le visiter

@ 01:39 AM (42 months, 2 days ago)
j'ai crée un petit annuaire. Vous pouvez le visiter :