Annexe 2 : Pool de connexion Tomcat

publicité
Javascript Internet
Servlets
Java server Java Bean
Sommaire
1.
Introduction................................................................................................. 1
1.1
Présentation ................................................................................................................. 1
1.1.1
1.1.2
1.2
Le contexte programmation serveur ......................................................................... 2
1.2.1
1.2.2
1.2.3
1.3
Pourquoi ? .............................................................................................................. 2
Comment ? ............................................................................................................. 3
Avantages de la technologie Servlets ..................................................................... 3
Mise en œuvre .............................................................................................................. 4
1.3.1
1.3.2
1.4
Pré requis & public:................................................................................................ 1
Bibliographie .......................................................................................................... 2
Ce qu’il nous faut ................................................................................................... 4
Installations ............................................................................................................ 4
TOMCAT..................................................................................................................... 5
1.4.1
1.4.2
1.4.3
1.4.4
1.4.5
1.4.6
Démarrage .............................................................................................................. 5
Architecture du répertoire Tomcat ......................................................................... 5
Le répertoire webapps ............................................................................................ 6
Paramétrage de l’invoker de servlet ....................................................................... 6
Premiers tests.......................................................................................................... 6
Le fichier Web.xml de l’application ...................................................................... 8
1.5
Eclipse : paramétrage et compilation ...................................................................... 10
1.6
Rechargement des servlets ....................................................................................... 11
2.
Les servlets................................................................................................. 12
2.1
Premier pas ................................................................................................................ 12
2.1.1
2.1.2
2.2
Suivi de session .......................................................................................................... 15
2.2.1
2.2.2
2.2.3
2.2.4
2.2.5
2.3
L’ API Servlet ...................................................................................................... 12
Mes premières servlets ......................................................................................... 13
Les cookies ........................................................................................................... 15
L’API session ....................................................................................................... 16
Les champs de formulaire cachés......................................................................... 17
La réécriture d’URL ............................................................................................. 17
Authentification de l’utilisateur ........................................................................... 18
Gérer l’authentification avec les realms ................................................................. 18
2.3.1
Définir les rôles et les utilisateurs ........................................................................ 18
2.3.2
URL à protéger ..................................................................................................... 18
2.4
Servlet et variable d’instance ................................................................................... 19
2.5
Accès aux bases de données ...................................................................................... 22
2.5.1
2.5.2
2.5.3
2.5.4
La méthode Init et les paramètres d’initialisation ................................................ 22
La gestion des exceptions et les logs .................................................................... 23
Une simple connexion .......................................................................................... 23
Gestion des connexions ........................................................................................ 23
2.6
Communication servlet Applet ................................................................................ 26
2.7
Autres… ..................................................................................................................... 26
3.
Les Java Server Pages .............................................................................. 27
3.1
Introduction et architecture J2EE .......................................................................... 27
3.1.1
3.1.2
3.1.3
3.1.4
3.2
Premiers éléments JSP ............................................................................................. 29
3.2.1
3.2.2
3.2.3
3.2.4
3.2.5
3.2.6
3.3
Limites des servlets .............................................................................................. 27
Distinction des différents traitements ................................................................... 27
Modèle MVC et J2EE .......................................................................................... 28
Architecture de J2EE ............................................................................................ 28
Structure ............................................................................................................... 29
Traitement ............................................................................................................ 31
Utilisation d’un JavaBean .................................................................................... 31
Structure de contrôle ............................................................................................ 31
Variables locales et globale .................................................................................. 32
Déclaration de procédure ..................................................................................... 32
Gestion des paramètres ............................................................................................ 33
3.3.1
3.3.2
Récupération des paramètres de requête .............................................................. 33
Affectation des paramètres de requête à un JavaBean ......................................... 34
3.4
Gestion des erreurs ................................................................................................... 35
3.5
Création d’un JavaBean ........................................................................................... 36
3.6
Les actions personnalisées ........................................................................................ 36
3.6.1
3.6.2
3.6.3
3.6.4
Présentation .......................................................................................................... 36
Principes ............................................................................................................... 37
Utilisation d’une action de la bibliothèque .......................................................... 38
Le fichier TLD ..................................................................................................... 39
Introduction
1.1 Présentation
1.1.1 Pré requis & public:
1.1.1.1 Pré requis
-
HTML
programmation objet en Java
JDBC
1.1.1.2 Public :
Ce document est proposé à des stagiaires DI option Services Internet ayant vu
 3 semaines de JAVA dans le tronc commun
 durant 4 semaines HTML, JScript, Asp
 durant 1 semaine PHP
1.1.1.3 Durée
Tout ça en une semaine de 4.5 jours…
1.1.2 Bibliographie
Ces ouvrages ont été pour moi des références dans la mise en œuvre de ces technologies :
Tomcat par la pratique - Eyrolles
Servlets Java - Guide du programmeur - O’Reilly
Java Server Pages - O’Reilly
Et bien sur Internet le site http://java.sun.com/ pour :
 Tutorial java
 Tutorial J2EE
 API Specification J2EE
 Et bien d’autres..
Le contexte programmation serveur
1.1.3 Pourquoi ?
Utilité : création de pages dynamiques
A l’origine technologie CGI (Common Gateway Interface)
Problème : à chaque requête un processus doit être créé par le serveur , donc problème de
performance.
Evolution ensuite Fast – CGI mais guère mieux
Technologie des servlets : un processus par servlet, un thread par client
Problème dans toutes ces technologies il s’agit d’insérer de l’HTML dans du code. Ces pages
sont réservées au monde du programmeur.
Sun à donc décider de développer les JSP. Java Server Pages en s’appuyant sur les servlets.
Une JSP est donc une page HTML incluant du code, converti en Servlet par un compilateur.
1.1.4 Comment ?
Pour exécuter des JSP et des servlets il faut un conteneur de servlet le plus connu est
TOMCAT de la fondation Apache ASF(ApacheSoftwareFoundation) , projet JAKARTA
Ce conteneur écrit en JAVA fonctionne donc sur toutes les plates-formes et s’intègre à la
plupart des serveurs WEB du marché (Apache, IIS).
http://www.apache.org
http://jakarta.apache.org/
1.1.5 Avantages de la technologie Servlets
 Portabilité : fonctionne sur toutes les plates-formes
 Puissance : bénéficie de toutes les API du monde java, plate-forme J2EE
 Efficacité et endurance : un seul processus. Une fois chargée par le conteneur, la
servlet reste en mémoire et donc est disponible immédiatement.
 Sûreté :fort typage du langage JAVA, ramasse miette, gestion des exceptions
 Elégance : orienté objet
 Intégration : très proche du serveur , possibilité d’utiliser des outils
Limites : excellent pour les grosses applications, peu adapté au petits sites..
1.2 Mise en œuvre
1.2.1 Ce qu’il nous faut
- Le JDK de sun : la version standard suffit
Rem : il faudra seulement ajouter dans la bibliothèque du projet le fichier servlet.jar
qui se trouve dans le répertoire du JRE local.
A l’adresse http://java.sun.com/
- TOMCAT (qui fait aussi office d’un petit serveur WEB)
A l’adresse http://www.apache.org (item Jakarta)
- éventuellement un AGL : ex :eclipse
A l’adresse http://www.eclipse.org/
1.2.2 Installations
1.2.2.1 Installation du JDK
Double cliquer sur le fichier
1.2.2.2
TOMCAT
Double cliquer sur le fichier
NB : pour les mots de passe User :admin Pwd :admin (sinon je ne pourrais pas vous aider en
cas de problèmes….)
1.2.2.3 Eclipse
Double cliquer sur le fichier
1.3 TOMCAT
1.3.1 Démarrage
Cliquer sur Démarrer / ApacheTomcat /
Lancer votre navigateur et taper l’adresse http://localhost :8080
La page suivante doit apparaître :
Pour se connecter au serveur de votre voisin remplacer localhost par son adresse IP (
winipcfg)
Pour arrêter le serveur passer toujours par
Présentation de la page d’accueil :
Accès aux utilitaires d’administration
- administration du serveur
- gestionnaire d’application
Remarques : ces outils servent juste d’interface pour modifier les fichiers de configuration
accessibles manuellement.
Accès à la documentation
Exemples de JSP et Servlets
Mais nous n’entrerons pas en détail dans le fonctionnement de TOMCAT …
1.3.2 Architecture du répertoire Tomcat

bin : exécutable startup / shutdown

common : classes et librairies communes a toutes les applications

conf : fichiers de configuration server.xml et web.xml ( accessibles via
Administration)

logs : fichiers de logs du serveur (trace des événements, et vos propres logs)

server : répertoire des applications administration et management

webapps : répertoire par défaut des applications

work : répertoire de travail du serveur
1.3.3 Le répertoire webapps
Une application = Un répertoire pour stocker les fichiers
Dans ce répertoire (en respectant la hierarchie ci-dessous):
 La page d’accueil index.html (*)
 Vos pages JSP ou les répertoires les contenant
 Un répertoire WEB-INF qui décrit et paramètre votre application
 Le fichier web.xml paramétrage de l’application
 Le répertoire classes contenant les servlets , les beans ou les
packages de votre application
 Le répertoire lib (*) pour les fichiers jar spécifiques à l’application (sinon voir
common)
 Le répertoire tlds (*) pour les tag des actions personnalisées des JSP
 attention WEB-INF toujours en majuscule, classes, lib en minuscule sinon ça ne
fonctionne pas !!!
 pour toute application il faut un répertoire WEB-INF avec dedans fichier web.xml
1.3.4 Paramétrage de l’invoker de servlet
éditer web.xml dans le répertoire conf
enlever le commentaire entourant l'élément servlet-mapping relatif à l'invoker de
servlet
<!-- The mapping for the invoker servlet -->
<servlet-mapping>
<servlet-name>invoker</servlet-name>
<url-pattern>/servlet/*</url-pattern>
</servlet-mapping>
Rem : les commentaires XML < !--
1.3.5 Premiers tests
-->
Mise en application 1 : Exécution de la servlet HelloWorld du package tp01
Pour nos expérimentations nous créerons un répertoire workdi
Récupérer le package tp01 et le placer au bon endroit…
Ensuite invoquer la servlet en tapant son chemin sans oublier d’inclure le mot clé servlet :
http://localhost:8080/workdi/servlet/tp01.HelloWorld
à vous de jouer…
Mise en application 2 :Exécution de jsp helloWorld
Récupérer la jsp et la placer au bon endroit…
Ensuite appeler la page en tapant son chemin
http://localhost:8080/workdi/helloWorld.jsp
à vous de jouer…
et aller faire un tour dans le répertoire work/standalone/localhost/workdi que trouvez
vous ?
…. … … …. … … …. … … …. … … …. … … …. … … …. … … …. … … …. … … …. … … ….
… … …. … … …. … … …. … … …. … … …. … … …. … … …. … … …. … … …. … … …. … …
…. … … …. … … …. … … …. … … …. … … …. … … …. … … …. … … …. … …
1.3.6 Le fichier Web.xml de l’application
1.3.6.1 Nommage des servlets
Etre obligé de saisir la référence complète de la classe de la servlet est un peu lourd (ex : nom
de package et sous package..) et puis si vous changez le nom de votre classe vous devrez
modifier dans tous vos fichiers y faisant référence…
Le fichier web.xml permet de paramétrer le nommage des servlets
Rien n’empêche par la suite de définir que hello fait référence à la servlet
tp01.accueil.HelloWorld
 Attention à chaque modification du fichier Xml de l’application il faut recharger
l’application pour que les modifications soit prises en compte
 Pour vérifier la syntaxe d’un fichier XML ouvre le avec votre navigateur
1.3.6.2 Recharger le paramétrage de l’application
Lancer le gestionnaire Tomcat
Et aller dans Tomcat manager
Cliquer sur Recharger (pour l’application workdi !!)
Remarque : le fait d’arrêter et redémarrer est équivalent.
Mise en application 3 : Nommer la servlet tp01.HelloWorld en hello
Modifier votre fichier web.xml
Recharger votre contexte Workdi
Ensuite appeler la page en tapant son chemin
http://localhost:8080/workdi/servlet/hello
1.3.6.3 Mapping des servlets
Obligé de mettre le mots clé servlet… pas forcément , il suffit d’associer une URI à la servlet
Mise en application 4 Mapper la servlet hello vers Hello
Modifier votre fichier web.xml
Recharger votre contexte Workdi
Ensuite appeler la page en tapant son chemin
http://localhost:8080/workdi/Hello
Synthèse :
Le nommage permet d’appeler directement la servlet sans passer par sa classe et son package
Le mapping évite l’emploi du mot clé servlet, il nécessite le nommage
1.4 Eclipse : paramétrage et compilation
Nous allons créer un nouveau projet
Ensuite dans les propriétés du projet nous allons rajouter la librairie Servlet.jar (vous la
trouverez sur votre machine)
Et nous allons définir comme chemin de sortie pour les fichiers .class le répertoire de notre
application workdi/WEB-INF/classes
Sur la même fenêtre cliquer sur Browse
Puis cliquer sur créer un nouveau répertoire
Nommer le répertoire output et le lier au répertoire classes de votre application workdi
Dans votre projet servlet créer un package tp01 .
Mise en application 5 Compiler la servlet Bonjour.java
Copier avec l’explorateur de windows le fichier Bonjour.java dans le répertoire
Servlet\tp01 puis sélectionner refresh pour votre projet
Dans le répertoire workdi/…/ classes vous devez trouver le fichier Bonjour.class
Invoquer la servlet
http://localhost:8080/workdi/servlet/tp01.Bonjour
1.5 Rechargement des servlets
Il souhaitable de vérifier que le contexte WorkDi soit paramètré de façon à recharger
automatiquement, lors du prochain appel, une servlet lorsque son fichier class change.
Lancer Tomcat Administration http://localhost:8080/
2. Les servlets
2.1 Premier pas
2.1.1 L’ API Servlet
La classe GenericServlet
indépendante du protocole.
du package javax.servlet permet d’implémenter une servlet
La classe HTTPServlet du package javax.servlet.HttpServlet propose les méthodes doGet et
doPost permettant de traiter les requêtes du serveur.
2.1.2 Mes premières servlets
package tp01;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class HelloWorld extends HttpServlet {
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException
{
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println( "helloworld this is my servlet" );
}
}
Penser à l’aide http://java.sun.com/j2ee/1.4/docs/api/index.html
Dans les méthodes get et post deux paramètres :
Entrée : un objet HttpServletRequest
Sortie : un objet HttpServletResponse
Avec l’objet HttpServletRequest on peut récupérer en utilisant la méthode getSession un objet
de type HttpSession
Mise en application 6
Affichage d’informations
En utilisant les objets request et session afficher les informations suivantes en créant une
servlet Infos.class dans le package tp01 :
Date
Identifiant de session
Remote adresse
Utilisateur
Chemin du contexte
Chemin de la servlet
Chemin réel
Pour récupérer les champs d’un formulaire utiliser la méthode getParameter(nomduchamp)
Mise en application 7 Gestion des paramètres
Soit la page html suivante : NumberGuess.html
Dont le formulaire invoque la servlet
le nom du champ est guess
Implémenter la méthode doGet (tp01.NumberGuess.class) de façon à afficher « trop bas
trop haut ou gagné »
Rem :
int number = (int) (Math.random()*100)
Mise en application 8 Le post et le get
Implémenter doPost de façon à ce qu’il appelle le doGet
Et modifier la page html
Que remarquez – vous ?
…. … … …. … … …. … … …. … … …. … … …. … … …. … … …. … … …. … … …. … … ….
… … …. … … …. … … …. … … …. … … …. … … …. … … …. … … …. … … …. … … …. … …
…. … … …. … … …. … … …. … … …. … … …. … … …. … … …. … … …. … …
Rem : La methode HttpRequest.getParametersNames() renvoie la liste de tous les nom de paramètres d’un
formulaire
GET :





Utilisé lorsqu’on rentre une URL dans le navigateur
Si il y a des paramètres ils sont ajoutés à l’URL
La page peut être ajoutée aux signets
Ne pas utiliser pour les mises à jour critiques
Page rechargeable
POST :
 Paramètres non visibles
 Grosse quantité d’information
 Sécurité : paramètres non journalisés par le serveur
2.2 Suivi de session
Http est un protocole sans état : il ne fournit aucun moyen à un serveur de reconnaître
qu’une séquence de requêtes proviennent toutes du même client. La solution est que le client
se présente à chaque requête. Il existe différents moyens de suivre une session :
 Les cookies persistants
 L’ API suivi de session
 Les champs de formulaire cachés
 La réécriture d’URL
 L’authentification de l’utilisateur
2.2.1 Les cookies
L’API servlet fournit la classe javax.servlet.http.Cookie pour travailler avec les cookies.
Pour créer un cookie il suffit d’appeler le constructeur dont la signature est la suivante:
public Cookie(String name,String value)
Et ensuite de l’enregistrer en appelant la methode du paramètre response.
public void HttpServletResponse.AddCookie(Cookie cookie) .
Une servlet retrouve les cookies en appelant la methode du paramètre request
public Cookies[] HttpServletRequest.getCookies()
Exemple : Affichage des cookies
Cookies[] cookies=req.getCookies() ;
if (cookies != null) {
for (int i=0;i< cookies.length;i++) {
String name=cookies[i].getName();
String value=cookies[i].getValue();
}
}
Remarques : il est utile dans un package d’avoir une méthode permettant de rechercher un
cookie par son nom :
static public String Tools.searchCookie(Cookie[] cookies,String cookieName) (package Tools fourni)
Par défaut le cookie vit durant toute la session. Il est possible de modifier la durée en utilisant
la méthode :
Cookies.setMaxAge(int expiry) ou int est la durée en seconde.
La taille d’un cookie est limitée à 4096 ko.
Mise en application 9 Les cookies
Soit les servlets tp02.AffCookie et tp02.SetCookie qui permettent d’enregistrer une serie
de cookies .
La servlet AffCookie permet la saisie et l’affichage
Sur le bouton Deposer on invoque la servlet SetCookie qui permet d’enregistrer les valeurs
des champs dans des cookies.
Règles :
Pour enregistrer un cookie le champ nom et valeur ne peut etre null.
En cas de succès
Continuer envoi vers la page d’accueil
En cas d’erreur , on redirigera la réponse vers la page AffCookie . en passant le message
d’erreur via les paramètre Err .
La servlet AffCookie affiche la liste des cookies de la session. Elle affiche ensuite le
formulaire et le message d’erreur éventuel.
Les cookies sont enregistrés par votre navigateur sur votre machine c:\windows\cookies ( en général)
Rem : pour rediriger vers une page on utilise la méthode HttpResponse.sendRedirect(String url)
exemple : response.sendRedirect(request.getContextPath()+"/servlet/tp03.AffCookie?Err="+error);
2.2.2 L’API session
Les servlets intègrent le suivi de session . Chaque utilisateur d’un site est associé à un objet
javax.servlet.http.HttpSession que les servlets utilisent pour stocker ou retrouver les
informations sur l’utilisateur.
Pour stocker une information on utilise la méthode setAttribute(String key ,Object value)
HttpSession session=request.getSession();
session.setAttribute(“Nom”,user);
et HttpSession.getAttribute(String key) pour récupérer la valeur.
ou HttpSession.getAttributeNames() pour récupérer les noms des attributs
Mise en application 10 Le suivi de session
Reprendre l’exercice précédent sans utiliser les cookies. On nommera les servlets
AffSession et SetSession
Avantage : on stocke n’importe quel type d’objet , pas de limitation de taille , technique à
privilégier.
2.2.3 Les champs de formulaire cachés
Comme son nom l’indique ces champs sont ajouté au formulaire HTML mais ne sont pas
affichés par le navigateur.
Exemple :
<FORM ACTION= « …… » METHOD= « POST »>
<INPUT TYPE=”hidden” NAME=”User” VALUE=”Durand”>
<INPUT TYPE=”hidden” NAME=”NbVisite” VALUE=”11”>
</FORM>
2.2.4 La réécriture d’URL
Chaque URL est modifiée de façon à inclure des informations supplémentaires. Ces
informations sont gérés comme des paramètres supplémentaires.
La méthode HttpResponse.encodeURL(String url) permet de récrire l’URL en y incluant
l’identifiant de session.
La méthode java.net.URLEncoder.encode(String value) permet de coder en unicode les
caractères spéciaux.
Exemple : "<HREF='"+response.encodeURL("/servlet/help")+"'</HREF>"
2.2.5 Authentification de l’utilisateur
La méthode request.getRemoteUser() permet de récupérer le paramètre j_username qui
contient le nom de l’utilisateur . La contrainte est qu’il faut protéger l’accès aux différentes
pages et forcer l’utilisateur à s’identifier.
<form method="POST" action="j_security_check">
<p> Utilisateur <input type=TEXT name="j_username" size="20"></p>
<p> Mot de passe <input type=PASSWORD name="j_password" size="20"></p>
<p><input type=SUBMIT value="login"></p>
</form>
Tomcat permet de sécuriser l’accès aux différents éléments de l’application
2.3 Gérer l’authentification avec les realms
Pour gérer l’authentification avec les realms il est nécessaire de
- définir des rôles
- définir des utilisateurs et les rôles auxquels ils appartiennent
- définir les URL à protéger
- définir le type de page de login
- définir la page d’erreur de login
2.3.1 Définir les rôles et les utilisateurs
Le fichier tomcat-user.xml du répertoire conf.
<?xml version="1.0" encoding="utf-8" ?>
- <tomcat-users>
<role rolename="tomcat" />
<role rolename="manager" />
<role rolename="admin" />
<role rolename="stduser" description="utilisateur standard" />
<user username="di" password="di" fullName="stagiaire DI" roles="stduser" />
<user username="tomcat" password="tomcat" roles="tomcat" />
<user username="jdc" password="jdc" fullName="Jean DAvid" roles="admin,manager,stduser,tomcat" />
<user username="role1" password="tomcat" roles="role1" />
<user username="both" password="tomcat" roles="tomcat,role1" />
<user username="admin" password="admin" roles="admin,manager" />
</tomcat-users>
Exemple : Ici le fichier initial a été modifié :
définition du role stduser
définition du username DI avec le role stduser
définition du username JDC avec le role stduser,admin,manager,tomcat
On peut également faire ces modifications en utilisant Tomcat Administration :
2.3.2 URL à protéger
Le fichier web.xml de l’application permet de gérer ce paramétrage :
<!-- Security is active on entire directory -->
<security-constraint>
<display-name>Working Security Constraint</display-name>
<web-resource-collection>
<web-resource-name>Work protetected</web-resource-name>
<!-- Define the context-relative URL(s) to
<url-pattern>/servlet/*</url-pattern>
<url-pattern>*.html</url-pattern>
</web-resource-collection>
<auth-constraint>
<!-- Anyone with one of the listed roles
<role-name>stduser</role-name>
</auth-constraint>
be protected -->
Les URL à protéger
may access this area -->
Les rôles autorisés
</security-constraint>
<!-- Login configuration uses form-based authentication -->
<login-config>
<auth-method>FORM</auth-method>
<realm-name>Essais de protection</realm-name>
<form-login-config>
<form-login-page>/login.html</form-login-page>
<form-error-page>/error.html</form-error-page>
</form-login-config>
</login-config>
<!-- Security roles referenced by this web application -->
<security-role>
<description>Les rôles en jeu pour cette application</description>
<role-name>stduser</role-name>
</security-role>
Le type
d’authentification
Les FORM de
login et d’erreur
Les rôles mis en jeu
Remarques <auth-method> peut prendre différentes valeurs:
BASIC : formulaire par défaut avec info envoyée en clair
DIGEST : formulaire par défaut avec information codée
FORM : formulaire défini par le programmeur
CLIENT-CERT : formulaire par défaut basé sur les certificats
Mise en application 11 Protection d’URL
Créer dans webapps un répertoire workdi_sc (security constraint).
Copier une de vos servlets (ex : Infos.class), dans le repertoire WEB-INF/classes
Créer les pages error et login
Paramétrer le rôle stduser et l’utilisateur DI
Modifier le fichier WEB-XML afin de définir les contraintes de sécurité à partir du fichier
web_sec.txt
Invoquer votre servlet : vous devez passer obligatoirement par la page de login
2.4 Servlet et variable d’instance
Soit la servlet suivante qui permet de compter et d’afficher le nombre de fois que l’on y a
accédé.
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class SimpleCounter extends HttpServlet {
int count = 0;
public void doGet(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
res.setContentType("text/plain");
PrintWriter out = res.getWriter();
count++;
out.println("Since loading, this servlet has been accessed " +
count + " times.");
}
Deux clients invoquent la servlet selon le
principe de base des servlets une seule
instance de la servlet et crée mais deux
thread sont actifs
Lorsque nous écrivons notre code nous
supposons que les instructions count++ et
println ne sont pas dissociés. Or la JVM
pourrait exécuter les instructions comme
ceci :
count++
count++
println
println
//thread 1
//thread 2
(.. //thread 1
(.. //thread 2
et ce n’est pas ce que l’on voulait !!!
La solution est d’interdire la dissociation de ces instructions en les synchronisant .
Pour synchroniser ces deux lignes différentes solutions sont possibles
 Synchronisation du doGet
public synchronized void doGet(HttpServletRequest req,
HttpServletResponse res)
throws ServletException, IOException
Inconvénient : la servlet ne peut traiter qu’une requête à la fois
 Synchronisation des deux lignes
synchronized (this) {
count++;
out.println("Since loading, this servlet has been accessed " +
count + " times.");
}
Inconvénient : si le bloc comprends des instructions dont le temps est non négligeable, les
autres blocs ne peuvent pas être exécutés.
 Synchronisation de l’accès à la variable critique
synchronized (this) {
localCount = ++ count
procédure
}
//local count étant une variable de la
Attention trop de synchronisation pénalise les performances de votre application
2.5 Accès aux bases de données
2.5.1 La méthode Init et les paramètres d’initialisation
Au chargement de la servlet la méthode init est appelé, c’est le moment de charger les
paramètres d’initialisation de la servlets définis dans le fichier web.xml
Exemple :
public class DbServlet extends HttpServlet {
public void init (ServletConfig Config) trows ServletException
{
super.init(config);
String driver=config.getInitParameter(« database-driver-class »);
String jdbcUrl=config.getInitParameter(« database-url »);
}
}
et le fichier web.xml
</servlet>
<servlet-name>bdd</servlet-name>
<servlet-class>BdServlet</servlet-class>
<init-param>
<param-name>database-driver-class</param-name>
<param-value>oracle.jdbc.driver.OracleDriver</param-value >
</init-param>
<init-param>
<param-name>database-url</param-name>
<param-value>jdbc:oracle:thin:@linuxser.afpa:1521:fpa1</param-value >
</init-param>
</servlet>
Rem : pour une base access
pont ODBC : sun.jdbc.odbc.JdbcOdbcDriver
URL jdbc :odbc :Alias
pont MySQL : org.gjt.mm.mysql.Driver
URLjdbc:mySql://localhost:3306/Database
Si on utilise un driver de type 3 (Oracle,MySql) il faut penser à mettre dans
common\lib le fichier correspondant (Ex :classe12.jar pour oracle)
2.5.2 La gestion des exceptions et les logs
Il est possible de tracer les erreurs dans un fichier de log, répertoire \logs en utilisant la
méthode HttpServlet.log(String text)
Il est possible de générer sa propre page d’erreur sur une exception
Http.Response.sendError(int sc,String msg)
int sc étant le code d’état HTTP
2.5.3 Une simple connexion
Mise en application 12 Listing des tables architecture 3/tiers
Nous allons nous connecter à une base ORACLE
URL (bip-vénissieux): jdbc:oracle:thin:@linuxser.afpa:1521:fpa1
User ORAxx Pwd ORAxx
Exercice idem sur un autre base ex : access sauf driver Odbc
Créer la servlet tp03.ListingBdd avec une variable d’instance con de type Connection.
Dans la méthode init charger le driver (les paramètres seront dans le fichier XML) .
Tracer une éventuelle erreur dans le log
Dans la méthode doGet instanciation de la connexion (usr et pwd seront des paramètres de
la requête) et lister les tables de la base SELECT * FROM ALL_TABLES (uniquement
Oracle) en utilisant une objet Statement et un objet ResultSet.
Les exceptions générerons une redirection vers une page d’erreur standard
2.5.4 Gestion des connexions
2.5.4.1 Difficultés
La stratégie de gestion des connexions reste quelque chose de délicat :

Le temps d’allocation d’une connexion est long , ouvrir une connexion lors de l’accès
à chaque page n’est pas viable.

Lors d’ une transaction commerciale, en général la transaction se fait sur plusieurs
pages, d’ou la nécessité de mémoriser la connexion.

Associer une connexion à un utilisateur dés son arrivée sur un site est difficile à gérer
si un grand nombre de client est prévisible , un serveur ne pouvant gérer en moyenne
que100 connexions maximum.
2.5.4.2 Les pools de connexions
Une solution performante est d’utiliser un pool de connexion, cela consiste à gérer une liste
de connexion et de les mettre à disposition des servlets
Mise en œuvre logicielle
Une liste de connexion est mémorisée (ex : comme attribut statique d’une classe)
Lors d’un appel à la servlet, le thread demande à la liste une connexion. Si une connexion
est disponible il retourne cette dernière sinon il en crée une nouvelle.
Voir : Annexe 1
Mise en œuvre sous Tomcat
Tomcat permet de gérer les pools de connexion , pour récupérer une connexion il suffit
alors d’appeler la méthode public Connection DataSource.getConnection(String usr,String pwd);
2.5.4.3 Association de connexion à la session
Si l’on associe une connexion à la session, la difficulté est que lorsque la session se
termine inopinément il faut pouvoir libérer la connexion.
L’interface javax.servlet.HttpSessionBindingListenner permet de capturer l’événement de
fin et début de session.
Pour mettre fin manuellement à une session on utilise la méthode HttpSession.invalidate()
Mise en œuvre : classe container d’une connexion
class ConContainer implements HttpSessionBindingListener {
private Connection con =null;
public java.util.Date created=new java.util.Date();
public ConnectionHolder(Connection con){
this.con=con;
try { con.setAutoCommit(false);}catch (SQLException e) {}
}
public Connection getConnection() {return con;}
public void valueUnbound(HttpSessionBindingEvent event) {
//lors de la dissociation fermeture de la connexion
try {
if (con != null) {
con.rollback();
con.close();
}
}catch (SQLException e) {}
}
public void valueBound(HttpSessionBindingEvent event) {
// rien à faire lors de l'association
}
}
Utilisation :
Dans la servlet pour récupérer une connexion il suffit de faire :
ConContainer c=(ConContainer)session.getAttribute("servlet.connection");
if (c==null) {
try {
c=new ConnectionHolder(DriverManager.getConnection(url,usr,pwd));
session.setAttribute("servlet.connection",c);
con=c.getConnection();
} catch (SQLException e){}
} else {
con=c.getConnection();
out.println("<PRE> connecté le "+c.created+"</PRE>");
}
Mise en application 13 un livre de message
Mise en œuvre initiale : on crée la connexion à chaque appel
Créer une base de donnée Access ( driver ODBC)
ou MySQL (driver : org.gjt.mm.mysql.Driver)
Créer une table msgList avec comme champs :
id Long (key), Name char(15),email char(30),cmt char(255)
La servlet tp03.MsgBook permettra de poster un nouveau message avec nom et e-mail du
rédacteur et affichera la liste des 10 messages les plus récent du livre.
Optionnel :
Il y aura un lien vers une page de recherche des messages selon différents critères :
Message contenant une texte particulier
Exemple d’interface :
Cas
Cas
a : Sauvegarde de la connexion dans la session avec bindingEvent
b :Mise en place d’un pool de connexion :Logiciel et/ou matériel
2.6 Communication servlet Applet
Une Applet est exécutée par la JVM du client, pour des raisons de sécurité les fonctionnalités
d’une Applet au niveau gestion de ressources sont très limitées. Cet inconvénient est inhibé
en créant une servlet d’accès au ressources et en faisant communiquer l’Applet avec la servlet.
Ces technologies ne seront pas abordées ici : http,Socket,RMI….
2.7 Autres…

Gestion du multilangue grâce aux possibilités d’internationalisation du JDK1.1

Environnement de développement Tea : un développeur crée les applications écrites
en JAVA et installées dans TeaServlet. Un producteur crée et maintient l’apparence
des pages WEB dynamiques en écrivant des modèles Tea qui appellent les fonctions
fournies par les applications du développeur.

Environnement WebMacro : moteur de template , système remplaçant un texte dans
des modèles de page Web. La servlet exécute sa logique métier, crée un objet de
réponse contenant le résultat métier puis sélectionne un fichier modèle afin de générer
le contenu client.

Et bien d’autres oublis ….
3. Les Java Server Pages
3.1 Introduction et architecture J2EE
3.1.1 Limites des servlets
La solution de développer des composants CGI, servlet est basée sur de la programmation
incluant de l’HTML ce qui limite la création de site Web dynamique au monde des
programmeurs .
Les JSP partent dans la direction opposée mettre du code dans des pages HTML. C’est
pareil ? Non, car les différentes fonctions du traitement sont dissociées et attribuées selon
différentes compétences.
JSP est une spécification et non un produit.
JAVA est la langage par défaut des JSP mais la spécification autorise l’utilisation d’autre
langage comme JavaScript,Vbscript , Perl
3.1.2 Distinction des différents traitements
Un JavaBean est un composant offrant des services à l’application.
3.1.3 Modèle MVC et J2EE
Modèle , Vue , Contrôleur ( revoir UML)
En fait il s’agit d’une combinaison JSP,Servlet, Java Bean en fonction des rôles attribués :
JSP, HTML : affichage, saisie , c’est l’interface
Servlet : processus , c’est le moteur du système
JavaBean : métier , c’est la logique de l’application
3.1.4 Architecture de J2EE
3.2 Premiers éléments JSP
3.2.1 Structure
Une page JSP est composée de :
 Texte template : HTML, XML, texte en clair
 Eléments JSP qui sont :
o Des directives
o Des actions (standard, personnalisé )
o Des éléments de script (scriptlet, expression, déclaration)
Exemple :
<%@ page language="java" contentType="text/html" %>
<%! int globalCounter = 0; %>
<html>
<head>
<title>Page avec un compteur</title>
</head>
<body bgcolor="white">
<jsp:useBean id="clock" class="java.util.Date" />
<%= clock.toString() %>
<p>
Cette page a été visitée : <%= ++globalCounter %> fois.
<p>
</body>
</html>
3.2.1.1 Directives
<@ page … >
Description des attributs dépendant de la page comme le langage de
script, la page d’erreur
<@ include >
Inclut un fichier pendant la phase de traduction
<@taglib ..>
Déclare une bibliothèque de balises contenant les actions personnalisées
utilisées dans la page
voir Annexe 3
3.2.1.2 Actions standard
<jsp :useBean>
Rend un composant JavaBean disponible dans la page
<jsp :getProperty> Obtient la valeur d’une propriété d’un composant JavaBean et de
l’ajouter à la réponse
<jsp :setProperty> Définit la valeur d’une propriétés d’un JavaBean
<jsp :include>
Inclut la réponse d’une servlet ou d’une page JSP pendant la phases de
traitement de la requete
<jsp :forward>
Redirige le traitement de la requête vers une servlet ou une page JSP
<jsp :param>
Ajoute la valeur d’un paramètre à une requête traitée par une autre
servlet ou une autre page JSP indiqué dans une action include ou forward
<jsp :plugin>
Génère le code HTML qui contient les éléments dépendants du
navigateur adéquats (Object ou Embed) nécessaire à l’exécution d’une applet avec le logiciel
JavaPlugIn
3.2.1.3 Actions personnalisés
Voir chapitre à ce sujet 3.6
3.2.1.4 Eléments de script
<% %>
Scriptlet, utilisée pour embarquer du code script
<%= %>
expression, utilisée pour embarquer des expressions quand le résultat doit être
ajouté à la réponse. Utilisée aussi à l’exécution comme valeurs d’attribut pour les actions
<%! >
Déclaration, utilisée pour déclarer des variables d’instance et des méthodes
dans la classe d’implémentation de la classe JSP.
Dans éléments de script des objets implicites sont disponibles :
Voici la liste des objets accessibles implicitement depuis toute scriptlet :
Objet
request
Dérivé de
Description
javax.servlet.ServletRequest Objet contenant la requête du client
Objet contenant la réponse de la page JSP. Cet objet utilisé
response
javax.servlet.ServletResponse avec les servlets ne l'est généralement pas avec les JSP,
puisque le code HTML est directement créé
Objet contenant des informations sur l'environnement du
pageContext javax.servlet.jsp.PageContext
serveur
session
javax.servlet.http.HttpSession Objet contenant la session en cours
application javax.servlet.ServletContext Objet contenant le contexte de servlet
out
javax.servlet.jsp.JspWriter
Objet contenant le flux de sortie
config
javax.servlet.ServletConfig
Objet contenant la configuration de la servlet
page
java.lang.Object
Objet désignant la page elle-même (équivalent à this)
exception
java.lang.Throwable
Objet représentant une exception non interceptée
© Copyright 2004 Jean-François Pillou -
3.2.1.5 Commenatires
<%---%>
Tout texte placé entre ces deux marqueurs est ignoré.
3.2.2 Traitement
Les JSP bénéficient de la puissance des servlet car elles sont traités comme des servlets.
Le compilateur s’appelle JASPER
3.2.3 Utilisation d’un JavaBean
En JAVA nous avons vu que nous utilisions tout le temps des objets que nous instancions
avec la méthode new .
Utiliser un objet c’est utiliser un JavaBean.
<jsp :usebean id= « nom de l’objet » classe= « nom de la classe »/>
L’attribut scope de jsp :useBean permet de définir la porté du bean, quatre valeurs sont
possibles : page, request, session, application
Pour afficher l’information il faut appeler la méthode ou l’attribut de l’objet
<jsp :getProperty name= « nom de l’objet » property= « nom de propriétés »/
on peut directement appeler la méthode ou l’attribut de l’objet
<%= objet.methode() %>
équivallent à <% out.println(objet.method()) %>
seule la première syntaxe est du « vrai »JSP (pas de connaissance de programmation..)
Mise en application 1 Affichage de la date
page date1.jsp
Affichage de la date
Et du détail.
3.2.4 Structure de contrôle
Ce sont les même qu’en Java puisque c’est du Java…
Exemple pour le if :
<% if (chiffre==4) { %>
Vous avez trouvé le bon chiffre
<% } else { %>
Perdu
<% } %>
Le conteneur de JSP combine le code des 3 scriplets et les templates .
Mise en application 2 Sélection sur la date
page date2.jsp
Affichage de Bonsoir si l’heure est supérieure à 12 sinon Bonjour.
3.2.5 Variables locales et globale
Une variable déclarée en début de page après les directives <@ est traduite comme une
variable d’instance. <%! int globalCounter >
Une variable déclarée dans une scriplet est considérée comme une variable locale <% int
localCounter%>
Attention les variables globales sont donc partagées par tous les clients ….
A éviter sauf dans des cas bien précis : exemple compteur d’accès
Mise en application 3 Compteur d’accés
page counter.jsp
Créer une variable globale et une variable locale
Incrémenter les deux variables et afficher les deux valeurs
A voir : La locale ne varie pas, la générale est commune à tous les clients
3.2.6 Déclaration de procédure
La déclaration se fait avec une balise <% !
Exemple :
<% ! public void Hello() {
out.println(« Hello ») ;
} %>
3.3 Gestion des paramètres
3.3.1 Récupération des paramètres de requête
L’objet request propose la méthode getParameter (String paramName) qui retourne la valeur
du paramètre spécifié ou getParameterValues(String paramName) pour des listes de valeurs
Exemple :
String name = request.getParameter ("name");
String[] picked = request.getParameterValues("selection");
getParameterValues renvoie null si le paramètre n’est pas renseigné il faut donc
tester le retour de cette méthode
Mise en application 4 Questionnaire
page quest.jsp
Créer un formulaire comme ci-dessous qui réappelle la même page pour le traitement
Pour le traitement afficher les infos saisie par l’utilisateur
Remarques : Dans vos script, pensez à la syntaxe : =expression1 ? val1 : val2
3.3.2 Affectation des paramètres de requête à un JavaBean
Dans de nombreux cas, il est utile de stocker les paramètres de requête pour les traitements du
processus. Passer par un JavaBean simplifie le problème.
Soit le JavaBean de classe DataQuest avec comme propriété name et selection. Pour affecter
les paramètres name et selection de notre questionnaire (remarquez qu’ils portent le même
nom), il suffit lors de l’appel de JavaBean de déclarer :
<jsp :useBean id=monBean class=DataQuest>
<jsp:setProperty name= “monBean” property=”*”/>
</jsp :useBean >
On initialise la propriété *, c’est à dire toutes les propriétés avec les valeurs des paramètres
dont les nom et types correspondent au propriétés.
Mise en application 5 javeBean userInfo
page userInfo.jsp
Créer le formulaire userInfo.html qui appelera pour le traitement la page userInfo.jsp
La page userInfo.jsp stockera les paramètres dans le JavaBean tpBean.UserInfoBean. et
restituera les propriétés de ce bean afin d’obtenir l’affichage suivant.
Propriétés du bean :
userName, birthDate, emailAddr, sex, luckyNumber, valid, propertyStatusMsg
Remarques : pour forcer l’utilisateur à ressaisir jusqu’à validité voir l’exemple en annexe 4
3.4 Gestion des erreurs
La directive <%@page errorPage= permet de définir la page d’erreur à appeler en cas
d’exception non géré.
La page d’erreur contient la directive <%@ page isErrorPage= « true » %>
Dans la page d’erreur on peut utiliser la méthode exception.getMessage() pour avoir le message
d’erreur.
Pour connaître la page qui à généré l’erreur il faut au préalable avoir enregistré cette
information en utilisant request.setAttribute(« sourcePage »,request.getRequestUri())
Puis dans la page d’erreur on récupère l’information request.getAttribute(« sourcePage »)
Mise en application 7 Gestion d’erreur
page division.jsp
Créer la page divion.jsp qui permet d’afficher le résultat de la division de deux entiers.
et page d’erreur errordiv.jsp qui affiche le message d’erreur et l’URI de la page source
3.5 Création d’un JavaBean
Un JavaBean est une classe Java qui respectent certaines directives dont les principales sont
les suivantes :
 Implémente l’interface Serialisable afin d’assurer la persistance
 Les propriétés sont accessible via les assesseurs les set et get dont le nom correspond
à la propriété du bean
Exemple
public class User implements java.io.Serializable {
private string user
public void setUser(String user)
this.user=user;
}
public String getUser() {
return this.user;
}
}
donc dans la JSP
<jsp:getProperty …… property=”user”
Mise en application 7 Création d’un bean de calcul epargne
JavaBean tpBean.CountBean et pages countInfo.html countInfo.jsp
Propriété du JavaBean
durée durée en mois
taux taux d’interét
versement
versement mensuel
montant
montant au bout de la durée en fct du taux
Sans prendre une formule compliquée Montant = Montant * (Taux//12) + Versement
( à répéter durée fois)
3.6 Les actions personnalisées
3.6.1 Présentation
Soit un JavaBean monBean qui possède une méthode non standard (les seules méthodes
standard sont les assesseurs)
public int maMethode(int value)
Pour utiliser cette méthode on est obligé de passer par les scriplets. Or l’utilisation des
JavaBean est là pour éviter le code dans la JSP.
Les actions personnalisées permettent ce type d’action
Les actions personnalisées sont définies dans des librairies appelées bibliothèques de balises.
Un bibliothèque de balise contient un fichier descripteur de balise TLD Tag Lib Descriptor
3.6.2 Principes
Un action personnalisée est un JavaBean héritant de l’une des deux classes TagSupport ou
BodyTagSupport. Afin d’implémenter l’une des interfaces Tag ou BodyTag
Exemple :
import javax.servlet.jsp.tagext.* ;
public class monAction extends TagSupport {
private String nom ;
public void setNom(String nom){
this.nom=nom ;
}
public int doEndTag() throws JspException{
try {pageContext.getOut().println(« Bonjour »+nom) ;}
catch (IOException) {
throw new JspException(e.toString()) ;}
return EVAL_PAGE ;
}
}
Pour avoir un traitement dans le corps de l’action il faut implémenter BodyTag
Et ça devient plus délicat.. on ne verra pas cela… mais c’est tout l’interêt des JSP (Annexe 5 )
3.6.3 Utilisation d’une action de la bibliothèque
Pour utiliser une librairie il faut utiliser la directive
<@ taglib uri=
« uri symbolique » prefixe= « lib » %>
et dans ce cas dans le fichier xml définir vers quel fichier TLD pointe cette uri
<taglib>
<taglib-uri>
\maLib
</taglib-uri>
<taglib-location>
/WEB-INF/tlds/mesActions_1_02.tld
</taglib-location>
</taglib>
ou
<@ taglib uri=
« uri du TLD »
prefixe= « lib » %>
Remarque : l’intérêt de passer par le fichier xml et que si le nom du fichier TLD change
(modification de version ) vous n’avez pas à modifier toutes les pages JSP de votre
application !!!)
nous pourrons alors utiliser une action de la bibliothèque :
<lib :action ….
Exemple :
<lib:monAction name= « Durand » />
3.6.4 Le fichier TLD
Il faut définir à quoi correspond notre uri de bibliothèque.
Cela se fait dans le fichier web-xml
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE taglib
PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.1//EN"
"http://java.sun.com/j2ee/dtds/web-jsptaglibrary_1_1.dtd">
<!-- The tag library descriptor -->
<taglib>
<!-- Basic library information -->
<tlibversion>1.0</tlibversion>
<jspversion>1.1</jspversion>
<shortname>tools</shortname>
<info>
Déclaration de notre action
</info>
<tag>
<name>monAction</name>
<tagclass>tpBean.monAction</tagclass>
<bodycontent>JSP</bodycontent>
<attribute>
<name>name</name>
<required>true</required>
</attribute>
</tag>
</taglib>
Mise en application 8 Création d’une action personnalisé visu du contenu d’une table d’une
base de donnée
JavaBean tpBean.bddInfo et page bddInfoBean.jsp
Idem : Servlet livre d’or
Créer une base de donnée Access ( driver ODBC)
ou MySQL (driver : org.gjt.mm.mysql.Driver)
Créer une table msgList avec comme champs :
id Long (key), Name char(15),email char(30),cmt char(255)
Propriétés de l’action
Affiche le résultat de SELECT * FROM msgList sous forme soit de :
table <table> <tr> <td>
liste <li>
selon la valeur du paramètre presentation de l’action
Rem :
- le nom du driver et l’URL de la base seront des attributs static du bean.d’action.
- le driver sera chargé au niveau du constructeur
Annexe1 : pool de connexion logiciel
import java.sql.*;
import java.util.*;
public class ConnectionPool {
private Hashtable connections = new Hashtable();
private Properties props;
public ConnectionPool(Properties props, int initialConnections)
throws SQLException, ClassNotFoundException {
this.props = props;
initializePool(props, initialConnections);
}
public ConnectionPool(String driverClassName, String dbURL,
String user, String password,
int initialConnections)
throws SQLException, ClassNotFoundException {
props = new Properties();
props.put("connection.driver", driverClassName);
props.put("connection.url", dbURL);
props.put("user", user);
props.put("password", password);
initializePool(props, initialConnections);
}
public Connection getConnection() throws SQLException {
Connection con = null;
Enumeration cons = connections.keys();
synchronized (connections) {
while(cons.hasMoreElements()) {
con = (Connection)cons.nextElement();
Boolean b = (Boolean)connections.get(con);
if (b == Boolean.FALSE) {
try { con.setAutoCommit(true); }
catch(SQLException e) { // Problem with the connection, replace it.
try { con.close(); } catch (SQLException ignored) { }
connections.remove(con);
con = getNewConnection();
}
connections.put(con, Boolean.TRUE);
return con;
}
}
// If we get here, there were no free connections. Make one more.
con = getNewConnection();
connections.put(con, Boolean.FALSE);
return con;
}
}
public void returnConnection(Connection returned) {
if (connections.containsKey(returned)) {
connections.put(returned, Boolean.FALSE);
}
}
private void initializePool(Properties props, int initialConnections)
throws SQLException, ClassNotFoundException {
Class.forName(props.getProperty("connection.driver"));
// Put our pool of Connections in the Hashtable
// The FALSE value indicates they're unused
for(int i = 0; i < initialConnections; i++) {
Connection con = getNewConnection();
connections.put(con, Boolean.FALSE);
}
}
private Connection getNewConnection() throws SQLException {
return DriverManager.getConnection(
props.getProperty("connection.url"), props);
}
}
Utilisation
import
import
import
import
java.io.*;
java.sql.*;
javax.servlet.*;
javax.servlet.http.*;
public class OrderHandlerPool extends HttpServlet {
private ConnectionPool pool;
public void init() throws ServletException {
try {
pool = new ConnectionPool("oracle.jdbc.driver.OracleDriver",
"jdbc:oracle:oci7:orders", "user", "passwd", 5);
}
catch (Exception e) {
throw new UnavailableException("Couldn't create connection pool");
}
}
public void doPost(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
Connection con = null;
res.setContentType("text/plain");
PrintWriter out = res.getWriter();
try {
con = pool.getConnection();
// Turn on transactions
con.setAutoCommit(false);
Statement stmt = con.createStatement();
stmt.executeUpdate(
"UPDATE INVENTORY SET STOCK = (STOCK - 10) WHERE PRODUCTID = 7");
stmt.executeUpdate(
"UPDATE SHIPPING SET SHIPPED = (SHIPPED + 10) WHERE PRODUCTID = 7");
//chargeCard(); // method doesn't actually exist...
con.commit();
out.println("Order successful! Thanks for your business!");
}
catch (Exception e) {
// Any error is grounds for rollback
try {
con.rollback();
}
catch (Exception ignored) { }
out.println("Order failed. Please contact technical support.");
}
finally {
if (con != null) pool.returnConnection(con);
}
}
}
Annexe 2 : Pool de connexion Tomcat
import javax.naming.InitialContext;
import javax.naming.*;
import oracle.jdbc.pool.*;
public class PoolTomcat extends HttpServlet {
private static OracleDataSource ds;
public void init(){
//Récupération du DataSource
Context initCtx=new InitialContext();
Context envCtx=(Context) initCtx.lookup("java:comp/env");
ds=(OracleDataSource) envCtx.lookup("jdbc/testOracle");
}
public void doGet(HttpServletRequest request, HttpServletResponse
response) throws IOException, ServletException {
Connection con= ds.getConnection(defaultUser,defaultPwd);
}
Paramètrage des fichiers
Fichier s server.xml
<Context className="org.apache.catalina.core.StandardContext" cachingAllowed="true"
charsetMapperClass="org.apache.catalina.util.CharsetMapper" cookies="true" crossContext="false"
debug="0" displayName="Tomcat Examples" docBase="C:\Program Files\Apache Group\Tomcat
4.1\webapps\workjdc" mapperClass="org.apache.catalina.core.StandardContextMapper"
path="/workjdc" privileged="false" reloadable="true" swallowOutput="false" useNaming="true"
wrapperClass="org.apache.catalina.core.StandardWrapper">
<Resource auth="Container" name="jdbc/testOracle" scope="Shareable"
type="oracle.jdbc.pool.OracleDataSource" />
<ResourceParams name="jdbc/testOracle">
<parameter>
<name>factory</name>
<value>oracle.jdbc.pool.OracleDataSourceFactory</value>
</parameter>
<parameter>
<name>url</name>
<value>jdbc:oracle:thin:@linuxser.afpa:1521:fpa1</value>
</parameter>
<parameter>
<name>maxActive</name>
<value>4</value>
</parameter>
<parameter>
<name>maxWait</name>
<value>5000</value>
</parameter>
<parameter>
<name>driverClassName</name>
<value>oracle.jdbc.driver.OracleDriver</value>
</parameter>
<parameter>
<name>maxIdle</name>
<value>2</value>
</parameter>
</ResourceParams>
</Context>
Annexe 3 : Attributs de la directive page des JSP
Voici la liste des attributs de la directive de page
© Copyright 2004 Jean-François Pillou –
Attribut
language
extends
import
session
Valeurs possibles
Description
Permet de spécifier le langage à utiliser pour traiter les
java
instructions de la page. Java est le langage utilisé majoritairement,
mais on peut imaginer des servlets écrites dans un autre langage
Permet de définir une classe à étendre, c'est-à-dire la classe
package.class
parente de la servlet générée par JSP
Permet d'importer une liste de classes ou de packages en début de
package.class|pakage.*
page, au même titre que dans une application Java.
Permet de définir si la page actuelle peut accèder aux données
true|false
stockées dans la session. Cet attribut est true par défaut
buffer
none|8kb|sizekb
autoflush
true|false
isThreadSafe true|false
info
Texte
Permet de définir si le flot de sortie est placé dans un tampon
avant envoi. Par défaut la taille du tampon est de 8kb, mais il est
possible de définir la taille en kb. Cet attribut s'utilise avec
l'attribut autoflush
La valeur true (par défaut) indique que le tampon doit être vidé
lorsqu'il est plein
La valeur true (par défaut) indique que plusieurs clients peuvent
utilise simultanément la servlet. Lorsqu'elle vaut false, la servlet
passe en mode monothread, ce qui signifie qu'un seul client\ peut
accèder à la servlet à la fois. Cela est particulièrement utile si la
servlet accède à une ressource qui ne peut être partagée
Permet de retourner une description grâce à la méthode
servlet.getServletInfo()
Permet de spécifier une page JSP chargée de gérer les exceptions
non gérées par celle-ci
isErrorPage true|false
Permet de spécifier si la page en cours est une page d'erreur
text/html;charset=ISO- Indique le type MIME de la page ainsi que le jeu de caractères
contentType
8859-1
utilisés
errorPage
URL
Annexe 4 : Exemple userInfo2.jsp
<%@ page language="java" contentType="text/html" %>
<html>
<head><title>Formulaire de saisie des informations de l’utilisateur</title></head>
<body bgcolor="white">
<jsp:useBean
id="userInfo"
class="tpBean.UserInfoBean">
<jsp:setProperty name="userInfo" property="*" />
</jsp:useBean>
<%-- Affichage des valeurs ayant un format invalide, si elles existent --%>
<font color="red">
<jsp:getProperty name="userInfo" property="propertyStatusMsg" />
</font>
<%-- Affichage du formulaire avec les valeurs envoyées valides --%>
<form action="userinfo2.jsp" method="post">
<table>
<tr>
<td>Nom :</td>
<td><input type="text" name="userName"
value="<jsp:getProperty
name="userInfo"
property="userName"
/>">
</td>
</tr>
<tr>
<td>Date de naissance :</td>
<td><input type="text" name="birthDate"
value="<jsp:getProperty
name="userInfo"
property="birthDate"
/>">
</td>
<td>(Utilisez le format aaaa-mm-jj)</td>
</tr>
<tr>
<td>Adresse e-mail :</td>
<td><input type="text" name="emailAddr"
value="<jsp:getProperty
name="userInfo"
property="emailAddr"
/>">
</td>
<td>(Utilisez le format [email protected])</td>
</tr>
<tr>
<td>Sexe :</td>
<td><input type="text" name="sex"
value="<jsp:getProperty
name="userInfo"
property="sex"
/>">
</td>
<td>(Male ou female)</td>
</tr>
<tr>
<td colspan=2><input type="submit" value="Envoi"></td>
</tr>
</table>
</form>
</body>
</html>
Annexe 5 : Exemple d’utilisation d’action personnalisées
<%@ page language="java" contentType="text/html" %>
<%@ page import="java.text.*" %>
<%@ page import="java.util.*" %>
<%@ taglib uri="/orataglib" prefix="ora" %>
<html>
<head>
<title>Catalogue des produits</title>
</head>
<body bgcolor="white">
<h1>Catalogue des produits</h1>
Choisissez un livre dans notre catalogue pour en voir une description
détaillée et décidez si vous voulez en acheter un exemplaire :
<jsp:useBean
id="catalog"
scope="application"
class="com.ora.jsp.beans.shopping.CatalogBean"
/>
<%-Génère une liste des produits avec des liens vers la page produit.
--%>
<ul>
<ora:loop name="catalog"
property="productList"
loopId="product"
className="com.ora.jsp.beans.shopping.ProductBean">
<li>
<a href="<ora:encodeURL url="product.jsp">
<ora:param name="id"
value="<%= product.getId() %>"/>
</ora:encodeURL>"><%= product.getName() %></a>
</ora:loop>
</ul>
<jsp:useBean
id="cart"
scope="session"
class="com.ora.jsp.beans.shopping.CartBean"
/>
<%-- Montre le contenu du caddie, s’il existe (les prix sont donnés en $) --%>
<%
if (!cart.isEmpty()) {
NumberFormat numFormat = NumberFormat.getCurrencyInstance(Locale.US);
%>
Votre caddie contient les éléments suivants :<p>
<table border=0>
<ora:loop name="cart"
property="products"
loopId="product"
className="com.ora.jsp.beans.shopping.ProductBean">
<tr>
<td><%= product.getName() %></td>
<td><%= numFormat.format(product.getPrice()) %></td>
</tr>
</ora:loop>
<tr><td colspan=2><hr></td></tr>
<tr>
<td><b>Total :</b></td>
<td><%= numFormat.format(cart.getTotal()) %></td></tr>
</table>
<% } %>
</body>
</html>
Annexe 6 : EJB et architecture distribuée
Téléchargement