BD, XML et Serveur d'application

L'objectif de ce TP est d'utiliser le TP précédent dans une application Web de diffusion de livre. Les pages Web de l'application seront servies par un serveur Tomcat.

Rendu

Le programme (projets maven + éventuels scripts commentés dans un fichier zip, bien faire un clean avant) est à rendre pour le jeudi 19 janvier 2012 par mail à Haytham Elghazel avec pour sujet [BDAV-TP4] Rendu.

Serveur Tomcat et Servlets

:!: Avant de se lancer dans le TP, il est important de lancer la compilation du TP précédent afin de rendre disponibles les classes de ce dernier à l'application Web.

Récupérer l'archive du projet Web: livreweb.zip, la décompresser et l'ouvrir dans Netbeans. Il s'agit un projet Web maven préconfiguré. Le projet dépend du projet Maven du TP précédent.

Exécuter le serveur tomcat intégré via maven: clic droit sur le projet → Custom → tomcat.

Vérifier que tout fonctionne en suivant ce lien: http://localhost:8080/livreWeb/

Remarques:

  • Pour arrêter le serveur1), il faut arrêter l'exécution via Netbeans2).
  • Pour changer de port, si besoin: clic droit sur le projet → Properties; choisir Actions et sélection tomcat3) et changer maven.tomcat.port=xyzt4) dans Set Properties.

→ Trouver et ouvrir le fichier web.xml, regarder en particulier les onglets Servlet et XML. Ouvrir la classe d'implémentation de la servlet PremiereServlet et commenter le code de la méthode processRequest pour en expliquer le fonctionnement. Ne pas hésiter à consulter la javadoc.

Remarque: la méthode processRequest n'est pas nécessaire, elle permet juste de factoriser du code. Dans l'API JEE ce sont les méthode doGet et doPost5) qui sont appelées par le serveur Tomcat pour effectuer le rendu de la page.

→ Modifier la servlet pour afficher la valeur du paramètre id (voir la méthode getParameter de la classe HttpServletRequest).

Servlet d'affichage de livre

Ajouter une servlet (en utilisant le wizard associé, comme pour les classes) bdav.livreWeb.AfficheLivre. Cette servlet renverra un contenu de type text/xml.

Le but de cette servlet est de renvoyer au navigateur la représentation XML d'un livre. Dans un premier temps, on renverra un livre ayant un identifiant fixé. Dans un deuxième temps on utilisera le paramètre id pour récupérer l'identifiant du livre. On construira une liste de livre contenant le livre a afficher, ainsi que les membres nécessaires, puis on construira un JAXBContext pour sérialiser ce livre. On s'inspirera alors du cours sur les APIs XML pour “imprimer” la liste de livres vers le navigateur. Concernant la source de la transformation, on utilisera une javax.xml.bind.util.JAXBSource et on construira un StreamResult à partir du PrintWriter.

Bonus: Il ne faudrait pas mettre comme enfant direct d'un livre une partie qui est en fait une sous-partie d'une autre partie. Modifier si nécessaire la classe Livre (méthodes et/ou mapping) pour que sa représentation XML respecte cette contrainte.

Utilisation de XQuery en Java: affichage formaté

Packages java utiles: javax.xml.transform6), net.sf.saxon, net.sf.saxon.query;

Javadoc saxon (XQuery)

Le code Java suivant permet d'ouvrir un flux sur un fichier se trouvant dans le même projet que la classe courante:

InputStream flux = getClass().getResourceAsStream("/livre.xq");

Le code Java suivant permet de mettre en place une requête XQuery dont le code se trouve dans le fichier /livre.xq, fichier qui se trouve dans le même projet que la classe courante:

Configuration cfg = new Configuration();
StaticQueryContext stQC = new StaticQueryContext(cfg);
Reader xqSrc = new InputStreamReader(
        getClass().getResourceAsStream("/livre.xq"));
XQueryExpression expr = stQC.compileQuery(xqSrc);

Le requête XQuery peut alors être utilisée de la manière suivante:

Source inputDoc = ... // on recupère ici le document XML à interroger sous forme d'un StreamSource, DOMSource, JAXBSource, etc
Result output = ... // on veut écrire le résultat dans ce result
 
DynamicQueryContext dynQC = new DynamicQueryContext(cfg);
dynQC.setContextItem(cfg.buildDocument(src));
expr.run(dynQC, res, null);

Pour stocker un fichier avec les classes dans un projet maven, il doit être stocké dans src/main/resources7).

Modifier la servlet AfficheLivre de façon à:

  • si il y a un paramètre de la servlet appelé vue dont la valeur est “xml”, envoyer le contenu du livre au format XML
  • sinon appliquer une requête XQuery aux données XML du livre pour faire une présentation HTML de ce contenu XML.

Enfin, il faut savoir qu'une servlet peut être réutilisée pour plusieurs requêtes. Sachant qu'il est possible de surcharger la méthode public void init() throws ServletException qui est appelée juste après la création de la servlet, créer des champs correspondant aux objets réutilisables entre deux requêtes et les initialiser dans cette méthode. Remarque: Tomcat ne garanti pas que les accès concurrents à la servlet soient isolés. Pour s'assurer de ne pas avoir de problèmes, il faut poser un verrou sur la méthode processRequest en ajoutant le mot-clé synchronized après protected.

Bonus: Faire une version alternative de la Servlet utilisant une feuille de style XSLT via TrAX (cf API XML) et récupérant les données XML via JDBC et une vue du TP mappings.

1)
par exemple afin de le relancer pour prendre en compte des changements
2)
carré rouge dans la fenêtre Output livreWeb
3)
en bas de la liste
4)
par exemple maven.tomcat.port=8081
5)
visibles si on déplie le code ligne 45
6)
regarder également les sous-packages
7)
Visible dans “Other sources” dans Netbeans