Sie sind auf Seite 1von 9

Departement de genie logiciel et des TI LOG660 - Base de donnees haute performance Hiver 2012

Applications Web et servlets Java

Application Web
Une application Web rpartie sur trois couches (three-tier Web application) est compose e e selon larchitecture suivante : Client mince : ralis par un fureteur Web, le client mince est linterface utilisateur e e (GUI) qui soccupe de la prsentation et la saisie des donnes. Aucun traitement des e e donnes nest fait dans cette couche. e Serveur application : soccupe de traiter les requtes provenant du client a travers le e ` rseau et sert dinterface avec la base de donnes. La logique de contrle de lapplication e e o rside dans cette couche. e Serveur BD : normalement situ sur une machine dirente au serveur application, e e le serveur BD soccupe du stockage et de la gestion des donnes. La base de donnes e e (Oracle, MySQL, PostgreSQL) rside dans cette couche et communique au serveur e application ` travers le rseau. a e Puisque le serveur BD (disjkstra.logti.etsmtl.ca) contient dj` une base de donnes ea e cre au premier laboratoire, et comme plusieurs fureteurs Web sont disponibles, votre traee vail consistera essentiellement a implmenter le serveur application. La technologie qui sera ` e utilise pour ce serveur est celle des Servlets Java. e

Servlets Java
Un servlet est une application Java qui permet de crer dynamiquement des donnes e e au sein dun serveur HTTP. Ces donnes sont le plus souvent prsentes sous le format e e e HTML, mais elles peuvent galement ltre en format XML ou tout autre format destin e e e aux fureteurs Web. Tel quillustr a la Figure 1, le processus dinvocation dun servlet, dans e` une application ` trois couches, comporte 7 tapes : a e 1. Le fureteur se connecte a ladresse du site Web de lapplication et lui envoie une requte ` e HTTP GET demandant de produire une page HTTP associe a cette adresse. e ` 2. Le serveur Web (ex : Tomcat) retourne au fureteur une page HTML comportant une saisie de donnes (FORM HTML). Cette page Web prcise que les param`tres entrs e e e e par lutilisateur seront traites par un servlet. e 3. Lutilisateur entre linformation requise par la page Web qui est ensuite envoye par le e fureteur au serveur Web sous la forme dune requte HTTP POST. e 1

4. Le serveur Web dl`gue la requte au conteneur de servlet qui... ee e 5. ...dmarre un l du servlet correspondant. e 6. Le servlet dcode les param`tres provenant du client, tablit une connexion au serveur e e e BD et traite la requte a laide des donnes de la BD. e ` e 7. Le servlet produit une rponse a la requte sous la forme dune page HTML qui est e ` e retourne au client. e

Fig. 1 Invocation dun servlet Java ( c Robert Godin) Pour dvelopper une servlet HTTP, il faut crer une classe Java spcialisant la classe e e e javax.servlet.http.HttpServlet et rednir les mthodes doGet et doPost de la classe e e HttpServlet. Ces mthodes, produisant toutes les deux une page HTML en rponse a une e e ` requte HTTP, di`rent par la mani`re avec laquelle les param`tres sont transmis au serveur. e e e e Ainsi, dans la mthode doGet, les param`tres sont envoys directement dans lURL, sans e e e encryption. Cette mthode est souvent utilise pour demander une information au serveur. e e En revanche, la mthode doPost ins`re les param`tres de faon encrypte dans le corps de e e e c e la requte, et est utilise pour mettre a jour linformation du serveur. Dans le cadre de ce e e ` laboratoire, nous ne ferons pas la distinction entre ces deux types de requte et aurons une e mme implmentation pour les mthodes doGet et doPost. e e e

Exemple de servlet
Voici un exemple de servlet Java pour obtenir la liste des lms dont le titre renferme une certaine cha de caract`res : ne e
// Classe Java: ServletWebflix.java package webflix; import import import import import import import import java.io.IOException; java.io.OutputStreamWriter; java.io.PrintWriter; java.io.StringWriter; java.sql.Connection; javax.servlet.*; oracle.jdbc.pool.*; javax.naming.Context;

import javax.naming.InitialContext; public class ServletWebflix extends HttpServlet { // Initialisation du parent public void init(ServletConfig config) throws ServletException { super.init(config); } // Methode doGet: on utilise limplementation de doPost public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request,response); } // Traitement de la requete: // On recoit une chaine de charactere et on retourne un page HTML // contenant le titre des films de la BD contenant cette chaine // dans leur titre. public void doPost(HttpServletRequest requete, HttpServletResponse reponse) throws ServletException, IOException { // Specifier le type et lencodage des donnees reponse.setContentType("text/html"); reponse.setCharacterEncoding("utf-8"); // Creer un PrintWriter pour imprimer la page Web de la reponse OutputStreamWriter osw = new OutputStreamWriter(reponse.getOutputStream()); PrintWriter out = new PrintWriter(osw); // Entete de la page out.println("<html>"); out.println("<head><title>Reponse du Servlet Webflix</title></head>"); out.println("<body>"); String chaineRecherche = ""; Connection conn = null; PreparedStatement ps = null; try { // Recuperer le parametre provenant de la page HTML dentree chaineRecherche = requete.getParameter("chaineRecherche"); if (chaineRecherche != null) { // Ouvrir une connexion en passant par un DataSource Context initContext = new InitialContext(); Context envContext = (Context) initContext.lookup("java:/comp/env"); OracleDataSource ds = (OracleDataSource) envContext.lookup("jdbc/webflix"); conn = ds.getConnection(); // Creer une requete au serveur BD ps = conn.prepareStatement(

"SELECT * " + "FROM Film " + "WHERE titre like ?"); ps.setString(1,"%" + chaineRecherche + "%"); // Decoder les resultats ResultSet rs = ps.executeQuery(); while (rs.next()) out.println(rs.getString("titre") + " (" + rs.getInt("annee") + ")<br>"); } } catch (Exception e) { // Debug: afficher la trace derreur directement dans la page StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw); e.printStackTrace(pw); out.println("<p>" + sw.string() + "</p>"); } finally{ try{ // Liberer les connections et resources out.println("</body></html>"); out.close(); ps.close(); conn.close(); } catch(Exception lException){ lException.printStackTrace(); } } } }

Tel quillustr dans cet exemple, le traitement dune requte par un servlet, dans la e e mthode doPost comporte plusieurs tapes : e e 1. Congurer le type et lencodage des donnes de la rponse. Dans notre cas, les donnes e e e sont de type HTML et lencodage utilis est celui de la base de donnes (UTF-8). e e 2. Crer un PrintWriter an dimprimer la page HTML de la rponse. e e 3. Rcuprer les param`tres de la requte a laide de la fonction getParameter. e e e e ` 4. Crer une connexion ` la base donnes. Lors du laboratoire 1, les param`tres de la e a e e connexion (URL, ID et mot de passe pour la BD) taient entrs directement dans le e e code Java. Cette approche comporte plusieurs probl`mes, principalement au niveau de e la scurit et de la exibilit. Ainsi, si ladresse du serveur BD ou lID/mot de passe du e e e compte de la BD change, il faut modier et redployer le servlet. Dans ce laboratoire, e nous utiliserons une meilleure approche base sur les DataSource. Cette approche sera e explique plus en dtails dans lnonc. e e e e 5. Une fois la connexion a la BD tablit, utiliser un ou plusieurs PreparedStatement ` e pour faire une requte ou mettre ` jour les donnes de la BD. e a e 4

6. Imprimer sous la forme dune page HTML la rponse a la requte du client ` laide du e ` e a PrintWriter. 7. Dans tous les cas, librer les resources en fermant le PrintWriter, le PreparedStatement e ainsi que la connexion ` la BD. a Pour saisir et envoyer les donnes au servlet, il est ncessaire davoir une page HTML e e faisant rfrence au servlet : ee
<!-- Page HTML FormWebflixServlet.html --> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>Recherche de films dans la BD Webflix</title> </head> <body> <form action = "servlet-webflix" method = "post"> <p>Entrer une cha^ne de caract`res contenue dans le titre du film</p> e <table> <tr> <td>Cha^ne de recherche: </td> <td><input type = "text" name = "chaineRecherche" /></td> </tr> </table> <input type = "submit" value = "Soumettre" /> </form> </body> </html>

` A noter les lments action="servlet-webflix" et method="post" de la balise form. ee Le premier indique que le servlet qui recevra les donnes est situ ` lURL (virtuelle) : e ea
<adresse application Web>/servlet-webflix.

Nous verrons plus loin comment associer cette adresse virtuelle avec une classe Java (ex : ServletWebflix.class). Le second lment spcie que la requte sera envoye par un POST ee e e e HTTP et que la mthode doPost du servlet sera appele. e e

Gestion de session dans les servlets


Dans une application Web linteraction entre lutilisateur et lapplication se fait souvent a travers direntes pages. An de transmettre les donnes entres dans une page (serv` e e e let) a une autre page (servlet), dans une mme session, on doit utiliser le mcanisme de ` e e HttpSession. Prenons le cas dune application Web qui demande dentrer deux nombres, dans des pages direntes, et retourne une page HTML achant la somme de ces deux e nombres. Dans un premier temps, il faut une page HTML initiale demandant dentrer le premier nombre :
<!-- Page HTML FormSommeServlet.html --> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>Somme de deux nombres</title>

</head> <body> <form action = "somme1" method = "post"> <table> <tr> <td>Entrer un premier nombre: </td> <td><input type = "text" name = "premierNombre" /></td> </tr> </table> <input type = "submit" value = "Soumettre" /> </form> </body> </html>

Ensuite, dans le premier servlet, il faut rcuprer le param`tre envoy par cette page, le e e e e sauver dans un HttpSession, et imprimer dans la rponse une page Web demander e
// Classe Java: SommeServlet1.java ... public void doPost(HttpServletRequest requete, HttpServletResponse reponse) throws ServletException, IOException { ... // Creer une session HttpSession session = requete.getSession(true); try { // Recuperer le premier nombre String premierNombre = requete.getParameter("premierNombre"); // Sauver le premier parametre dans la session session.setAttribute("premierNombre", premierNombre); // Afficher la seconde page out.println("<html>"); out.println("<head><title>Somme de deux nombres (2)</title></head>"); out.println("<body>"); out.println("<form action = \"somme2\" method = \"post\">"); out.println("<table><tr>"); out.println("<td>Entrer un deuxi`me nombre: </td>"); e out.println("<td><input type = \"text\" name = \"deuxiemeNombre\" /></td>"); out.println("</tr></table>"); out.println("<input type = \"submit\" value = \"Soumettre\" />"); out.println("</form></body></html>"); } ... }

Puisque que la session est cre dans ce servlet, il faut donner le valeur true au param`tre ee e de la mthode getSession. Lorsque lon veut rcuprer une session dj` cre, on emploie e e e e a ee plutt la valeur false. Ensuite, il faut crer un second servlet qui va rcuprer les deux o e e e nombre et produire une page HTML donnant leur somme :
// Classe Java: SommeServlet2.java ...

public void doPost(HttpServletRequest requete, HttpServletResponse reponse) throws ServletException, IOException { ... // Creer une session HttpSession session = requete.getSession(false); try { // Recuperer le premier nombre String premierNombre = session.getAttribute("premierNombre"); // Recuperer le second nombre String deuxiemeNombre = requete.getParameter("deuxiemeNombre"); // Afficher la page contenant la somme out.println("<html>"); out.println("<head><title>Somme de deux nombres (3)</title></head>"); out.println("<body>"); out.println("<p>La somme des deux nombres est: </p>"); out.println(Integer.parseInt(premierNombre) + Integer.parseInt(deuxiemeNombre)); out.println("</body></html>"); } ... }

Dploiement de lapplication Web e


Le dploiement de votre application Web sera faite sur la plateforme Apache Tomcat e 6.0. Sous Tomcat, une application Web est structure sous la forme dune hirarchie de e e e e rpertoires, dont la racine porte le nom de lapplication (<mon app>), situs dans le rpertoire e Tomcat des applications Web (ex :/var/lib/tomcat6/webapps/) :
<mon app>/ : Contient les chiers HTML, JSP, JavaScript, CSS, images, ainsi que tout autre chier directement visible par le fureteur. Par exemple, cest ici que lon met le chier FormWebflixServlet.html dans lexemple prcdent. e e

<mon app>/WEB-INF/web.xml : Dcrit les servlets de lapplication, leur association avec une e URL virtuelle, leurs param`tres, ainsi que les ressources utie lises par ces servlets. Par exemple. cest dans ce chier e que la classe Java ServletWebflix.class est associe avec e lURL virtuelle servlet-webflix rfrence dans le chier ee e FormWebflixServlet.html. <mon app>/WEB-INF/classes/ : Contient tous les classes Java (chiers .class) requis par lapplication, incluant ` la fois les classes a ` des servlets et celles utilises par ces servlets. A noe ter que lemplacement des classes doit respecter la position de la classe dans son paquetage Java. Par exemple, comme la classe ServletWebflix.java renferme la ligne package webflix ;, le chier ServletWebflix.class doit se trouver dans le sous-rpertoire e <mon app>/WEB-INF/classes/webflix/.

: Contient toutes les libraires JAR requises par votre applica` tion. A noter que certaines JAR, comme celles renfermant les pilotes JDBC se trouvent dj` dans un rpertoire partag les ea e e rendant disponibles ` toutes les applications Web dans Toma cat. e <mon app>/META-INF/context.xml : Dnit les resources disponibles dans le contexte de lapplication Web. Cest dans ce chier que lon dnit les param`tres e e de la connexion JDBC ` la BD Oracle. a <mon app>/WEB-INF/lib/

La description du dploiement de lapplication se fait dans le chier web.xml situ dans e e le rpertoire <mon app>/WEB-INF. Pour chacun des servlets de lapplication ce chier doit e avoir une balise
<servlet> <servlet-name> nom_servlet </servlet-name> <servlet-class> classe_servlet </servlet-class> </servlet>

ainsi quune balise


<servlet-mapping> <servlet-name> nom_servlet </servlet-name> <url-pattern> url_servlet </url-pattern> </servlet-mapping>

Ici, nom servlet est un identiant choisit pour le servlet, classe servlet est la classe du servlet correspondant, incluant le prxe du paquetage Java, et url servlet est lURL e virtuelle associe au servlet, soit url serveur tomcat/url servlet. Par ailleurs, ce chier e peut galement dnir certaines ressources utilises par lapplication, avec une balise : e e e
<resource-ref> <description> texte_descriptif </description> <res-ref-name> nom_ressource </res-ref-name> <res-type> classe_ressource </res-type> <res-auth>Container</res-auth> </resource-ref>

Voici un exemple de chier pour le servlet dcrit prcdemment : e e e


<?xml version = 1.0 encoding = UTF-8?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"> <servlet> <servlet-name>ServletWebflix</servlet-name> <servlet-class>webflix.ServletWebflix</servlet-class> </servlet> <servlet-mapping> <servlet-name>ServletWebflix</servlet-name> <url-pattern>/servlet-webflix</url-pattern> </servlet-mapping> <session-config> <session-timeout>30</session-timeout> </session-config> <mime-mapping>

<extension>html</extension> <mime-type>text/html</mime-type> </mime-mapping> <mime-mapping> <extension>txt</extension> <mime-type>text/plain</mime-type> </mime-mapping> <welcome-file-list> <welcome-file>index.jsp</welcome-file> <welcome-file>index.html</welcome-file> </welcome-file-list> <resource-ref> <description>JDBC connexion datasource</description> <res-ref-name>jdbc/webflix</res-ref-name> <res-type>oracle.jdbc.pool.OracleDataSource</res-type> <res-auth>Container</res-auth> </resource-ref> </web-app>

La ressource dcrite dans cet exemple est une data source Oracle permettant de se connece ter a la BD Webix. Les param`tres de cette ressource doivent tre dnis dans le chier ` e e e context.xml :
<?xml version=1.0 encoding=utf-8?> <Context reloadable="true"> <Resource name="jdbc/webflix" auth="Container" type="oracle.jdbc.pool.OracleDataSource" factory="oracle.jdbc.pool.OracleDataSourceFactory" maxActive="30" maxIdle="2" maxWait="1000" user="nomLogin" password="motDePasseLogin" driverClassName="oracle.jdbc.driver.OracleDriver" url="jdbc:oracle:thin:@dijkstra.logti.etsmtl.ca:1521:log660" /> </Context>

Evidemment, les valeurs des param`tres user et password doivent correspondre ` ceux e a utiliss pour se connecter a la BD. e `

Rfrences ee
Documentation Tomcat6 : http://tomcat.apache.org/tomcat-6.0-doc/index.html

Das könnte Ihnen auch gefallen