TP17 : Algorithmique – Programmation FIP (ING39 ) Java et Web (2)

Transcription

TP17 : Algorithmique – Programmation FIP (ING39 ) Java et Web (2)
TP17 : Algorithmique – Programmation FIP (ING39 )
Java et Web (2)
S. Rosmorduc
Le but de ce TP est d’apprendre un certain nombre de bonnes pratiques de structuration pour créer
une application web maintenable.
Dans ce TP, on travaillera sur le système de forums vu dans le TP précédent.
Exercice 1
On veut réorganiser le forum pour que
– le contrôle soit réalisé par les servlets ;
– l’affichage soit réalisé par les jsp (placées dans le dossier WEB-INF)
On utilisera les beans.
Question 1
Réécrire l’affichage de la liste des messages en :
– traitant l’appel par une servlet (et non plus une jsp). La servlet ira chercher la liste des messages
correspondant dans ForumFacade, et le placera, comme bean request, sous le nom listeMessages dans
les attributs de l’objet request.
– la jsp affichera le contenu du bean listeMessages (on aura intérêt à utiliser JSLT et les expressions
pour se simplifier la vie).
Question 2
Même question, avec l’affichage d’un message particulier.
Question 3
Même question, pour l’ajout d’un nouveau message. Pour ce dernier cas, on utilisera la servlet pour
traiter à la fois
– l’affichage du formulaire s’il n’y a pas de données ou si les données sont incomplète, avec message
d’erreur dans le second cas ;
– l’affichage du résultat quand un message a été ajouté correctement.
Note : quand un formulaire comprend un champ vide, celui-ci a comme valeur ”” (la chaı̂ne vide). Quand
on arrive pour la première fois sur un formulaire, ses champs sont à null.
Question 4
Tant qu’à faire, ajoutez un menu à vos pages (sous forme d’une jsp à inclure).
1
Exercice 2
Question 1
Modifiez le forum et en particulier les messages pour que ceux ci soient signés par un utilisateur. Un
Utilisateur sera identifiée par un login et un mot de passe. Les Utilisateurs connus sont stockés dans le
forum (on pourra les créer a priori ).
On ajoutera une page connexion , qui permettra à un utilisateur de se connecter. L’ajout de nouveaux
message sera réservé aux utilisateurs connectés.
Pour stocker l’utilisateur connecté, vous utiliserez un bean session. (si vous le pouvez, testez sur plusieurs
navigateurs différents pour vous connecter sous plusieurs noms).
Question 2
Modifiez en conséquence l’affichage des menus (n’affichez à un utilisateur que ce qu’il peut faire).
Exercice 3
On veut utiliser l’architecture dite front controller, et réduire à... une le nombre de servlets nécessaires.
L’idée est la suivante :
La servlet utilisée a la forme :
public c l a s s C o n t r o l l e r extends H t t p S e r v l e t {
protected void p r o c e s s R e q u e s t ( H t t p S e r v l e t R e q u e s t r e q u e s t , H t t p S e r v l e t R e s p o n s e r e s p o n s e )
throws S e r v l e t E x c e p t i o n , IOException {
// G a r a n t i t que l e s e n t r é e s s o n t en UTF−8
r e q u e s t . s e t C h a r a c t e r E n c o d i n g ( ”UTF−8” ) ;
// ce qu ’ on v e u t v r a i m e n t f a i r e e s t s t o c k é dans command
S t r i n g command = r e q u e s t . ge tPa ra met er ( ”command” ) ;
// l ’ o b j e t q u i va ” v r a i m e n t ” t r a i t e r l a r e q u ê t e
ControlCommand controlCommand ;
// t e s t s e l o n l e s commandes . . . on p e u t f a i r e p l u s j o l i
i f ( ” l i s t ” . e q u a l s ( command ) ) {
controlCommand= new ListCommand ( g e t S e r v l e t C o n t e x t ( ) , r e q u e s t , r e s p o n s e ) ;
} e l s e i f ( ”add” . e q u a l s ( command ) ) {
controlCommand= new AddCommand( g e t S e r v l e t C o n t e x t ( ) , r e q u e s t , r e s p o n s e ) ;
} e l s e i f ( ”show” . e q u a l s ( command ) ) {
controlCommand = new ShowCommand( g e t S e r v l e t C o n t e x t ( ) , r e q u e s t , r e s p o n s e ) ;
} else {
// MessageCommand e s t une commande pour a f f i c h e r une j s p dé j à c h o i s i e . . .
// ( u t i l e pour l e s p a g e s f i x e s )
controlCommand= new MessageCommand ( ”unknown . j s p ” ) ;
}
// On e x é c u t e l a commande e t on ré c u pè r e l ’ i n f o r m a t i o n c o r r e s p o n d a n t e
A f f i c h a g e I n f o a f f i c h a g e = controlCommand . doCommand ( ) ;
// On a f f i c h e l e r é s u l t a t
a f f i c h a g e . a f f i c h e r ( this , r e q u e s t , r e s p o n s e ) ;
}
...
}
2
Pour donner un exemple, ListeCommand a la forme suivante
c l a s s ListCommand extends ControlCommand {
public ListCommand ( S e r v l e t C o n t e x t s e r v l e t C o n t e x t ,
HttpServletRequest request ,
HttpServletResponse response ) {
super ( s e r v l e t C o n t e x t , r e q u e s t , r e s p o n s e ) ;
}
public A f f i c h a g e I n f o doCommand ( ) {
// r é c u p é r a t i o n d e s messages . . .
ForumFacade f a c a d e= ForumFacade . g e t I n s t a n c e ( ) ;
A r r a y L i s t <Message> msgs= new A r r a y L i s t <Message > ( ) ;
int s i z e= f a c a d e . getNumberOfMessages ( ) ;
f o r ( int i= 0 ; i < s i z e ; i ++) {
msgs . add ( f a c a d e . getMessage ( i ) ) ;
}
// on en f a i t un bean 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 ( ” l i s t e M e s s a g e s ” , msgs ) ;
// on demande l ’ a f f i c h a g e de l i s t . j s p
return A f f i c h a g e I n f o . c o n s t r u i r e J S P ( ” l i s t . j s p ” ) ;
}
}
La classe AffichageInfo va nous servir à gérer les affichage plus simplement. Elle traite deux cas :
– l’affichage se fait en utilisant une JSP
– l’affichage se fait par redirection http vers une autre page (pour éviter les POST doublés )
public c l a s s A f f i c h a g e I n f o {
private S t r i n g a d r e s s e ;
private boolean r e d i r e c t i o n= f a l s e ;
private A f f i c h a g e I n f o ( S t r i n g a d r e s s e , boolean r e d i r e c t i o n ) {
this . adresse = adresse ;
this . r e d i r e c t i o n = r e d i r e c t i o n ;
}
/∗ ∗
∗ C o n s t r u c t e u r nommé .
∗/
public s t a t i c A f f i c h a g e I n f o c o n s t r u i r e R e d i r e c t i o n ( S t r i n g c h e m i n R e d i r e c t i o n ) {
return new A f f i c h a g e I n f o ( c h e m i n R e d i r e c t i o n , true ) ;
}
/∗ ∗
∗ R e d i r e c t i o n v e r s une JSP s t o c k é e dans WEB−INF/ j s p .
∗/
public s t a t i c A f f i c h a g e I n f o c o n s t r u i r e J S P ( S t r i n g nomJsp ) {
return new A f f i c h a g e I n f o ( nomJsp , f a l s e ) ;
}
/∗ ∗
∗ Effectuer l ’ affichage .
3
∗/
public void a f f i c h e r ( H t t p S e r v l e t s e r v l e t ,
HttpServletRequest request ,
HttpServletResponse response )
throws IOException , S e r v l e t E x c e p t i o n {
if ( redirection ) {
response . sendRedirect ( adresse ) ;
} else {
RequestDispatcher requestDispatcher =
s e r v l e t . getServletContext ( ) . getRequestDispatcher (
” /WEB−INF/ j s p / ” + a d r e s s e ) ;
requestDispatcher . forward ( request , response ) ;
}
}
}
Pour terminer, la classe de base pour les commandes, ControlCommand, a le code suivant :
/∗ ∗
∗ Commande g é n é r i q u e .
∗ <p> Les o b j e t s commande s t o c k e n t d e s i n f o r m a t i o n s t e m p o r a i r e s ;
∗ i l s ne s o n t pas d e s t i n é s à ê t r e c o n s e r vé s l o n g t e m p s .
∗ @author rosmord
∗/
public abstract c l a s s ControlCommand {
protected H t t p S e r v l e t R e q u e s t r e q u e s t ;
protected H t t p S e r v l e t R e s p o n s e r e s p o n s e ;
protected S e r v l e t C o n t e x t s e r v l e t C o n t e x t ;
public ControlCommand ( S e r v l e t C o n t e x t s e r v l e t C o n t e x t ,
HttpServletRequest request ,
HttpServletResponse response ) {
this . request = request ;
this . response = response ;
t h i s . s e r v l e t C o n t e x t= s e r v l e t C o n t e x t ;
}
/∗ ∗
∗ E x e c u t e l a commande e t r e t o u r n e l ’ a f f i c h a g e s u i v a n t .
∗/
public abstract A f f i c h a g e I n f o doCommand ( ) ;
}
Note : ControlCommand pourrait éventuellement être une interface
4