Java intensif
Programmation Web
Serge Rosmorduc
2013-2021
Serge Rosmorduc Java intensifProgrammation Web 2013-2014 1 / 29
Plan
Rappel : L’architecture web : client, serveur, serveur applicatif ;
Une application java ;
notion de servlet ;
limites des servlets ;
notion de jsp ; expression language ; beans request ;
combinaison jsp/servlets, forwarding ;
architecture du traitement d’un formulaire (détaillé) ;
Serge Rosmorduc Java intensifProgrammation Web 2013-2014 2 / 29
Rappels sur l’architecture Web
Pour HTML, formulaires... voir supports du cours NFA016 sur
deptinfo.
Serge Rosmorduc Java intensifProgrammation Web 2013-2014 3 / 29
L’écosystème J2EE
Serveurs applicatifs à géométrie variable ; nombreux modules.
Couche web : Servlets/JSP ; Wicket, JSF ;
+ annuaire de services (JNDI) ;
+ gestion de transactions (JTA) ; gestion de persistence (JTA) ;
+ load balancing...
serveurs simples : Tomcat, Jetty...
serveurs complets : JBoss, Glassfish...
EJB3 vs. Spring : convergence des approches
Abandon de J2EE par Oracle : gestion par la fondation Eclipse ;
Ce cours : on reste simple, Servlets, JSP, un peu d’archi.
Serge Rosmorduc Java intensifProgrammation Web 2013-2014 4 / 29
Organisation d’une application Web
Serge Rosmorduc Java intensifProgrammation Web 2013-2014 5 / 29
Organisation d’une application Web
L’application est typiquement compressée dans un fichier .war
la racine de l’application contient :
des resources directement accessibles (pages web, images, jsp) ;
un dossier nommé WEB-INF qui contient :
I un fichier de configuration [Link] ;
I un dossier classes contenant des classes java (.class) ;
I un dossier lib contenant des bibliothèques java (.jar) ;
I ...
WEB-INF n’est pas visible depuis l’extérieur : on y range souvent
des ressources qu’on veut cacher.
Serge Rosmorduc Java intensifProgrammation Web 2013-2014 6 / 29
Remarque sur Netbeans
Serge Rosmorduc Java intensifProgrammation Web 2013-2014 7 / 29
Rappel sur la méthode GET
Les données sont passées dans l’URL :
[Link]
protocole et serveur [Link]
page : search
variable(s) :
I q qui vaut cnam ;
I sourceid qui vaut chrome .
Une requête en mode get est simple à construire sur un navigateur
web.
Serge Rosmorduc Java intensifProgrammation Web 2013-2014 8 / 29
Rappel sur la méthode POST
Autre système : les données de la requête sont envoyées dans le
corps de la requête http.
elles ne sont pas visibles.
Serge Rosmorduc Java intensifProgrammation Web 2013-2014 9 / 29
Notion de Servlet
classe java qui étend HttpServlet ;
associée à une URL ;
fournit deux méthodes : doGet() et doPost() ;
ces méthodes sont supposées récupérer les requêtes et y
répondre.
Serge Rosmorduc Java intensifProgrammation Web 2013-2014 10 / 29
Remarque technique (java 8 vs java 11)
ancienne version (oracle) : packages [Link] ;
nouvelle version (eclipse) : packages [Link] ;
les tps sont mis à jour pour jakarta ; en entreprise, il y a des
chances de rencontrer du code javax.
Serge Rosmorduc Java intensifProgrammation Web 2013-2014 11 / 29
Hello World en Servlet
1 @WebServlet ( name = ” H e l l o S e r v l e t ” , u r l P a t t e r n s = { ” / h e l l o ” } )
2 public class H e l l o S e r v l e t extends H t t p S e r v l e t {
3 protected void doGet ( H t t p S e r v l e t R e q u e s t request ,
4 HttpServletResponse response )
5 throws S e r v l e t E x c e p t i o n , IOException {
6 response . setContentType ( ” t e x t / h t m l ; c h a r s e t =UTF−8 ” ) ;
7 P r i n t W r i t e r o u t = response . g e t W r i t e r ( ) ;
8 try {
9 o u t . p r i n t l n ( ” <!DOCTYPE html>” ) ;
0 o u t . p r i n t l n ( ”<html>” ) ;
1 o u t . p r i n t l n ( ”<body>” ) ;
2 o u t . p r i n t l n ( ” Bonjour ” + r e q u e s t . getParameter ( ”nom” ) ) ;
3 o u t . p r i n t l n ( ” </body>” ) ;
4 o u t . p r i n t l n ( ” </ html>” ) ;
5 } finally {
6 out . close ( ) ;
7 }
8 }
9 }
Serge Rosmorduc Java intensifProgrammation Web 2013-2014 12 / 29
Servlets
Annotation :
@WebServlet(name = "HelloServlet",
urlPatterns = "/hello")
Dis que la servlet est associée à l’URL /hello
objet request : représente la requête. Permet de récupérer les
données de formulaire ;
méthodes utiles :
I String getParameter(String) : retourne la valeur d’un
paramètre
I String[] getParameterValues(String) : retourne les
valeurs d’un paramètre (pour les listes, etc...)
objet réponse : ici, permet de fixer le type et le codage de la
réponse, ainsi que son contenu.
Serge Rosmorduc Java intensifProgrammation Web 2013-2014 13 / 29
Limitation des servlets
Génération de HTML très lourde ;
Le HTML est mélangé au java :
I mauvaise séparation affichage/traitements ;
I pas adapté à une séparation des tâches
Serge Rosmorduc Java intensifProgrammation Web 2013-2014 14 / 29
Les JSP
En gros, HTML avec des vrais morceaux de java dedans.
Balises spécifiques
<% ...%> : introduit des instructions java ; <%= ... %> : introduit
des expressions java, dont le résultat est affiché. ;
Objets disponibles
out : permet d’écrire (JspWriter)
request : objet requête ;
response : objet réponse ;
session : objet représentant la session ;
application : représente l’application web.
Serge Rosmorduc Java intensifProgrammation Web 2013-2014 15 / 29
JSP, exemple
1 <!DOCTYPE html>
2 <html>
3 <head>
4 <meta c h a r s e t = ” UTF−8 ”>
5 < t i t l e >JSP</ t i t l e >
6 </head>
7 <body>
8 <p>Bonjour <%= r e q u e s t . getParameter ( ”nom” ) %></p>
9
0 <p>
1 <%
2 f o r ( i n t i = 0 ; i < 100; i ++) {
3 out . p r i n t ( ” − ” ) ;
4 }
5 %>
6 </body>
7 </ html>
Serge Rosmorduc Java intensifProgrammation Web 2013-2014 16 / 29
Utilisation propre de tout ça
La servlet :
I c’est du java (chic !)
I reçoit la requête ;
I délègue le traitement à des classes métier (parce que le web
c’est l’enfer) ;
I délègue l’affichage à une JSP
La JSP :
I mélange du HTML et du code ;
I ne calcule rien du tout.
I se contente d’afficher les données transmises par la servlet.
avantages : éléments développables séparément, testables
séparéments.
En pratique...
Serge Rosmorduc Java intensifProgrammation Web 2013-2014 17 / 29
Transmettre la main à une JSP depuis une servlet
Exemple : affichage du nom d’une personne capitalisé.
On utilise un RequestDispatcher dans la servlet....
1 public class H e l l o 2 extends H t t p S e r v l e t {
2 protected void doGet ( H t t p S e r v l e t R e q u e s t request ,
3 HttpServletResponse response )
4 throws S e r v l e t E x c e p t i o n , IOException {
5 / / R écup ération des param ètres
6 S t r i n g nom = r e q u e s t . getParameter ( ”nom” ) ;
7 / / T r a i t e m e n t : une c l a s s e m é t i e r . . .
8 S t r i n g nomCap= NomHelper . c a p i t a l i s e r (nom ) ;
9 / / On t r a n s m e t l e s donn ées
0 / / à a f f i c h e r comme ” beans r e q u e s t ”
1 r e q u e s t . s e t A t t r i b u t e ( ” n o m C a p i t a l i s e ” , nomCap ) ;
2 / / On cr ée l e d i s p a t c h e r
3 RequestDispatcher r =
4 r e q u e s t . g e t R e q u e s t D i s p a t c h e r ( ” /WEB−INF / j s p / h e l l o 2 . j s p ” ) ;
5 / / On passe l a main à l a s e r v l e t
6 r . f o r w a r d ( request , response ) ;
7 }
8 }
Serge Rosmorduc Java intensifProgrammation Web 2013-2014 18 / 29
Commentaires
La capitalisation n’est pas si simple (nom null, nom de taille 0 ou
1)...
on la sort de la servlet, qui doit être le moins intelligente possible
→ création d’une classe NomHelper
la méthode est statique, mais c’est juste parce que l’exemple est
simple ;
séparée de la servlet, elle peut être testée seule ;
on calcule les données à afficher (ici nomCap), et on les transmet
à la jsp comme beans request à l’aide de la méthode
[Link](ident, valeur)
I ident est un identifiant pour désigner l’attribut ;
I valeur est un objet quelconque (pas forcément une String)
Serge Rosmorduc Java intensifProgrammation Web 2013-2014 19 / 29
RequestDispatcher
Sert à demander à une JSP de terminer le traitement de la requête.
Utilisation
1 S t r i n g chemin= ” /WEB−INF / j s p / h e l l o 2 . j s p ” ;
2 RequestDispatcher r =
3 r e q u e s t . g e t R e q u e s t D i s p a t c h e r ( chemin ) ;
4 r . f o r w a r d ( request , response ) ;
chemin : page qui traite l’affichage. Très souvent une JSP, placée
dans WEB-INF.
[Link](request,response) expédie la requête courante
à cette nouvelle page.
Serge Rosmorduc Java intensifProgrammation Web 2013-2014 20 / 29
L’expression language (première approche)
Dans la JSP, on peut écrire :
1 <%= r e q u e s t . g e t A t t r i b u t e ( ” n o m C a p i t a l i s e ” ) %>
Mais c’est long et peu lisible.
de plus, on souhaite éliminer le code java des JSP : la JSP ne fait
que de l’affichage.
Un langage spécial est disponible : ${nomCapitalise} affiche
la valeur du bean.
Serge Rosmorduc Java intensifProgrammation Web 2013-2014 21 / 29
Propriétés des beans
Quand un bean est un objet avec des accesseurs... ;
par exemple un bean personne de classe Personne avec les
accesseurs getNom() et getPrenom() ;
alors ${[Link]} affiche le nom de la personne en
appelant [Link]()
Serge Rosmorduc Java intensifProgrammation Web 2013-2014 22 / 29
[Link]
1 <!DOCTYPE html>
2 <html>
3 <head>
4 < t i t l e >JSP Page</ t i t l e >
5 </head>
6 <body>
7 Bonjour ${ n o m C a p i t a l i s e }
8 </body>
9 </ html>
Serge Rosmorduc Java intensifProgrammation Web 2013-2014 23 / 29
Récapitulation
la servlet reçoit une requête, extrait les arguments, et décide quoi
faire ;
elle délègue le traitement effectif à des classes métiers, qui ne
connaissent rien du web ;
puis elle range les valeurs à afficher dans des beans request,
enfin, elle passe la main à une JSP.
Serge Rosmorduc Java intensifProgrammation Web 2013-2014 24 / 29
Deuxième partie II
Du traitement des formulaires
Serge Rosmorduc Java intensifProgrammation Web 2013-2014 25 / 29
Formulaire, exemple
Application qui
I saisit le nom et le prénom d’une personne ;
I vérifie que les champs sont remplis ;
I calcule le texte de la salutation ;
I l’affiche avec une jsp ;
I réaffiche le formulaire avec des messsages d’erreur et les données
erronées en cas de problème.
C’est la même servlet qui affiche le formulaire et le traite.
deux jsp : le formulaire et le résultat.
souvent, doGet() est appelé pour le premier affichage, et
doPost pour les traitements.
Serge Rosmorduc Java intensifProgrammation Web 2013-2014 26 / 29
Servlet
1 public class S a l u e r extends H t t p S e r v l e t {
2 protected void doGet ( . . . . . . . . . ) {
3 / / A p r i o r i , p r e m i e r appel . . .
4 req . g e t R e q u e s t D i s p a t c h e r ( ” /WEB−INF / j s p / saluerForm . j s p ” )
5 . f o r w a r d ( req , resp ) ;
6 }
7
8 protected void doPost ( . . . . . . . . . . ) {
9 String jsp ;
0 S t r i n g nom= req . getParameter ( ”nom” ) ;
1 S t r i n g prenom= req . getParameter ( ” prenom ” ) ;
2 i f (nom == n u l l | | prenom == n u l l | |
3 ” ” . equals (nom) | | ” ” . equals ( prenom ) ) {
4 req . s e t A t t r i b u t e ( ” message ” ,
5 ” l e s champs d o i v e n t ê t r e r e m p l i s ” ) ;
6 j s p = ” /WEB−INF / j s p / saluerForm . j s p ” ;
7 } else {
8 req . s e t A t t r i b u t e ( ”nom” , nom . toUpperCase ( ) ) ;
9 req . s e t A t t r i b u t e ( ” prenom ” , prenom ) ;
0 j s p = ” /WEB−INF / j s p / s a l u e r . j s p ” ;
1 }
2 req . g e t R e q u e s t D i s p a t c h e r ( j s p ) . f o r w a r d ( req , resp ) ;
3 }
4 }
Serge Rosmorduc Java intensifProgrammation Web 2013-2014 27 / 29
JSP formulaire
1 <%@page contentType= ” t e x t / h t m l ” pageEncoding= ” UTF−8 ”%>
2 <!DOCTYPE html>
3 <html>
4 <head>
5 < t i t l e >Saluer </ t i t l e >
6 </head>
7 <body>
8 <p s t y l e = ” c o l o r : red ”>${message}</p>
9 <form method= ”POST”>
0 <p>nom :
1 <i n p u t t y p e = ” t e x t ” name= ”nom” v a l u e = ” ${param . nom} ” /></p>
2 <p>prenom :
3 <i n p u t t y p e = ” t e x t ” name= ” prenom ” v a l u e = ” ${param . prenom} ” /></p>
4 <p><i n p u t t y p e = ” submit ” /></p>
5 </form>
6 </body>
7 </ html>
Noter que quand ${message} est absent, ça ne pose pas de
problème...
${[Link]} : valeur du paramètre nom (et non de l’attribut) :
valeur provenant du formulaire qu’on traite.
Serge Rosmorduc Java intensifProgrammation Web 2013-2014 28 / 29
Amélioration : gestion des erreurs par tableau
1 protected void doPost ( . . . . ) {
2 String jsp ;
3 HashMap<S t r i n g , S t r i n g > e r r e u r s = new HashMap<S t r i n g , S t r i n g > ( ) ;
4 S t r i n g nom= req . getParameter ( ”nom” ) ;
5 S t r i n g prenom= req . getParameter ( ” prenom ” ) ;
6
7 i f (nom == n u l l | | ” ” . equals (nom ) ) {
8 e r r e u r s . p u t ( ”nom” , ” ce champ d o i t ê t r e r e m p l i ” ) ;
9 }
0 i f ( prenom == n u l l | | ” ” . equals ( prenom ) ) {
1 e r r e u r s . p u t ( ” prenom ” , ” ce champ d o i t ê t r e r e m p l i ” ) ;
2 }
3
4 i f ( ! e r r e u r s . isEmpty ( ) ) {
5 req . s e t A t t r i b u t e ( ” e r r e u r s ” , e r r e u r s ) ;
6 j s p = ” /WEB−INF / j s p / saluerForm1 . j s p ” ;
7 } else {
8 req . s e t A t t r i b u t e ( ”nom” , nom . toUpperCase ( ) ) ;
9 req . s e t A t t r i b u t e ( ” prenom ” , prenom ) ;
0 j s p = ” /WEB−INF / j s p / s a l u e r . j s p ” ;
1 }
2 req . g e t R e q u e s t D i s p a t c h e r ( j s p ) . f o r w a r d ( req , resp ) ;
Serge Rosmorduc Java intensifProgrammation Web 2013-2014 29 / 29
Nouvelle version de la JSP
1 <%@page contentType= ” t e x t / h t m l ” pageEncoding= ” UTF−8 ”%>
2 <!DOCTYPE html>
3 <html>
4 <head>
5 <meta c h a r s e t = ” UTF−8 ”>
6 < t i t l e >Saluer </ t i t l e >
7 <s t y l e >
8 . e r r e u r { c o l o r : red ; }
9 </ s t y l e >
0 </head>
1 <body>
2 <form method= ”POST”>
3 <p>nom : <i n p u t t y p e = ” t e x t ” name= ”nom” v a l u e = ” ${param . nom} ” />
4 <span class= ” e r r e u r ”> ${ e r r e u r s . nom}</span>
5 </p>
6 <p>prenom : <i n p u t t y p e = ” t e x t ” name= ” prenom ”
7 v a l u e = ” ${param . prenom} ” />
8 <span class= ” e r r e u r ”> ${ e r r e u r s . prenom}</span>
9 </p>
0 <p><i n p u t t y p e = ” submit ” /></p>
1 </form>
2 </body>
3 </ html>
Serge Rosmorduc Java intensifProgrammation Web 2013-2014 30 / 29