Java intensif Programmation Web - Deptinfo

publicité
Java intensif
Programmation Web
Serge Rosmorduc
2013-2014
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
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
I
I
I
un fichier de configuration web.xml ;
un dossier classes contenant des classes java (.class) ;
un dossier lib contenant des bibliothèques java (.jar) ;
...
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 :
http://www.google.com/search?q=cnam&sourceid=chrome
protocole et serveur http://www.google.com
page : search
variable(s) :
I
I
q qui vaut cnam ;
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
1
2
3
4
5
6
7
8
9
0
1
2
3
4
5
6
7
8
9
Hello World en Servlet
@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 ” } )
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 {
protected void doGet ( H t t p S e r v l e t R e q u e s t request ,
HttpServletResponse response )
throws S e r v l e t E x c e p t i o n , IOException {
response . setContentType ( ” t e x t / h t m l ; c h a r s e t =UTF−8” ) ;
P r i n t W r i t e r o u t = response . g e t W r i t e r ( ) ;
try {
o u t . p r i n t l n ( ” <!DOCTYPE html>” ) ;
o u t . p r i n t l n ( ”<html>” ) ;
o u t . p r i n t l n ( ”<body>” ) ;
o u t . p r i n t l n ( ” Bonjour ” + r e q u e s t . getParameter ( ”nom” ) ) ;
o u t . p r i n t l n ( ” </body>” ) ;
o u t . p r i n t l n ( ” </ html>” ) ;
} finally {
out . close ( ) ;
}
}
}
Serge Rosmorduc
Java intensifProgrammation Web
2013-2014
11 / 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
I
String getParameter(String) : retourne la valeur d’un
paramètre
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
12 / 29
Limitation des servlets
Génération de HTML très lourde ;
Le HTML est mélangé au java :
I
I
mauvaise séparation affichage/traitements ;
pas adapté à une séparation des tâches
Serge Rosmorduc
Java intensifProgrammation Web
2013-2014
13 / 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
14 / 29
1
2
3
4
5
6
7
8
9
0
1
2
3
4
5
6
7
JSP, exemple
<!DOCTYPE html>
<html>
<head>
<meta c h a r s e t = ” UTF−8”>
< t i t l e >JSP</ t i t l e >
</head>
<body>
<p>Bonjour <%= r e q u e s t . getParameter ( ”nom” ) %></p>
<p>
<%
f o r ( i n t i = 0 ; i < 100; i ++) {
o u t . p r i n t ( ”−” ) ;
}
%>
</body>
</ html>
Serge Rosmorduc
Java intensifProgrammation Web
2013-2014
15 / 29
Utilisation propre de tout ça
La servlet :
I
I
I
I
c’est du java (chic !)
reçoit la requête ;
délègue le traitement à des classes métier (parce que le web
c’est l’enfer) ;
délègue l’affichage à une JSP
La JSP :
I
I
I
mélange du HTML et du code ;
ne calcule rien du tout.
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
16 / 29
1
2
3
4
5
6
7
8
9
0
1
2
3
4
5
6
7
8
Transmettre la main à une JSP depuis une servlet
Exemple : affichage du nom d’une personne capitalisé.
On utilise un RequestDispatcher dans la servlet....
public class H e l l o 2 extends H t t p S e r v l e t {
protected void doGet ( H t t p S e r v l e t R e q u e s t request ,
HttpServletResponse response )
throws S e r v l e t E x c e p t i o n , IOException {
/ / R écup ération des param ètres
S t r i n g nom = r e q u e s t . getParameter ( ”nom” ) ;
/ / T r a i t e m e n t : une c l a s s e m é t i e r . . .
S t r i n g nomCap= NomHelper . c a p i t a l i s e r (nom ) ;
/ / On t r a n s m e t l e s donn ées
/ / à a f f i c h e r comme ” beans r e q u e s t ”
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 ) ;
/ / On cr ée l e d i s p a t c h e r
RequestDispatcher r =
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 ” ) ;
/ / On passe l a main à l a s e r v l e t
r . f o r w a r d ( request , response ) ;
}
}
Serge Rosmorduc
Java intensifProgrammation Web
2013-2014
17 / 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
request.setAttribute(ident, valeur)
I
I
ident est un identifiant pour désigner l’attribut ;
valeur est un objet quelconque (pas forcément une String)
Serge Rosmorduc
Java intensifProgrammation Web
2013-2014
18 / 29
1
2
3
4
RequestDispatcher
Sert à demander à une JSP de terminer le traitement de la requête.
Utilisation
S t r i n g chemin= ” /WEB−INF / j s p / h e l l o 2 . j s p ” ;
RequestDispatcher r =
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 ) ;
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.
r.forward(request,response) expédie la requête courante
à cette nouvelle page.
Serge Rosmorduc
Java intensifProgrammation Web
2013-2014
19 / 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
20 / 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 ${personne.nom} affiche le nom de la personne en
appelant personne.getNom()
Serge Rosmorduc
Java intensifProgrammation Web
2013-2014
21 / 29
1
2
3
4
5
6
7
8
9
hello2.jsp
<!DOCTYPE html>
<html>
<head>
< t i t l e >JSP Page</ t i t l e >
</head>
<body>
Bonjour ${ n o m C a p i t a l i s e }
</body>
</ html>
Serge Rosmorduc
Java intensifProgrammation Web
2013-2014
22 / 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
23 / 29
Deuxième partie II
Du traitement des formulaires
Serge Rosmorduc
Java intensifProgrammation Web
2013-2014
24 / 29
Formulaire, exemple
Application qui
I
I
I
I
I
saisit le nom et le prénom d’une personne ;
vérifie que les champs sont remplis ;
calcule le texte de la salutation ;
l’affiche avec une jsp ;
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
25 / 29
1
2
3
4
5
6
7
8
9
0
1
2
3
4
5
6
7
8
9
0
1
2
3
4
Servlet
public class S a l u e r extends H t t p S e r v l e t {
protected void doGet ( . . . . . . . . . ) {
/ / A p r i o r i , p r e m i e r appel . . .
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 ” )
. f o r w a r d ( req , resp ) ;
}
protected void doPost ( . . . . . . . . . . ) {
String jsp ;
S t r i n g nom= req . getParameter ( ”nom” ) ;
S t r i n g prenom= req . getParameter ( ” prenom ” ) ;
i f (nom == n u l l | | prenom == n u l l | |
” ” . equals (nom) | | ” ” . equals ( prenom ) ) {
req . s e t A t t r i b u t e ( ” message ” ,
” l e s champs d o i v e n t ê t r e r e m p l i s ” ) ;
j s p = ” /WEB−INF / j s p / saluerForm . j s p ” ;
} else {
req . s e t A t t r i b u t e ( ”nom” , nom . toUpperCase ( ) ) ;
req . s e t A t t r i b u t e ( ” prenom ” , prenom ) ;
j s p = ” /WEB−INF / j s p / s a l u e r . j s p ” ;
}
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
26 / 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...
${param.nom} : valeur du paramètre nom (et non de l’attribut) :
valeur provenant du formulaire qu’on traite.
Serge Rosmorduc
Java intensifProgrammation Web
2013-2014
27 / 29
1
2
3
4
5
6
7
8
9
0
1
2
3
4
5
6
7
8
9
0
1
2
Amélioration : gestion des erreurs par tableau
protected void doPost ( . . . . ) {
String jsp ;
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 > ( ) ;
S t r i n g nom= req . getParameter ( ”nom” ) ;
S t r i n g prenom= req . getParameter ( ” prenom ” ) ;
i f (nom == n u l l | | ” ” . equals (nom ) ) {
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 ” ) ;
}
i f ( prenom == n u l l | | ” ” . equals ( prenom ) ) {
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 ” ) ;
}
i f ( ! e r r e u r s . isEmpty ( ) ) {
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 ) ;
j s p = ” /WEB−INF / j s p / saluerForm1 . j s p ” ;
} else {
req . s e t A t t r i b u t e ( ”nom” , nom . toUpperCase ( ) ) ;
req . s e t A t t r i b u t e ( ” prenom ” , prenom ) ;
j s p = ” /WEB−INF / j s p / s a l u e r . j s p ” ;
}
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
28 / 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
29 / 29
Téléchargement