Professional Documents
Culture Documents
Objectifs :au travers l'tude d'une application simple illustrer la mise en uvre d'approche Modle, Vue, Contrle (MVC) Technologies : Servlets JSP JDBC (utilisation de DataSources)
1
Janvier 2010
Construit Modifie
Transfert
Driver JDBC
Modle Effectue les traitements couche mtier Vue Prsentation des rsultats
Consulte
Janvier 2010
Janvier 2010
Le modle
Modle (objet mtier) : classe qui reprsente une des entit du domaine qui pourra ensuite tre utilise par les composants Web
Par exemple ici une classe Histogramme qui reprsente un histogramme de notes
Histogramme POO 2005
Serveur SGBD
Histogramme
- String matiere - int annee - int[] freq = new int[21] + Histogramme()
0 1 2 ... 9 10 ... 18 19 20
index.html
HistogramImager HistogramImager
(Servlet) (Servlet)
Tableau.jsp Tableau.jsp
+ String getMatiere() + void setMatiere(String m) + int getAnnee() + void setAnnee(int a) + int getFreq(int n) + void setFreq(int n, int freq) + int notePlusFrequente() + double moyenne() + double ecartType()
(JSP) (JSP)
accesseurs (getters) et modifieurs (setters) pour les diff diffrentes propri proprits que l'on veut exposer
Pour faciliter son utilisation par les composants web (en particulier pages JSP via EL) le modle doit tre sous la forme d'un java bean
Philippe GENOUD -Patrick REIGNIER - UJF Janvier 2010
Janvier 2010
Le modle
Aller chercher dans la Bd les frquences des notes pour une matire et une anne donne
Histogramme POO 2008 matire="poo" anne=2008 Anne 2003 2003 ... 2008 ... 2008 2008 2008 ... 2005 select note, count(*) count(*) from notes where annee= annee=2005 and matiere= matiere='poo' poo' group by note 2 1
note 1 2 9 18 count 1 3 12 1 0 1 2 ... 9 10 ... 18 19 20
Le modle
Aller chercher dans la Bd les frquences des notes pour une matire et une anne donne
Histogramme Serveur SGBD
Serveur SGBD
notes POO 2008 matire="poo" anne=2008 Anne 2003 2003 ... 2008 ... 2008 2008 2008 ... 2005 note 7 14 ... 10 ... 12 11 8 ... 16 Matire bd ihm ... poo ... ihm bd poo ... poo noEtud 20234 20014 ... 21345 ... 20014 20234 20234 ... 21417 0 1 3 ... 12 10 ... 1 0 0 1) Faire requte SQL via JDBC
notes
0 1 2 ... 9 10 ... 18 19 20
0 1 3 ... 12 10 ... 1 0 0 Construire un tableau des fr frquences qui pourra ensuite tre consult consult par les composants web note 7 14 ... 10 ... 12 11 8 ... 16 2) Parcourir le ResultSet pour remplir le tableau des fr frquences
Philippe GENOUD -Patrick REIGNIER - UJF Janvier 2010 Philippe GENOUD -Patrick REIGNIER - UJF
noEtud 20234 20014 ... 21345 ... 20014 20234 20234 ... 21417
7
Janvier 2010
Le modle
Aller chercher dans la Bd les frquences des notes pour une matire et une anne donne
Servlets Client Histogramme POO 2008 matire="poo" anne=2008 notes Pages JSP Compte Serveur SGBD prsentation mtier Accs aux donnes ClientDAO
Architecture en couches
JDBC
CompteDAO
SGBD Relationnel
0 1 2 ... 9 10 ... 18 19 20
0 1 3 ... 12 10 ... 1 0 0
code JDBC
Les objets DAO (Data Access Object) isolent tout le code li la persistance des donnes Quand l'application a besoin d'effectuer une opration lie la persistance elle fait appel un objet DAO L'interface des objets DAO est indpendante du support de persistance Le reste de l'application utilise les DAO uniquement au travers de leur interface abstraite Par exemple si on change d'implmentation de DAO pour passer d'une base Oracle des fichiers XML le reste de l'application demeure inchang. Chaque classe d'objet mtier a son propre type de DAO (IClientDAO, ICompteDAO) Le mme objet DAO peut tre utilis pour les objets d'une mme classe d'objet mtier
10
NotesDAO NotesDAO
Serveur SGBD
Retreive
Collection<Note> notesEtudiant(int numEtud, String matiere)
index.html
HistogramImager HistogramImager
(Servlet) (Servlet)
Tableau.jsp Tableau.jsp
(JSP) (JSP)
Update Delete
OracleNotesDAO
MySQLNotesDAO
XMLNotesDAO
Janvier 2010
11
Janvier 2010
12
Retreive
Update Delete
parcours du r rsultat de la requte pour remplir le tableau des fr frquences de l'objet Histogramme retourne l'objet Histogramme } catch (SQLException (SQLException e) { } } } throw new DAOException(" DAOException("pb ("pb recup recupration histogramme" , e); cr cration d'un objet Histogramme
le code d'implmentation de ces mthodes effectue des entres/sorties (dans il peut donc lever des exceptions (SQLException) notre cas accs la BD) Que faire de ces exceptions ?
Les attraper ? try { } catch (SQLException e) { } Les faire remonter ? throws SQLException mais si on veut pouvoir changer facilement de DAO il ne faut pas lier les exceptions un type de DAO particulier
Philippe GENOUD -Patrick REIGNIER - UJF Janvier 2010 Philippe GENOUD -Patrick REIGNIER - UJF
13
Janvier 2010
14
connexion JDBC la BD
Note getNote(int numEtud, int annee, String matiere) throws DAOException Histogramme getHistogramme(int annee, String matiere) throws DAOException Collection<Note> notesEtudiant(int numEtud) throws DAOException Collection<Note> notesEtudiant(int numEtud, int annee) throws DAOException Collection<Note> notesEtudiant(int numEtud, Strin matiere) throws DAOException void updateNote(Note n) throws DAOException void deleteNote(Note n) throws DAOException
stmt = conn.createStatement() ;
result = stmt.executeQuery("select note, count(*) from notes" + " where annee = " + annee + " and matiere='" + matiere + "' group by note") ;
Histogramme hist = new Histogramme(); cration d'un objet Histogramme hist.setMatiere(matiere); hist.setAnnee(annee);
Dans le code qui utilise les objets DAO ? moyen ce code doit tre le plus
Pour les classes d'implmentation assurant la persistence avec une BD toutes ces mthodes ont besoin d'une connexion JDBC la base de donne O et quand crer (ouvrir) la connexion ? Quand la librer (fermer) ?
while (result.next()) parcours du rsultat de { la requte pour remplir le tableau indpendant possible des DAO note = result.getInt(1); des frquences de l'objet Histogramme hist.setFreq(i,result.getInt(2)); Dans le code des DAO ? } rs.close(); stmt.close(); au dbut et la fin de chaque mthode return hist; retourne l'objet Histogramme
} depuis toutes les mthodes ? catch (SQLException e) { throw new DAOException("pb histogramme ", e); } }
Philippe GENOUD -Patrick REIGNIER - UJF Janvier 2010
15
Janvier 2010
16
result = stmt.executeQuery("select note, count(*) from notes" + " where annee = " + annee + " and matiere='" + matiere + "' group by note") ; Histogramme hist = new Histogramme(); hist.setMatiere(matiere); hist.setAnnee(annee); // parcours du rsultat de la requete et pour chaque note // on reporte son nombre d'occurences dans le tableau freq while (result.next()) { note = result.getInt(1); hist.setFreq(i,result.getInt(2)); } finally { rs.close(); stmt.close(); if (conn != null) { return hist; try { } conn.close(); catch (SQLException e) { } catch (SQLException e) { throw new DAOException("pb histogramme ", e); throw new DAOException(e); } } }
Philippe GENOUD -Patrick REIGNIER - UJF Janvier 2010
result = stmt.executeQuery("select note, count(*) from notes" + " where annee = " + annee + " and matiere='" + matiere + "' group by note") ; Histogramme hist = new Histogramme(); hist.setMatiere(matiere); hist.setAnnee(annee); // parcours du rsultat de la requete et pour chaque note // on reporte son nombre d'occurences dans le tableau freq while (result.next()) { connexion ferme lorsque l'objet note = result.getInt(1); DAO n'est plus utilis hist.setFreq(i,result.getInt(2)); } public void finalize() { rs.close(); stmt.close(); return hist; if (conn != null) { } try { catch (SQLException e) { conn.close(); throw new DAOException("pb histogramme ", e); } }
} 18
Connexion attribut du DAO partag par toutes les requtes (mthodes) du DAO Nombreux problmes possibles : Timeout : la connexion peut tre ferme automatiquement (par exemple si l'utilisateur a cess momentanment son activit sans quitter l'application). Passage l'chelle si pour chaque utilisateur (session) un objet DAO avec une connexion est cre nombre d'utilisateur limit par le nombre de connexions pouvant tre ouverte simultanment Risques d'incohrences si mme objet DAO donc mme objet connexion partag par plusieurs utilisateurs ne pas oublier que les servlets sont multithreads : la mme instance sert toutes les requtes
19
Janvier 2010
20
noitcasnart al etubd 1t noitcasnart enu reutceffe ruop noixennoc al erugifnoc 1t 1 ruetasilitu ruop 1t daerht nu'd noitarC
La connexion est en mode autoCommit La mise jour de la table est immdiatement effective ! } ... Une partie du code ex excut cut par la m mthode service d'un servlet ... try { con.setAutoCommit(false); // excuter les instructions // qui constituent la transaction stmt.executeUpdate(...); stmt.executeUpdate(...); // valide la transaction con.commit(); con.setAutoCommit(true); } catch (SQLException e) { con.rollback(); // annule // les oprations de la transaction t2
noitcasnart enu reutceffe ruop noixennoc al erugifnoc 2t
timmoCotua edom el eutitser 1t )evitceffe tse selbat sed ruoj esim al( noitcasnart al edilav 1t
javax.sql package dextension standard de JDBC Pour les applications JEE (Java Entreprise Edition) Inclus en standard dans JSE (Java Standard Edition) depuis version 1.4 DataSource : Obtention du nom de la base partir de serveurs de noms plutt que davoir le nom de la base de donnes cod en dur dans lapplication. Utilisation de JNDI (Java Naming and Directory Interface) pour connexion une base de donne PooledConnection : support pour gestion dun pool de connexion gestion dun cache des connexion ouvertes vite la cration de nouvelles connexions (ce qui est coteux) Quand un code a besoin d'accder la base de donnes, il obtient une connexion en s'adressant la DataSource
DataSource
noitcasnart al etubd 2t
noitcasnart al tiusruop 1t
Philippe GENOUD -Patrick REIGNIER - UJF Janvier 2010
21
Janvier 2010
22
javax.sql
javax.sql.DataSource
L'objet DataSource avec pooling de connexions maintient un ensemble de connexions la BD prtes l'emploi (pool ou cache de connexions).
Janvier 2010
23
Janvier 2010
24
javax.sql.DataSource
L'objet DataSource avec pooling de connexions maintient un ensemble de connexions la BD prtes l'emploi (pool ou cache de connexions).
DataSource DataSource
javax.sql.DataSource
L'objet DataSource avec pooling de connexions maintient un ensemble de connexions la BD prtes l'emploi (pool ou cache de connexions).
Connection En fait PooledConnection DataSource ds; ... Connection c = ds.getConnnection(); ... c = c.close(); c = c.close(); DataSource ds; ... Connection c = ds.getConnnection(); ...
Quand un code a besoin d'accder la base de donnes, il obtient une connexion en s'adressant la DataSource. Il conserve la connexion jusqu' sa fermeture explicite.
Philippe GENOUD -Patrick REIGNIER - UJF Janvier 2010 Philippe GENOUD -Patrick REIGNIER - UJF
Quand un code a besoin d'accder la base de donnes, il obtient une connexion en s'adressant la DataSource. Il conserve la connexion jusqu' sa fermeture explicite. Lorsqu'une connexion est "ferme", elle est en fait relche et remise dans le pool.
25
Janvier 2010
26
private static Map<DataSource,OracleNotesDAO> daoInstances = new HashMap<DataSource,OracleNotesDAO>(); public synchronized static OracleNotesDAO getInstance(DataSource ds) { OracleNotesDAO inst = daoInstances.get(ds); if (inst == null) { inst = new OracleNotesDAO(ds); daoInstances.put(ds,inst); } return inst; } private public OracleNotesDAO(DataSource ds) { this.ds = ds; }
... } 27
28
Dfinir Dfinir un un pool pool de de connexions connexions avec avec TomCat TomCat
javax.sql.DataSource = pool de connexions Interface dans javax.sql.DataSource Objet DataSource pris en charge par le serveur TomCat org.apache.commons.dbcp.BasicDataSource Cr par le serveur Tomcat partir de paramtres de configuration ressource globale un contexte (ressource partage par toutes les sessions d'une mme application) description dans le fichier context.xml de l'application ressource globale partage par tous les contextes description dans le fichier server.xml
Dfinir Dfinir un un pool pool de de connexions connexions avec avec Tomcat Tomcat
Dfinition d'une ressource de type DataSource pour le contexte de l'application dans le fichier de configuration context.xml de l'application Dsignation cette ressource dans le fichier de dploiement de l'application dans le fichier web.xml de l'application Installer le pilote JDBC dans le rpertoire lib de Tomcat
Voir dans la documentation de Tomcat http://tomcat.apache.org/tomcat-x.x-doc/index.html
Mis disposition des applications par un serveur dobjets : on rcupre l'objet DataSource cr et gr par le conteneur au travers d'un identificateur (API JNDI (Java Naming Directory Interface))
Philippe GENOUD -Patrick REIGNIER - UJF Janvier 2010
jndi-datasource-examples-howto.html
29
Janvier 2010
30
Dfinir Dfinir un un pool pool de de connexions connexions avec avec TomCat TomCat
Dfinir Dfinir un un pool pool de de connexions connexions avec avec Tomcat Tomcat
1
Dfinition d'une ressource de type DataSource pour le contexte de l'application dans le fichier de configuration context.xml de l'application Dsignation cette ressource dans le fichier de dploiement de l'application dans le fichier web.xml de l'application Installer le pilote JDBC dans le rpertoire lib de Tomcat
context.xml <Context path="/HistogramMVC"> <Context path="/HistogramMVC">
Plus de rfrence explicite dans le code Au driver jdbc A lurl daccs la base Au nom de lutilisateur A son mot de passe Possibilit de changer de base lors du dploiement sans avoir besoin de recompiler lapplication. Il suffit de modifier les fichiers de configuration
Paramtrage de la connexion JDBC <Resource name="jdbc/Notes" <Resource name="jdbc/Notes" auth="Container" auth="Container" type="javax.sql.DataSource" type="javax.sql.DataSource" Paramtrage du maxActive="10" maxActive="10" pool de connexion maxIdle="3" maxIdle="3" maxWait="10000" maxWait="10000" username="genoud" username="genoud" password="xxxxxxx" password="xxxxxxx" driverClassName="oracle.jdbc.OracleDriver" driverClassName="oracle.jdbc.OracleDriver" url="jdbc:oracle:thin:@hopper.e.ujf-grenoble.fr:1521:ufrima"/> url="jdbc:oracle:thin:@hopper.e.ujf-grenoble.fr:1521:ufrima"/> </Context> </Context>
31
Janvier 2010
32
Dfinir Dfinir un un pool pool de de connexions connexions avec avec Tomcat Tomcat
Dfinition d'une ressource de type DataSource pour le contexte de l'application dans le fichier de configuration context.xml de l'application
2
Dfinir Dfinir un un pool pool de de connexions connexions avec avec Tomcat Tomcat
Dfinition d'une ressource de type DataSource pour le contexte de l'application dans le fichier de configuration context.xml de l'application Dsignation cette ressource dans le fichier de dploiement de l'application dans le fichier web.xml de l'application
3
Dsignation cette ressource dans le fichier de dploiement de l'application dans le fichier web.xml de l'application Installer le pilote JDBC dans le rpertoire lib de Tomcat
web.xml ... <servlet-mapping> ... </servlet-mapping>
Si vous lancez Tomcat depuis Netbeans et que vous n'avez pas le droit d'criture dans le rpertoire d'installation de Tomcat vous pouvez configurer l'instance de Tomcat que vous utilisez l'aide des fichiers contenus dans le fichier .netbeans qui se trouve sur votre compte
Janvier 2010
33
Janvier 2010
34
Dfinir Dfinir un un pool pool de de connexions connexions avec avec Tomcat Tomcat
1
<GlobalNamingResources> <Environment name="simpleValue" type="java.lang.Integer" value="30"/> <Resource auth="Container" description="User database that can be updated and saved" name="UserDatabase" type="org.apache.catalina.UserDatabase" pathname="conf/tomcat-users.xml" factory="org.apache.catalina.users.MemoryUserDatabaseFactory"/> <Resource name="jdbc/test" type="javax.sql.DataSource" driverClassName="com.mysql.jdbc.Driver" password="xyyyyyyy" maxIdle="2" maxWait="5000" username="genoud" url="jdbc:mysql://localhost/essai" maxActive="4"/> </GlobalNamingResources>
Dfinir Dfinir un un pool pool de de connexions connexions avec avec Tomcat Tomcat
Dfinition d'une ressource globale partage par tous les contextes
context.xml de l'application
Dfinition d'une ressource globale partage par tous les contextes Description dans le fichier de configuration du serveur ($CATALINA_HOME/conf/server.xml)
Dclaration d'un lien pour chaque contexte qui peut y accder (fichier context.xmldes applications concernes)
web.xml de l'application
La dfinition de la DataSource peut se faire par l'intermdiaire de la console d'administration Tomcat Au 01/02/2008 pas disponible avec Tomcat 6.
Philippe GENOUD -Patrick REIGNIER - UJF Janvier 2010
35
Janvier 2010
36
Dfinir Dfinir un un pool pool de de connexions connexions avec avec Tomcat Tomcat
Controleur Controleur (Servlet) (Servlet)
Serveur SGBD
L'application Notes
l'objet NotesDAO construit l'objet Histogramme
NotesDAO NotesDAO JDBC
revenons notre application 38 40
Philippe GENOUD -Patrick REIGNIER - UJF Janvier 2010
L'objet DataSource est cr par le conteneur web (par ex. le serveur Tomcat) partir des informations de configuration. Ce n'est pas le code applicatif qui instancie cet objet.
context.xml
Serveur Tomcat
org.apache.commons. dbcp.BasicDataSource
Histogramme Histogramme
<Context path="/HistogramMVC">
<Resource name="jdbc/Notes"
auth="Container" type="javax.sql.DataSource" maxActive="10" maxIdle="3" maxWait="10000" username="genoud" password="xxxxxxx" driverClassName="oracle.jdbc.OracleDriver" url="jdbc:oracle:thin:@hopper.e.ujf-grenoble.fr:1521:ufrima"/>
(JavaBean) (JavaBean)
Servlet Servlet
HistogramImager HistogramImager
index.html
</Context>
(Servlet) (Servlet)
Tableau.jsp Tableau.jsp
NotesDAO Histogramme
(JSP) (JSP)
Utilisation de l'API JNDI (Java Naming Directory Interface) dfinie dans le package javax.naming
37
Janvier 2010
La page index.html
notes?annee="2005"&matiere="bd" &presentation="graphic" web.xml
<web-app> <web-app> <display-name>Notes</display-name> <display-name>Notes</display-name>
<servlet> <servlet> <servlet-name>controleur</servlet-name> <servlet-name>controleur</servlet-name> <description> <description> Controleur de l'applications histogramme de notes Controleur de l'applications histogramme de notes </description> </description> <servlet-class>servlets.Controleur</servlet-class> <servlet-class>servlets.Controleur</servlet-class> </servlet> </servlet>
<servlet> <servlet> <servlet-name>graphic</servlet-name> <servlet-name>graphic</servlet-name> <description> <description> Affiche histogramme sous forme graphique Affiche histogramme sous forme graphique </description> </description> <servlet-class>servlets.view.HistogramImager</servlet-class> <servlet-class>servlets.view.HistogramImager</servlet-class> </servlet> </servlet>
Controleur
Histogram Imager
<url-pattern>/notes</url-pattern> <url-pattern>/notes</url-pattern>
Le fichier de dploiement web.xml permet au serveur d'application de dterminer vers quel composant la requte doit tre adresse
notes?annee="2005"&matiere="bd"&presentation="graphic"
Philippe GENOUD -Patrick REIGNIER - UJF Janvier 2010
</web-app> </web-app>
39
HttpRequest
Serveur Tomcat
HttpRequest
Serveur Tomcat
HttpResponse
"5002" "db"
La servlet peut interroger l'objet HttpRequest pour rcuprer les paramtres de la requte
request.getParameter("prsentation")
Controleur
utiliser l'objet HttpResponse pour construire et envoyer un rponse au client qui a mis la requte
response.setContentType("text/html;charset=UTF-8"); PrintWriter out = response.getWriter(); out.println("<html>"); out.println("<head>"); ...
2'
41
Janvier 2010
42
Contrleur
public class HistogramControleur extends HttpServlet { notes?annee="2005"&matiere="bd"
/** * Rponse une requte de type <CODE>get</CODE> * @param request donnes associes la requte HTTP * @param response donnes associes la rponse **/ public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { //---------------------------------------------------------------------// Analyse de la requte HTTP //---------------------------------------------------------------------... //---------------------------------------------------------------------// Construction du modle //----------------------------------------------------------------------
... //---------------------------------------------------------------------// Rcupration des donnes (construction m.a.j. du modle) //---------------------------------------------------------------------... //---------------------------------------------------------------------// Gnration de la prsentation //----------------------------------------------------------------------
... }
Philippe GENOUD -Patrick REIGNIER - UJF Janvier 2010 Philippe GENOUD -Patrick REIGNIER - UJF
43
Janvier 2010
44
cela ne dispense pas de refaire une vrification ct serveur ! par exemple au cas o l'url serait tape } directement
try { annee = Integer.parseInt(request.getParameter("annee")) ; matiere = request.getParameter("matiere") ; presentation = request.getParameter("presentation") ; } catch(NumberFormatException e) { // Normalement la vrification que l'anne est bien un nombre // devrait tre confie javascript ct client avec blocage de // l'envoi du formulaire si saisie incorrecte.
try { annee = Integer.parseInt(request.getParameter("annee")) ; matiere = request.getParameter("matiere") ; presentation = request.getParameter("presentation") ; } catch(NumberFormatException e) { // Normalement la vrification que l'anne est bien un nombre // devrait tre confie javascript ct client avec blocage de // l'envoi du formulaire si saisie incorrecte. response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "L'anne demande n'est pas un nombre") ; return; }
Janvier 2010
45
Janvier 2010
46
int annee = 0 ; String matiere = null ; String presentation = null ; try { annee = Integer.parseInt(request.getParameter("annee")) ; matiere = request.getParameter("matiere") ; presentation = request.getParameter("presentation") ; } catch(NumberFormatException e) { // Normalement la vrification que l'anne est bien un nombre // devrait tre confie javascript ct client avec blocage de // l'envoi du formulaire si saisie incorrecte. response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "L'anne demande n'est pas un nombre") ;
try { annee = Integer.parseInt(request.getParameter("annee")) ; matiere = request.getParameter("matiere") ; presentation = request.getParameter("presentation") ; } catch(NumberFormatException e) { // Normalement la vrification que l'anne est bien un nombre // devrait tre confie javascript ct client avec blocage de // l'envoi du formulaire si saisie incorrecte. response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "L'anne demande n'est pas un nombre") ;
return; }
... if (presentation.equals("tableau"))
Philippe GENOUD -Patrick REIGNIER - UJF Janvier 2010
47
Janvier 2010
48
try { annee = Integer.parseInt(request.getParameter("annee")) ; matiere = request.getParameter("matiere") ; presentation = request.getParameter("presentation") ; } catch(NumberFormatException e) { // Normalement la vrification que l'anne est bien un nombre // devrait tre confie javascript ct client avec blocage de // l'envoi du formulaire si saisie incorrecte. // MAIS cela ne dispense pas de refaire une vrification ct // serveur (par exemple au cas ou l'url serait tape directement) response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, demande n'est n'est pas unpas nombre") ; throw new "L'anne ServletException("Anne un nombre", e); return ;
try { annee = Integer.parseInt(request.getParameter("annee")) ; matiere = request.getParameter("matiere") ; presentation = request.getParameter("presentation") ; } catch(NumberFormatException e) { // Normalement la vrification que l'anne est bien un nombre // devrait tre confie javascript ct client avec blocage de // l'envoi du formulaire si saisie incorrecte. // MAIS cela ne dispense pas de refaire une vrification ct // serveur (par exemple au cas ou l'url serait tape directement) response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, getServletContext().getRequestDispatcher( "L'anne demande n'est pas un nombre") ; "/formulaire.jsp").forward(request, response); }
49
Janvier 2010
50
formulaire.jsp
Rafficher la valeur du paramtre prcdent
notes?annee="200x"&matiere="bd"
/notes
<body> <form method="post" action="notes"> <p>Anne : <input type="text" name="annee" /> <font color="#FF0000"> (erreur != null) Le if message d'erreur si il est prsent out.println(erreur); %>
<JSP >
Ecriture lourde.
<JSP >
HistogramControler
tableau.jsp formulaire.jsp HistogramImager.java
${requestScope.erreurAnnee} </font> </p> Simplifie par ... utilisation de EL ... <input type="submit" value="envoyer"/> (Expression Language </form>
Rafficher la valeur du paramtre prcdent
${requestScope.erreurAnnee}
protected void doPost(HttpServletRequest request, HttpServletResponse response) ... String erreurAnnee = "Anne doit tre un nombre";
Chane identifiant l'attribut Rfrence de l'objet valeur de l'attribut
request.setAttribute("erreurAnnee",erreurAnnee);
getServletContext().getRequestDispatcher( "/accueil.jsp").forward(request, response); Philippe GENOUD -Patrick REIGNIER - UJF Janvier 2010
<input type="text" name="annee" value=" "/> <% String annee = request.getParameter("annee"); if (annee != null) out.println(annee); %>
String erreurAnnee = "Anne doit tre un nombre"; request.setAttribute("erreurAnnee",erreurAnnee); getServletContext().getRequestDispatcher( "/accueil.jsp").forward(request, response);
${param.annee} ${param.annee}
Philippe GENOUD -Patrick REIGNIER - UJF Janvier 2010
EL 52
51
connexion connexion la la BD BD
3me 3me solution solution :: pool pool de de connexions connexions
intialisation de la source de donnes au chargement du servlet contrleur
import javax.naming.* public class HistogramControleur extends HttpServlet { /** * la source de donnes qui permettra d'accder la base de donne * (c'est elle qui gre un pool de connexions, et qui fournira les * connexions aux diffrents objets en ayant l'usage). */ private DataSource dataSource;
} catch (DAOException e) { /** * A l'initialisation du servlet, cration d'un pool de connexions * qui servira fournir des connexions la base de donnes * utilise par les composants modle, et cration d'un objet INotesDAO * */ public void init() throws ServletException { try { Utilisation de l'API Context initialCtxt = new InitialContext(); JNDI DataSource dataSource = (DataSource) initialCtxt .lookup("java:comp/env/jdbc/Notes"); } catch (NamingException ne) { throw new ServletException( "problme lors de la crtion de la dataSource jdbc/Notes ", ne); }
Janvier 2010
... }
dataSource : rfrence vers la source de donnes dfinie dans les fichiers de configuration de l'application cette source donnes cr par le container (TomCat) et rcupre via l'API JDNI
53
Janvier 2010
54
...
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage()) ;
Transmission de l'objet modle en le plaant comme attribut dans la requte request.setAttribute("histoNotes", notes);
Dans la page JSP tableau.jsp <%@ <%@ page page import="model.HistogramModel" import="model.HistogramModel" %> %> <jsp:useBean <jsp:useBean id="histoNotes" id="histoNotes" class="model.HistogramModel" class="model.HistogramModel" scope="request"/> scope="request"/> ... ... <%=histoNotes.getMatiere()%> <%=histoNotes.getMatiere()%> ${requestScope.histoNotes.matiere} ${requestScope.histoNotes.matiere} EL Dans la servlet HistogramImager HistogramModel HistogramModel notes notes == (HistogramModel) (HistogramModel) request.getAttribute("histoNotes"); request.getAttribute("histoNotes");
Philippe GENOUD -Patrick REIGNIER - UJF Janvier 2010
La page JSP (tableau.jsp) ou la servlet (HistogramImager) vont exploiter l'objet histoNotes (Histogramme) cr prcdemment Comment l'objet Contrleur leur transmet cet objet ?
56
Philippe GENOUD -Patrick REIGNIER - UJF Janvier 2010
55