You are on page 1of 136

Architectures client/serveur

Master Technologies de l'Internet 1 Eric Cariou


Universit de Pau et des Pays de l'Adour UFR Sciences Pau Dpartement Informatique Eric.Cariou@univ-pau.fr
1
re

anne

Tryptique d'une application

"rsentation

ervices !tier

"ersistance

Tryptique d'une application

"rsentation
Interface utilisateur pour interagir avec l'application

Interface classi$ue t%pe &'I (e) * traite!ent de te)te+ Interface ,e-. plus lgre

"ersistance
Enregistre!ent sur support ph%si$ue des donnes de l'application

/ichiers (-inaires. 0M1. ...+ 2ase de donnes


i!ple 3vec redondance pour fia-ilit Multiples * fdration de -ases de donnes ...

Tryptique d'une application

ervices !tier
Intgre la logi$ue !tier

E)* un docu!ent est co!pos de sections. elles !5!es co!poses de sous-sections ...

ervices offerts au) utilisateurs


E)* crer un docu!ent. le !odifier. a6outer des sections. l'enregistrer ...

"artie7applicative ont intgres et cooprent pour le fonctionne!ent de l'application En anglais. on les appele aussi des 87tiers79 (tages+

Trois parties

3pplication 87# : tiers79 $uand les # parties sont claire!ent4 distinctes

Tryptique d'une application

<ans un conte)te distri-u


1es tiers sont = peuvent 5tre e)cuts sur des !achines diffrente Certains tiers peuvent 5tre sous dcoups <e no!-reuses variantes de place!ent des tiers et de leur distri-ution Tout est sur la !5!e !achine
"rsentation ervices Mtiers "ersistance ;

Modle centralis

3rchitecture 2 : tiers

Architecture 2 tiers

Client = serveur de -ase. avec 2 l!ents


Client * prsentation. interface utilisateur erveur * partie persistance. gestion ph%si$ue des donnes oit entire!ent cot client. intgrs avec la prsentation

1es services !tier = la partie applicative peuvent 5tre

1a partie serveur ne gre $ue les donnes


E) * traite!ent de te)te avec serveur de fichiers distants E) * application accdant ? une 2<< distante

oit entire!ent cot serveur


1a partie client ne gre $ue l'interface utilisateur 1'interface utilisateur peut !5!e 5tre e)cute sur le serveur

/onctionne!ent !ode ter!inal = !ainfra!e 1'utilisateur a si!ple!ent devant lui cran = clavier = souris pour interagir ? distance avec l'application s'e)cutant entire!ent sur le serveur

oit dcoups entre la partie serveur et la partie client

>

Architecture 2 tiers

Client * prsentation A applicatif


ervices Mtiers "ersistance erveur

"rsentation Client

erveur * applicatif A gestion donnes


ervices Mtiers

"rsentation Client

"ersistance

erveur @

Architecture 2 tiers

Ter!inal * client intgre un !ini!u! de la partie prsentation


Ter!inal

"rsentation

ervices Mtiers erveur

"ersistance

Client

3pplicatif * dcoup entre client et serveur


3pplicatif "rsentation client Client 3pplicatif "ersistance serveur erveur B

Architecture 3 tiers

3rchitecture # : tiers
1es # principau) tiers s'e)cutent chacun sur une !achine diffrente "rsentation

Machine client erveur d'applications erveur de (-ase de+ donnes ervices Mtiers erveur applicatif "ersistance erveur C donnes

3pplicatif = !tier

"ersistance

"rsentation Client

Architecture 3 tiers sur le web

3rchitecture # : tiers
Trs dveloppe de nos 6ours

3vec gnrale!ent un fonctionne!ent au dessus du ,eEavigateur Fe- sur !achine cliente

Couche prsentation

Client lger

3ffichage de contenu GTM1 erveur d'applications


Couche applicative = !tier

erveur GTT" e)cutant des co!posants = l!ents logiciels $ui gnrent d%na!i$ue!ent du contenu GTM1 Hia des re$u5tes ? des 2<< distantes erveur(s+ de 2<< de donnes

Couche persistance

1D

Architecture n tiers

3rchitecture n : tiers
Ia6oute des tages = couches en plus 1a couche applicative n'est pas !onoliti$ue

"eut s'appu%er et interagir avec d'autres services Co!position horiJontale

ervice !tier utilise d'autres services !tiers 1es services !tiers peuvent aussi s'appu%er sur des services techni$ues

Co!position verticale

curit. Transaction ...

Cha$ue service correspond ? une couche

<'oK le ter!e de E-tiers 11

Architecture n tiers

Intr5ts d'avoir plusieurs services = couches (# ou plus+


Iutilisation de services e)istants <couplage des aspects !tiers et techni$ue et des services entre eu) * !eilleure !odularit /acilite volution * nouvelle version de service /acilite passage ? l'chelle * volution de certains services Ln recherche en gnral un couplage fai-le entre les services

"er!et de faire voluer les services un par un sans !odification du reste de l'application

Inconvnients
En gnral. les divers services s'appuient sur des technologies trs varies * ncessite de grer l'htrognit et l'interopra-ilit 'tilisation de fra!eForM = outils suppl!entaires 1es services tant plus dcoups et distri-us. pose plus de pro-l!es lis ? la distri-ution

12

Logique de prsentation

1es tNches lies ? la prsentation re$uirent

1'interaction avec l'utilisateur


Ialise par la &'I d'un client lourd * -outons. listes. !enus. ... Ialise par le navigateur pour un client Fe

Hia interaction plus 87-asi$ue79 * for!ulaires. liens vers des 'I1s ...

1a logi$ue de prsentation

1e traite!ent des donnes retournes par les services !tiers et leur prsentation ? destination de l'utilisateur Ialise par un client lourd $ui gnrale!ent fait directe!ent l'appel des services !tiers sur le serveur "our un client Fe

Eavigateur se contente d'afficher du code GTM1 $ui ne peut pas 5tre stati$ue ici vu $ue le contenu dpend des donnes retournes <oit donc e)cuter du code $ui rcupre les donnes retournes par les services !tiers et gnre d%na!i$ue!ent du code GTM1 1ogi$ue de prsentation peut 5tre e)cute cot client ou cot serveur !ais se fait gnrale!ent dans un tiers ? part cot serveur

1#

Persistance

Couche de persistance
tocMage et !anipulation des donnes de l'application "lusieurs supports ph%si$ue

/ichiers -inaires. te)tes 87de -ase79 /ichiers 0M1 'ne -ase de donnes ou un ense!-le de -ases de donnes Ecessit d'envo%er ? distance des re$u5tes (t%pes O1+ et d'en rcuprer les rsultats "our raliser cela

"our ce dernier cas


oit c'est natif dans le langage utilis (e) * "G"+ oit on passe par des fra!eForMs ou des 3"I ddis

14

Ouel$ues standards = outils d'accs ? distance ? des 2<<


Persistance

I<3 (Ie!ote <ata 3ccess+ de l'I L L<2C (Lpen <ata 2ase Connectivit%+ de Microsoft P<2C (Pava <ata 2ase Connectivit%+ de un

/ra!eForM pour le langage Pava

/onctionne!ent gnral

&estion de re$u5tes O1 !ais avec indpendance du &2<I utilis (!% O1. "ostgre O1. Lracle ...+ En gnral. seule la phase de conne)ion au &2<I est spcifi$ue

E)iste gale!ent des fra!eForMs de plus haut niveau


E)e!ples * Gi-ernate ( un. P2EE+. EGi-ernate (li-re. pour .Eet+ "rincipe gnral

Ln dfinit de !anire a-straite (via 0M1 par e)e!ple+ la structure des donnes ? !anipuler 1'outil gnre un ense!-le d'oprations de !anipulation de donnes (en 6ava par e)e!ple+ utilisa-le dans un progra!!e 1; 1'outil fait en interne le lien avec le support ph%si$ue ( &2<I ...+ considr

ra!ewor"s globau#

'ne application #=E : tiers intgre un grand no!-re de technologies


"rsentation * GTM1. &'I ... 3pplicatif * o-6ets. co!posants. scripts e)cuta-les. services ... 2<< * fichiers 0M1. &2<I. ... "rotocoles de co!!unication * I"C = IMI. GTT"

"our faciliter l'intgration de ces technologies et le dveloppe!ent d'applications

Editeurs offrent des fra!eForMs glo-au)


P2EE = Pava EE cheJ un .Eet cheJ Microsoft

erveur d'application
erveur per!ettant d'e)cuter les parties applicatives dans le conte)te de ces fra!eFoMs

1>

P2EE = Pava EE * Pava Entreprise Edition


$un %2&&

Eor!e = standard dfini par un pour le langage Pava Technologies intgres


Co!posants logiciels * EP2 3pplications orientes ,e- * P ". servlet Co!!unication ? distance * Pava IMI. IIL". PM (Pava Message ervice * co!!unication par !essage+. ,e- ervices &estion donnes distantes * P<2C. P"3 (Pava "ersistance 3"I+ &estion d'annuaires (t%pe 1<3"+ * PE<I Transactions * PT3 Et -ien d'autres ...

E)iste plusieurs serveurs d'applications P2EE

Hersions li-res

&lass/ish. P2oss. 3pache &eroni!o. Ponas ... Hersions d'diteurs un Pava %ste! 3pplication erver (-as sur &lass/ish+. I2M1@ ,e- phere. 2E3 ,e-1ogic. Lracle Container for Pava EE. ...

olution Microsoft si!ilaire ? P2EE


"articularit * !ulti-langage

'icroso(t )*et

"er!et interopra-ilit d'l!ents crits en C. Pava. CQ. PQ. Eiffel. H2. ... (plus de 2D langages+ Traduction en code inter!diaire (M I1+ $ui sera e)cut par la couche C1I (Co!!on 1anguage Iunti!e+

Cot Pava. c'est le code Pava $ui tait converti en -%te code e)cut par la !achine virtuelle Pava (PHM+

C'est une nor!e gale!ent

1a principale !ise en oeuvre est -ien sRr de Microsoft et pour ,indoFs. !ais il e)iste $uel$ues versions li-res (i!pl!entations souvent partielles+

Technologies intgres

Co!posants logiciels * CLMA 3pplications orientes ,e- * 3 " .Eet.


Co!!unication ? distance * .Eet re!oting. M MO. ,e- services

3ccs donnes * 3<L .Eet. L<2C ...

1B

Architecture 3/+ tiers, conte#te %2&&

<eu) architectures gnrales conte)te P2EE

1ogi$ue applicative

Ialise par co!posants EP2 Co!!unication via Gi-ernate ou P<2C pour atta$uer 2<< distante 3vec client lger ou client lourd Client lger * navigateur Fe

"rsentation

Intr5t * si!plifie la prsentation (suffit d'un navigateur+ Inconvnient * li!ite de l'interaction via GTM1 3pplication 87standard 97cot client. gre la logi$ue de prsentation Intr5t * plus grande possi-ilit en ter!e de prsentation et d'interaction Inconvnient * ncessite un dveloppe!ent ddi via des 3"I de Fidgets

Client lourd

Interaction avec la partie applicative sur le serveur


Hia P " = ervlet pour un client lger

'occupe de la logi$ue de prsentation

<irect si client lourd (via un !iddleFare t%pe IMI+

1C

Architecture 3/+ tiers, conte#te %2&&

Client lourd (#-tiers+


Client lourd Co!posants EP2 Conteneur EP2 &2< erveur donnes

Client lger (4-tiers+


Eavigateur ,e-

erveur P2EE Conteneur Feervlet = P " logique de prsentation

logique mtier

Co!posants EP2 Conteneur EP2 erveur P2EE

&2< erveur 2D donnes

Technologies -eb . gnration dyna!ique /T'L cot serveur %$P / $ervlet

21

Technologies -eb

"rsentation
3ffichage docu!ent GTM1 A feuilles de st%les 'e)cute dans un navigateur Fe- * client lger Interaction avec l'utilisateur via des for!ulaires (listes. entres te)te. -outons ...+ et liens 2ut * produire un contenu GTM1

3pplicatif
elon les choi) de l'utilisateur elon les donnes ? afficher Ecessite d')ecuter du code $ui va gnrer ces pages 22

Ecessite une gnration d%na!i$ue des pages GTM1

Technologies -eb

E)cution de code * deu) possi-ilits


E)cution cot client

1e client tlcharge ? partir du serveur du code $ui s'e)cute dans le navigateur du client E)e!ple * applet Pava

E)cution d'un progra!!e Pava (d'une for!e particulire+ au sein du navigateur Tlcharge!ent peut 5tre lourd * cha$ue client doit tlcharger le code "ro-l!e de scurit car on e)cute locale!ent du code venant d'un l!ent distant

"ro-l!es

E)cution cot serveur


<u code est e)cut cot serveur pour gnrer de !anire d%na!i$ue la page GTM1 $ui sera envo%e au client 2# Ln va s'intresser ? ce t%pe d'e)cution dans ce cours

0nration pages dyna!iques

<eu) principes gnrau) de fonctionne!ent. cot serveur

1angages de scripts

<ou-le t%pe de contenu dans une page GTM1


"artie stati$ue * -alises GTM1 standards avec contenu te)tuel "artie d%na!i$ue * du code crit dans un langage de script Ce code gnre du code GTM1 standard

1a page entre!elle les parties stati$ues et d%na!i$ues Ouand un navigateur de!ande le contenu d'une page

1a partie d%na!i$ue est e)cute et re!place par le GTM1 gnr 1e navigateur du client reSoit donc uni$ue!ent du code GTM1

E)cution d'un progra!!e


'n progra!!e co!plet s'e)cute et gnre du contenu GTM1 1a page est entire!ent d%na!i$ue

"lus prcis!ent * les partie stati$ues e)istent !ais elles sont intgres dans le code. pas crites directe!ent en GTM1 standard

1e navigateur de!ande l'e)cution d'un progra!!e et rcupre le code GTM1 gnr

1a de!ande d'e)cution est transparente * utilise 'I1 standard

24

0nration pages dyna!iques

E)e!ples de technologies
1angages de script

"G"

1angage interprt offrant l'avantage d'intgrer native!ent les pri!itives de re$u5tes O1 sur des 2<< 3 " et 3 " .Eet olutions Microsoft P " (Pava erver "age+ olution un pour Pava

E)cution de progra!!es

C&I * Co!!on &ateFa% Interface

Gistori$ue!ent. une des pre!ires solutions

ervlet
olution un pour Pava * e)cution de code Pava respectant 2; certaines caractristi$ues

0nration pages dyna!iques

"latefor!e d'e)cution
<ans tous les cas. il faut pouvoir e)cuter du code et co!!uni$uer via GTT" avec le navigateur cot client <eu) co!posants pour gnration de pages d%na!i$ues

erveur GTT" standard El!ent (conteneur+ d'e)cution des progra!!es ou des scripts

E)e!ples de serveurs = platefor!es


3pache To!cat

P ". ervlet 1ogiciel li-re 3 ". 3 " .Eet "ropritaire

Microsoft II

2>

$ervlet

'ne servlet est un progra!!e Pava particulier


Classe $ui hrite de HttpServlet

E$uivalent d'une applet Pava. !ais cot serveur

Classe standard du point de vue de son contenu en ter!e d'attri-uts. !thodes ... Mais e)cution et interactions diffrentes d'un o-6et Pava standard

"as d'appel de constructeur. pas de main() 3 la cration de la servlet par le serveur d'e)cution

3ppel par le serveur d'e)cution de la fonction init(ServletConfig) Ln peut % faire les actions $u'on ferait dans un constructeur 3ppel par le serveur d'e)cution de destroy() 3 redfinir si on veut effectuer certaines actions ? la suppression de la servlet

Ouand la servlet est dtruite


2@

Eavigateur Fe- cot client

$ervlet

Envoie des re$u5tes GTT" au serveur


&ET. "L T. "'T. <E1ETE. GE3<. L"TILE . TI3CE

<ans une servlet

3 cha$ue re$u5te correspond une !thode doXXX(...) hrite de la classe HttpServlet et $ui sera appele selon la re$u5te client

Ln rdfinit ces !thodes pour % placer le code ? e)cuter par la servlet En prati$ue. pas -esoin de redfinir toutes les !thodes (&ET et "L T !ini!u!+ <e !anire plus gnrale (!ais !oins reco!!ande+. la !thode service(...) reSoit toutes les re$u5tes et peut 5tre redfinie directe!ent (par dfaut elle redispatche au) doXXX(...) +

E)e!ple pour &ET


doGet(HttpServletRequest request, HttpServletResponse response) thro s Servlet!"ception, #$!"ception request * contient la description de la re$u5te du client response * ? utiliser pour envo%er la rponse au client 2B Toutes les !thodes doXXX(...) ont la !5!e signature

Para!1tres des do2223)))4

HttpServletRequest request
Initialis par l'appel du client (le navigateur+ <onnes = infor!ations sur la re$u5te envo%e par le client Ln peut % rcuprer nota!!ent

Haleurs entres pour un for!ulaire 'ne session pour grer un tat ddi ? cha$ue client CooMies du client envo%s avec la re$u5te Infor!ations sur l''I1 utilise pour l'appel de la servlet 1ogin de l'utilisateur s'il s'est identifi Et de !anire plus gnrale. tous les 87headers79 de l'appel

Identifiants du navigateur. t%pe de re$u5te (&ET. "'T ...+. t%pe d'encodage support par le navigateur. ...

2C

Para!1tres des do2223)))4

HttpServletResponse response

3 initialiser et utiliser par la servlet pour gnrer le rsultat ? envo%er au navigateur client <finir le t%pe MIME des donnes envo%es
&nrale!et du code GTM1 response.setContent%ype(&te"t'html(charset)*%+,-&)( Mais peut utiliser n'i!porte $uel t%pe MIME * image'gif, audio'mp., application'pdf. ...

Icuprer le flu) de sortie pour envo%er les donnes


/rint0riter get0riter()

/lu) te)te. t%pi$ue!ent pour du GTM1 /lu) -inaire pour des i!ages. vidos ...

Servlet$utputStream get$utputStream

36outer=envo%er des donnes cot client


Cr un nouveau cooMie (ou !odifier un e)istant+ 36outer un header au) donnes envo%es

#D

5aractristiques d'une servlet

'nicit d'une servlet


'ne servlet n'est cre $u'en une seule instance i plusieurs clients accdent ? l''I1 d'une !5!e servlet

3ppelle les !thodes sur cette instance uni$ue Cet tat est per!anent et conserv (tant $ue la servlet e)iste+ Il est accd = !odifi par tous les clients * tat glo-al

'ne servlet possde des attri-uts donc un tat


Etat associ ? un client

Te!poraire * !ode session


"our cha$ue client. une session est cre

Ln peut lui associer des donnes via des couples 787cl (chaine+ = o-6et 9

1a session a une dure de vie configura-le E)e!ple t%pi$ue d'utilisation d'une session

"anier d'un utilisateur sur un site de vente en ligne * conserve les produits choisis par l'utilisateur pendant son parcours sur le site

"er!anent * cooMies du navigateur

#1

E)e!ple -asi$ue de servlet


&#e!ple . servlet hello world

&nre une page $ui affiche 87hello Ford79 &re et affiche un co!pteur $ui est incr!ent ? cha$ue accs ? la servlet 1e code $ui suit a t cr sous Eet-eans $ui gnre un s$uelette de code

Eote sur le code prsent

Ce s$uelette contient une !thode principale processRequest() $ui contiendra le code principal de la servlet 1es !thodes hrites doGet() et do/ost() appellent directe!ent cette !thode processRequest() avec les !5!es para!tres

'ne fois dplo%e sur le serveur. on accde ? une servlet via une 'I1 GTT"
1a notre est contenue dans le fichier Hello0orld.1ava 'I1 sera de la for!e * http2'' ."""""".fr'XXX'Hello0orld Eote * peut choisir une 'I1 d'accs ? la servlet diffrente #2

du no! de la servlet Pava

&#e!ple . servlet hello world

Code de la servlet Hello0orld.1ava


public class HelloWorld extends HttpServlet { == co!pteur gr par la servlet protected int compteur = 0; protected void processRequest( HttpServletRequest request, HttpServletResponse response) thro s Servlet!xception, "#!xception { == out * flu) de sortie !ode te)te $ui contiendra le GTM1 response$set%ontent&'pe((text)html;charset=*&+,-(); .rintWriter out = response$/etWriter(); tr' { == on crit ligne par ligne le code GTM1 ? afficher cheJ le client out$println((0html1(); out$println((0head1(); out$println((0title1Servlet HelloWorld0)title1(); out$println((0)head1(); out$println((0bod'1(); out$println((0h21Servlet HelloWorld0)h21(); == on insre ici la valeur du co!pteur (en l'incr!entant au passage+ out$println((0p13ombre d4appels 5 (6(66compteur)6(0)p1(); out$println((0)bod'1(); out$println((0)html1(); 7 8inall' { out$close();

##

7 7

&#e!ple . servlet hello world

E)e!ple d'e)cution
3prs 4 charge!ents de la servlet co!pteur passe ? ;

#4

&#e!ple . servlet hello world

Code prcdent

1e co!pteur est glo-al * co!!un ? tous les clients "asser par les donnes $u'on peut associer ? une session Modification de processRequest()
tr' { == rcupre la session associe au client HttpSession session = request$/etSession(true); == rcupre le co!pteur associ ? la session "nte/er compteur = ("nte/er)session$/et9ttribute((compteur(); == si valeur null * attri-ut 87co!pteur79 n'e)iste pas. Sa signifie == $ue c'est la pre!ire e)cution par le client. il faut crer le co!pteur i8 (compteur==null) { compteur = ne "nte/er(2); session$set9ttribute((compteur(, compteur); == configure pour $u'une session dure 1D secondes !a) session$set:ax"nactive"nterval(20); 7 ($$$) out$println((0p13ombre d4appels 5 (6compteur6(0)p1(); ($$$) == incr!ente le co!pteur #; session$set9ttribute((compteur(, ne "nte/er(compteur$int;alue()62));

Hariante pour grer un co!pteur local ? cha$ue client


&#e!ple . passage de para!1tres

3utre e)e!ple

Manipulation de rectangles avec # oprations


Cration d'un rectangle <calage du rectangle courant (non prsent en dtail pour gagner de la place+ Calcul de la surface du rectangle courant

I!pl!entation

appeler la servlet avec ces para!tres Eote * dans l'e)e!ple. c'est une page P " !ais c'est du GTM1 standard. aucun code Pava n'est inclus dans la page

'ne page GTM1 contient un for!ulaire pour entrer les para!tres et

ervlet
'ne servlet gre le rectangle et e)cute les # oprations en fonction des para!tres venant du for!ulaire Ln rcupre ces para!tres via * request.get/arameter(nom/aram) #>

&#e!ple . servlet rectangle

Code de la page GTM1


0html1 0head1 0meta http,equiv=(%ontent,&'pe( content=(text)html; charset=*&+,-(1 0title1<S. .a/e0)title1 0)head1 0bod'1 0h21:anipulation de rectan/le avec une servlet0)h21 08orm action=(RectServlet( method=(post(1 0p1 0table border=(0(1 0tr1 0td1=2 ou = d>cala/e0)td1 0td10input 0tr1 0td1?2 ou ? d>cala/e0)td1 0td10input 0tr1 0td ali/n=(ri/ht(1=@0)td1 0td10input 0tr1 0td ali/n=(ri/ht(1?@0)td1 0td10input 0)table10)p1

name=(x2(1 name=('2(1 name=(x@(1 name=('@(1

0)td1 0)td1 0)td1 0)td1

0)tr1 0)tr1 0)tr1 0)tr1

0p10input t'pe=(radio( name=(action( value=(creer( checAed=(checAed( )1 %r>er Rectan/le0br )1 0input t'pe=(radio( name=(action( value=(decaler( )1B>caler Rectan/le0br )1 0input t'pe=(radio( name=(action( value=(sur8ace( )1%alcul Sur8ace0)p1 0p10input t'pe=(submit( value=(!x>cuter(1 0input t'pe=(reset( value=(Remise C D>ro10)p1 0)8orm1 0)bod'1 0)html1

#@

&#e!ple . servlet rectangle

1iens entre page GTM1 et la servlet


1e for!ulaire de la page GTM1 contient

'ne action associe $ui est l'appel de la servlet RectServlet 4 cha!ps d'entre de no!s "3, y3, "4, y4 'ne liste de -outons radio dont selon le choi). on aura le para!tre action gal ? 87creer79. 8 decaler79 ou 87surface79 Ln rcupre ces ; para!tres dans request Eota!!ent le para!tre action $ui prcisera $uelle opration on veut appeler 1a servlet conservera le dernier rectangle cr (avec un pre!ier rectangle dfini par dfaut+ et les fonctions de dcalage et de surface seront appeles sur ce rectangle "our si!plifier. on !et les fonctions !tiers (!anipulation de rectangles+ directe!ent dans le code de la classe #B de la ervlet

<ans le code de la servlet RectServlet.1ava


&#e!ple . servlet rectangle

Code de la servlet ServRectangle.1ava


public class RectServlet extends HttpServlet { == rectange !anipul par la servlet protected Rectan/le rectan/le; public int calculSur8ace(Rectan/le rect) { return ( (rect$x@ , rect$x2) E (rect$'@ , rect$'2)); 7 public Rectan/le decalerRectan/le(Rectan/le rect, int x, '){ return ne Rectan/le(rect$x2 6 x, rect$'2 6 ', rect$x@ 6 x, rect$'@ 6 '); 7 public void init(Servlet%on8i/ con8i/) thro s Servlet!xception { == initialisation par dfaut du rectangle rectan/le = ne Rectan/le(20, @0, F0, G0); 7

#C

&#e!ple . servlet rectangle


Code de la servlet ServRectangle.1ava (suite+
protected void processRequest( HttpServletRequest request, HttpServletResponse response) thro s Servlet!xception, "#!xception { response$set%ontent&'pe((text)html;charset=*&+,-(); .rintWriter out = response$/etWriter(); tr' { == ent5te du docu!ent out$println((0html1(); out$println((0head1(); out$println((0title1&est de Servlet 5 RectServlet0)title1(); out$println((0)head1(); out$println((0bod'1(); out$println((0h21Servlet RectServlet0)h21(); == affichage du rectangle courant out$println((0p1!tat courant de mon rectan/le5(6rectan/le6(0)p1(); == rcupre l'identifiant de l'action ? raliser Strin/ action = request$/et.arameter((action(); == calcul de surface du rectangle courant i8 (action$equals((sur8ace()) int sur8ace = calculSur8ace(rectan/le); out$println((0p1Sur8ace 5 (6sur8ace6(0)p1(); 7

4D

&#e!ple . servlet rectangle


Code de la servlet ServRectangle.1ava (fin+
== cration d'un rectangle i8 (action$equals((creer()) { int x2 = "nte/er$parse"nt(request$/et.arameter((x2()); int '2 = "nte/er$parse"nt(request$/et.arameter(('2()); int x@ = "nte/er$parse"nt(request$/et.arameter((x@()); int '@ = "nte/er$parse"nt(request$/et.arameter(('@()); rectan/le = ne 7 Rectan/le(x2, '2, x@, '@);

out$println((0p1Rectan/le cr>> 5 (6 rectan/le 6 (0)p1();

catch (!xception e) { == en cas de pro-l!e. affiche un !essage out$println((0p10b1!rreur HH0)b10br )1(); out$println(e$toStrin/()6(0)p1(); 7 == fin du docu!ent * lien pour retour en arrire out$println((0p10a hre8=I((6request$/et%ontext.ath()6(I(1 Retour0)a10)p1(); out$println((0)bod'1(); out$println((0)html1(); 41 out$close(); 7

&#e!ple . servlet rectangle

3ffichage de la page GTM1


Ln re!plit les 4 cha!ps et slectionne 87crer79

42

&#e!ple . servlet rectangle

3prs clic sur 87e)cuter 9


e retrouve 87sur 9 la servlet $ui cre alors un rectangle

4#

&#e!ple . servlet rectangle

lection de retour pour revenir ? la page GTM1 puis choi) de 87calcul surface79

44

&#e!ple . servlet rectangle

3prs clic sur e)cuter


E)cute la servlet avec l'opration de calcul surface Ln voit $u'elle s'appli$ue sur le rectangle $u'on vient de crer et $ui a donc t conserv

4;

%ava $erver Page . %$P

"ages !i)tes contenant ? la fois


<u code GTM1 stati$ue <u code Pava $ui est e)cut d%na!i$ue!ent et gnre du code GTM1 1es parties stati$ues et Pava sont entre!5les pour for!er une page P " 1e navigateur client rcupre une page GTM1 standard contenant

1es parties stati$ues 1es parties en Pava re!places par le code GTM1 $u'elles ont gnres 1e serveur d'e)cution de la P " la traduit d'a-ord en une servlet co!plte $uivalente et c'est cette servlet $ui est 4> e)cute

En prati$ue

%$P . insertion de code %ava

3ttri-uts i!plicites (non dclars+ utilisa-les dans le code Pava


i!ilaires ? ce $u'on aurait dans une servlet

out * flu) de sortie te)te dans le$uel on crit le code GTM1 gnr par les parties de code Pava request * para!tres de l'appel de la P " = ervlet response * pour renvo%er la rponse au client session * la session spcifi$ue au client courant config * configuration de la P "

pcifi$ue au fonctionne!ent des P "


page * l'instance de la P " = ervlet ($uivalent du this+ e"ception * l'e)ception $ui a t leve en cas de pro-l!e application * donnes co!!unes ? toutes les P " du serveur pageConte"t * conte)te de la page (gestion d'attri-uts ...+ 4@

2alises spciales pour insrer du code Pava


%$P . insertion de code %ava

Trois -alises 56 ... 67. 568 ... 67 et 56) ... 67 "eut insrer plusieurs de ces -alises dans une !5!e page P " P " co!pile en ervlet donc unicit de la P " gale!ent <claration d'attri-uts et de !thodes Ils seront glo-au) ? tous les appels de la P " pour tous les clients criplet * suite d'instructions Pava $ui sera e)cute ? cha$ue appel de la page P " i on % dclare des attri-uts. ils sont locau) ? cha$ue appel Evalue le e"pr et affiche le rsultat dans le code GTM1 E$uivalent de 56 out.print(e"pr) 67

"oint i!portant

568 ... 67

56 ... 67

56) e"pr 67

4B

%$P . insertion de code %ava

2alise spciale 569 page .... 67


Infor!ations gnrales sur la P "

3 utiliser si les valeurs par dfaut de la page sont ? !odifier 569 page import ) 1ava.util.:ector 67 "ar dfaut du te)t=ht!l 569 page content%ype ) ;;image'png;; 67 E)cuter une P " en cas d'erreur rencontre

I!port de classes Pava

T%pe MIME de la page


&estion des erreurs

569 page error/age);;erreur.1sp;; 67 569 page is!rror/age);;true;; 67

"rciser $u'une P " est ou pas une page d'erreur

4C

&#e!ple . %$P hello world

E)e!ple -asi$ue de page P "


Code stati$ue GTM1 * affiche 87Gello ,orld T79 Code d%na!i$ue et code Pava

&estion d'un co!pteur local et d'un co!pteur glo-al d'appel 3ffichage de ces 2 co!pteurs (via !lange code stati$ue et d%na!i$ue+

I!pl!entation
Trois insertions de code Pava pour grer les co!pteurs
1. UV ...VW * dclaration du co!pteur local 2. UVT ... VW * dclaration du co!pteur glo-al et d'une !thode d'incr!entation de ce co!pteur #. UV ... VW * incr!entation des 2 co!pteurs "uis affiche via des 56) ... 67 les valeurs des co!pteurs ;D

&#e!ple . %$P hello world

Code de la page P "


5html7 5head7 5meta http,equiv)&Content,%ype& content)&te"t'html( charset)*%+,-&7 5title7<S/ Hello0orld5'title7 5'head7 5=ody7 5h37Hello 0orld85'h37 56 int n=>ocal ) ?( 67 568 int n=Glo=al ) ?( void inc@=Glo=al() A n=Glo=alBB( C 67 56 n=>ocalBB( inc@=Glo=al()( 67 5p7Compteur local 2 56) n=>ocal 67 5=r '7 Compteur glo=al 2 56) n=Glo=al 675'p7 5'=ody7 5'html7

1gende couleur * !ode e"cut localement !ode dclar glo#alement $valuation de la valeur des attri#uts !ode %&'( statique

;1

&#e!ple . %$P hello world

E)e!ple d'e)cution
3prs 4 charge!ents de la servlet co!pteur glo-al passe ? ; !ais le local est s%st!ati$ue!ent ? 1

;2

&#e!ple . %$P hello world

Co!!entaires sur le code prsent


<ans dernire -alise UV ... VW

3urait pu re!placer 87incGlo=al@=()( 9 par directe!ent 87glo=al@=BB(DE 1es attri-uts et !thodes dclares en glo-al sont tous accessi-les directe!ent

Ee peut par contre pas dclarer une !thode pour incr!enter le co!pteur local

void inc@=>ocal A n=>ocalBB( C Ee peut pas dclarer de !thode dans une -alise UVT ... VW

Ee contient $u'une suite d'instructions ? e)cuter 1'attri-ut n=>ocal est local et n'est pas connu dans le code glo-al

Ee peut pas dclarer cette !thode dans la -alise UV ... VW

;#

&#e!ple . %$P rectangle

M5!e e)e!ple de gestion des rectangles


Ln a -esoin d'une seule page P " au total Elle fera l'affichage du for!ulaire avec GTM1 standard et contiendra le code Pava des oprations (en vert+ Elle s'auto-appellera pour l'e)cution de l'opration choisie

Code la page rectangle.1sp


0head1 0meta http,equiv=(%ontent,&'pe( content=(text)html; charset=*&+,-(1 0title1Rectan/le0)title1 0)head1 0bod'1 0JKpa/e import=(rect$E( J1

la classe Rectangle est dfinie dans un pacMage rect

0h21:anipulation de rectan/es avec du <S.0)h21

;4

&#e!ple . %$P rectangle

Code la page rectangle.1sp (suite+


0JH Rectan/le rectan/le = ne Rectan/le(20, @0, F0, G0); public int calculSur8ace(Rectan/le rect) { return ( (rect$x@ , rect$x2) E (rect$'@ , rect$'2)); 7 public Rectan/le decalerRectan/le(Rectan/le rect, int x, int '){ return ne Rectan/le(rect$x2 6 x, rect$'2 6 ', rect$x@ 6 x, rect$'@ 6 '); 7

J1

08orm action=(rectan/le$Lsp( method=(post(1 0p1 0table border=(0(1 0tr1 0td1=2 ou = d>cala/e0)td1 0td10input 0tr1 0td1?2 ou ? d>cala/e0)td1 0td10input 0tr1 0td ali/n=(ri/ht(1=@0)td1 0td10input 0tr1 0td ali/n=(ri/ht(1?@0)td1 0td10input 0)table10)p1

name=(x2(1 name=('2(1 name=(x@(1 name=('@(1

0)td1 0)td1 0)td1 0)td1

0)tr1 0)tr1 0)tr1 0)tr1

0p10input t'pe=(radio( name=(action( value=(creer( checAed=(checAed( )1 %r>er Rectan/le0br )1 0input t'pe=(radio( name=(action( value=(decaler( )1B>caler Rectan/le0br )1 0input t'pe=(radio( name=(action( value=(sur8ace( )1%alcul Sur8ace0)p1 ;;

&#e!ple . %$P rectangle

Code la page rectangle.1sp (suite+


0p10input t'pe=(submit( value=(!x>cuter(1 0input t'pe=(reset( value=(Remise C D>ro10)p1 0)8orm1 0p1Rectan/le courant 5 0J= rectan/le$toStrin/() J1 0)p1 0J tr' { Strin/ action = request$/et.arameter((action(); == cas du pre!ier affichage de la page * pas de para!tre == il n'% a pas d'actions ? e)cuter i8 (action == null) return; )) cr>ation d4un rectan/le i8 (action$equals((creer()) { int x2 = "nte/er$parse"nt(request$/et.arameter((x2()); int '2 = "nte/er$parse"nt(request$/et.arameter(('2()); int x@ = "nte/er$parse"nt(request$/et.arameter((x@()); int '@ = "nte/er$parse"nt(request$/et.arameter(('@()); rectan/le = ne Rectan/le(x2, '2, x@, '@); out$println((0p1Rectan/le cr>> 5 (6rectan/le 6 (0)p1();

;>

&#e!ple . %$P rectangle

Code la page rectangle.1sp (suite+


i8 (action$equals((sur8ace()) { int sur8ace = calculSur8ace(rectan/le); out$println((0p1Sur8ace 5 (6sur8ace6(0)p1(); 7 7 )) tr' catch (!xception e) { out$println((0p10b1!rreur HH0)b10br )1(); out$println(e$toStrin/()6(0)p1(); 7

)) calcul de sur8ace du rectan/le courant

J1 0)bod'1 0)html1

Ln utilise ici les attri-uts i!plicites


request * pour rcuprer les para!tres passs avec get/arameter() out * flu) de sortie pour gnrer du code GTM1 'tilisation du out co!!e avec une servlet 'tilisation d'une -alise UVX ... VW dans du code GTM1

<eu) faSons de gnrer du code GTM1 en d%na!i$ue


;@

3ffichage par dfaut de la page rectangle.1sp

&#e!ple . %$P rectangle

Ln va re!plir les 4 cha!ps avec valeurs 4;. 12. ;C. 4@ ;B et lancer l'e)cution de 87crer rectangle79

&#e!ple . %$P rectangle

Isultat de la cration du rectangle

Ln e)cute !aintenant ? partir de cette page 87calcul surface79

;C

&#e!ple . %$P rectangle

Isultat du calcul de surface

>D

Modle par dfaut d'e)cution


&#cution concurrente

ervlet = page P " est uni$ue erveur GTT" peut avoir plusieurs re$u5tes d'accs ? la servlet=P " par plusieurs clients ? la fois

E)cution !ulti-threade par le serveur GTT" "lusieurs threads peuvent donc e)cuter en !5!e te!ps du code de la !5!e servlet=P " ervlet

'assurer $u'un seul thread ? la fois e)cute une servlet=P "


I!pl!entation de l'interface (vide+ Single%hreadFodel pu=lic class FaServlet e"tends HttpServlet implements Single%hreadFodel "asse par les para!tres gnrau) de la page * is%hreadSafe 569 page is%hreadSafe)&true& 67

P "

"our une gestion plus fine et plus prcise

Mar$uer des !thodes ou des parties de code de la servlet=P " >1 avec synchroniGed

5o!!unication inter6l!ents

Cha$ue servlet = P " possde un tat glo-al ou un tat local pour cha$ue client

"eut aussi vouloir avoir un tat glo-al ? toutes les pages P " ou les servlets gres par le serveur GTT"
"er!et de dfinir des attri-uts co!!e pour une session. !ais co!!uns ? toutes les pages P " gres par le serveur GTT" E)e!ple * code Pava pour grer un co!pteur co!!un ? toutes les pages P "

3ttri-ut i!plicite application dans P "


56 #nteger compteur ) (#nteger)application.getHttri=ute(&compteur&)( if (compteur))null) A '' on crIe le compteur qui n;e"istait pas compteur ) ne #nteger(?)( application.setHttri=ute(&compteur&, compteur)( out.println(&5p7CrIation du compteur ...5'p7&)( C application.setHttri=ute(&compteur&, BBcompteur)( >2 out.println(&5p7Compteur glo=al 2 &BcompteurB&5'p7&)( 67

5o!!unication inter6l!ents

Etat co!!un glo-al au serveur GTT"


3utre techni$ue * dfinir une classe accessi-le (dans !5!e pacMage+ par toutes les servlets = P "

Y dfinir des attri-uts ou !thodes stati$ues E)e!ple pour le co!pteur

pu=lic class Compteur A protected static int compteur ) ?( pu=lic synchroniGed static int ne"t:alue() A return BBcompteur( C C

Ln accde par e)e!ple au co!pteur glo-al dans une servlet ou une page P "

out.println(&5p7@om=re d;appels 2 &BCompteur.ne"t:alue()B&5'p7&)(

>#

<ans une servlet ou une page P ". possi-ilit

7elation entre servlets/%$P

<'appeler une autre servlet ou page P " pour dlguer le traite!ent de la re$u5te ou inclure un rsultat suppl!entaire dans celui de la servlet=page P " courante ervlet

Icupre le 87re$uest dispatcher 9

RequestJispatcher rd ) request.getRequestJispatcher( &maServlet& )(

/ait suivre le traite!ent de la re$u5te ou inclus un traite!ent ralis par la servlet 8 !a ervlet79

rd.for ard(request, response)( rd.include(request, response)(

"age P "

Inclusion du rsultat d'une autre page

51sp2include page);;ma/age.1sp;;75'1sp2include7

/aire suivre le traite!ent de la re$u5te ? une autre page P "


51sp2for ard page);;ma/age.1sp;;75'1sp2for ard7 <ans les 2 cas. peut passer des para!tres ? la page appele via inclusion >4 51sp2param name);;compteurD;; value);;34;; '7

7elation entre l!ents

En cas d'erreur dans une page P ". peut aussi e)cuter une page P " particulire
<ans la page. insrer une redirection en cas d'erreur

569 page error/age);;erreur.1sp;; 67 En cas d'e)ception leve par une instruction Pava. la page erreur.1sp est alors e)cute "rciser $ue l'on est une page d'erreur

<ans erreur.1sp

569 page is!rror/age);;true;; 67 5p7!"ception levIe 2 56) e"ception 67 5'p7 1'attri-ut i!plicite e"ception est une e)ception Pava classi$ue. on peut appeler dessus des !thodes co!!e getFessage(), getCause(), printStacK%race(), ... >;

"eut alors rcuprer l'e)ception leve et par e)e!ple l'afficher


7etour sur l'e#e!ple des rectangles

<ans une P ". une part i!portante du code est ddie ? si!ple!ent afficher le contenu d'o-6ets
M5!e avec des UVX ... VW Sa peut 5tre relative!ent lourd ? raliser Ieprenons notre !anipulation de rectangles

E)e!ple
1a servlet RectServlet gre le rectangle courant et e)cute les actions associs 'ne page GTM1 affiche un for!ulaire pour rentrer les diffrents cha!ps i l'utilisateur veut !odifier une des 4 valeurs de coordonne (%1 par e)e!ple+ du rectangle courant. il doit rentrer les 4 valeurs Ln pourrait re!plir par dfaut les 4 cha!ps avec le contenu du rectangle courant >>

7etour sur l'e#e!ple des rectangles

Modifie RectServlet.1ava pour a6outer le rectangle en tant $u'attri-ut de la session


protected void processRequest(...) A HttpSession session ) request.getSession(true)( '' premier appel de la servlet, on crLe l;attri=ut rectangle if (session.getHttri=ute(&rectangle&) )) null) session.setHttri=ute(&rectangle&, rectangle)( if (action.equals(&creer&)) A '' rIcupLre les paramLtres "3, "4, y3, y4 dans la requMte (...) rectangle ) ne Rectangle("3, y3, "4, y4)( out.println(&5p7Rectangle crII 2 &Brectangle B &5'p7&)( '' met N 1our l;attri=ut de la session avec le nouveau rectangle session.setHttri=ute(&rectangle&, rectangle)( C >@ (...)

7etour sur l'e#e!ple des rectangles

Transfor!e la page GTM1 associe en page P " pour pouvoir rcuprer le rectangle associ ? la session

569page import ) &rect.Rectangle& 67 56 Rectangle rect )(Rectangle) session.getHttri=ute(;;rectangle;;)( 67 5h37Fanipulation de rectangle avec une servlet5'h37 5form action)&RectServlet& method)&post&7 5p7 5ta=le =order)&?&7 5tr7 5td7X35'td7 5td75input name)&"3& value)&56)rect.getX3() 67&75'td7 5'tr7 (...) Ln rcupre l'attri-ut 87rectangle79 associ ? la session Ln s'en sert pour !ettre une valeur par dfaut dans les cha!ps d'entre des 4 valeurs de coordonnes

>B

7etour sur l'e#e!ple des rectangles

1e code prsent se!-le pertinent ... !ais ne !arche pas

3u pre!ier charge!ent de la P ". aucun appel n'a encore t fait sur la ervlet * pas d'attri-ut 87rectangle79 associ ? la session

1'attri-ut rect vaut donc null et 56) rect.getX3() 67 lve une e)ception 569page import ) &rect.Rectangle& 67 56 Rectangle rect ) (Rectangle) session.getHttri=ute(;;rectangle;;)( String "3 ) ;;;;, "4) ;;;;, y3 ) ;;;;, y4 ) ;;;;( if (rect 8) null) A "3 ) ne #nteger(rect.getX3()).toString()( (...) C 67 5h37Fanipulation de rectangle avec une servlet5'h37 5form action)&RectServlet& method)&post&7 5p7 5ta=le =order)&?&7 5tr7 5td7X35'td7 5td75input name)&"3& value)&56) "3 67&75'td7 >C (...)

Il faut grer e)plicite!ent le cas oK l'attri-ut n'est pas encore dfini

7etour sur l'e#e!ple prcdent

3utre solution pour rcuprer le rectangle courant


E)pression 'E1 ('nified E)pression 1anguage+ i!plifie l'accs au) attri-uts (dans le sens des attri-uts associs ? une session+

1a page P " devient tout si!ple!ent 5h37Fanipulation de rectangle avec une servlet5'h37 5form action)&RectServlet& method)&post&7 5p7 5ta=le =order)&?&7 5tr7 5td7X35'td7 5td75input name)&"3& value);; OAsessionScope.rectangle."3C;;75'td7
(...+

1e cha!p d'entre 01 est initialis par le contenu de la proprit "3 de l'attri-ut rectangle associ ? la session i l'attri-ut rectangle n'e)iste pas. ne gnre pas d'erreur. retourne si!ple!ent une chaine vide

"lus -esoin de vrifier e)plicite!ent $ue l'attri-ut e)iste

@D

8&L 9 %$TL

'nified E)pression 1anguage ('E1+

1angage d'e)pression per!ettant si!ple!ent dans une page P "


<e rcuprer des attri-uts associs ? des conte)tes

3ttri-uts de la session. de l'application. du header ou de la re$u5te GTT" ... 3ddition. !ultiplication. !odulo ...

<'crire des e)pressions de calcul ou de test

Co!paraisons de valeurs. oprateurs logi$ues (L'. ET ...+

Pava erver "ages tandard Tag 1i-rar% (P T1+


Ense!-les de -alises offrant des fonctionnalits pour !anipuler des fichiers 0M1. accs ? des 2<<s. l'internationalisation ... Ense!-le 87core79 per!et nota!!ent de !anipuler si!ple!ent des ense!-les de donnes. faire des tests et d'associer des -alises GTM1 (ou autres+ ? ces traite!ents ... /acilite grande!ent dans une page P " l'affichage de donnes @1 retourns par la logi$ue !tier

En co!-inant 'E1 et P T1

3ttri-ut

8&L . attributs, proprits

Instance d'une classe Pava respectant $uel$ues contraintes structurelles * Pava 2eans

<finit des proprits

'n attri-ut (de la classe+ avec un getter et un setter associ

<finit un constructeur sans para!tre

Ln peut ensuite accder au) proprits des attri-uts via une notation pointe ? partir d'un certain conte)te

E)e!ple * sessionScope.rectangle."3

Conte)te * sessionScope 3ttri-ut * rectangle "roprit * "3 ((Rectangle)sessionScope.getHttri=ute(;;rectangle;;)).getX3() Ln voit -ien l'o-ligation d'avoir un getter=setter associ ? cha$ue proprit pour pouvoir % accder

Ievient ? e)cuter de !anire rfle)ive


i l'attri-ut ou une de ses proprits n'est pas dfinie (valeur null+ @2 gnre une chaZne vide

8&L . conte#tes et ob:ets i!plicites

L-6ets i!plicites. dont certains si!ilaires au) o-6ets i!plicites P "


pageConte"t. param. param:alues. header. header:alues. cooKie. init/aram Conte)tes (87scope79+. ? partir des$uels on peut associer des attri-uts

pageScope * la page P " requestScope * la re$u5te GTT" sessionScope * la session associe avec le navigateur client applicationScope * conte)te glo-al ? toutes les pages P " du serveur

@#

3ccde au) donnes d'un ta-leau (arra%. list ...+ ou d'une !ap via une notation inde)e

8&L . tableau# et !ap

attPinde"Q

3vec inde) $ui est soit la cl pour une !ap. soit l'inde) pour un ta-leau "eut aussi 5tre le contenu d'une varia-le "our un ta-leau. peut utiliser un inde) sous for!e d'entier ou de chaine

E)e!ple * une servlet e)cute le code suivant

Iectangle rect1 X neF Iectangle(1D.1D.2D.2D+[ Iectangle rect2 X neF Iectangle(#D. #D. ;D. ;D+[ GashMapU tring. IectangleW !apIect X neF GashMapU tring. IectangleW(+[ Iectangle\] arra%Iect X neF Iectangle\2][ int inde) X 1[ !apIect.put(^pre!ier^.rect1+[ !apIect.put(^second^. rect2+[ arra%Iect\D] X rect1[ arra%Iect\1] X rect2[ session.set3ttri-ute(^!apIect^. !apIect+[ session.set3ttri-ute(^arra%Iect^. arra%Iect+[ session.set3ttri-ute(^inde)^. inde)+[

@4

8&L . tableau# et !ap

1a servlet forFarde la re$u5te ? la page P "

5p7 Fap ,7 &premier& 2 OAsessionScope.mapRectP&premier&Q."3C5=r '7 Fap ,7 ;second; 2 OAsessionScope.mapRectP;second;Q."3C5=r '7 Fap ,7 &troisieme& 2 OAsessionScope.mapRectP&troisieme&Q."3C5=r '7 Hrray ,7 ? 2 OAsessionScope.arrayRectP?Q."3C5=r '7 Hrray ,7 ;3; 2 OAsessionScope.arrayRectP;3;Q."3C5=r '7 Hrray ,7 4 2 OAsessionScope.arrayRectP4Q."3C5=r '7 Hrray ,7 inde" 2 OAsessionScope.arrayRectPsessionScope.inde"Q."3C5=r '7 5'p7

3ffichage rsultant

Fap ,7 &premier& 2 3? Fap ,7 ;second; 2 .? Fap ,7 &troisieme& 2 Hrray ,7 ? 2 3? Hrray ,7 ;3; 2 .? Hrray ,7 4 2 Hrray ,7 inde" 2 .?

i des l!ents dans la !ap n'e)istent pas ou si on dpasse@; l'inde) !a) du ta-leau. renvoie une chaine vide

8&L . oprateurs

Lprateurs logi$ues
RR (ou and+. SS (ou or+. 8 (ou not+ )) (ou eq+. 8) (ou ne+. W (ou gt+ ... B. ,. T. ' (ou div+. 6 (ou mod+ T%pes de no!-re disponi-les * entier et rel empty * renvoie vrai si valeur 87vide79
Egale ? null. chaine vide. un ta-leau vide ou une !ap vide _ * choi) conditionnel @> test U choi":rai 2 choi"+au"

Lprateurs de co!paraison Lprateurs de calcul

<ivers

"our utiliser du P T1 core dans une page P ". insrer la -alise suivante dans la page

%$TL . core

569tagli= uri)&http2''1ava.sun.com'1sp'1stl'core& prefi")&c& 67 3u dploie!ent. ne pas ou-lier le lien vers la li-rairie (.6ar+ e)terne i!pl!entant cet ense!-le de -alises 5c2out value);;valeur;; '7 5c2if test);;condition;;7 ... 5'c2if7 5c2choose7 5c2 hen test);;condition1;;7 ... 5'c2 hen7 5c2 hen test);;condition2;;7 ... 5'c2 hen7 ... 5c2other ise7 ... 5'c2other ise7 5'c2choose7

3ffichage d'une valeur

Test d'une valeur

Choi) conditionnels

@@

%$TL . core

"arcours d'une liste = ta-leau


5c2for!ach items);;laListe;; var);;eltCourant;;7 ... 5'c2for!ach7 items * la liste ou le ta-leau ? parcourir var * varia-le $ui contiendra l'l!ent courant Co!!e pour une liste !ais sur l'l!ent courant

"arcours d'une !ap


3ccde ? sa cl via * eltCourant.Key 3ccs ? sa valeur via * eltCourant.value

3utres tags e)istants


5c2for%oKens7,5c2set7, 5c2remove7, 5c2catch7, 5c2import7, 5c2url7, 5c2redirect7, 5c2param7
@B

%$TL . core

E)e!ple
5c2if test)&OAempty sessionScope.arrayRectP4Q."3C&7 /as d;IlIment d;inde" 4 dans le ta=leau5=r '75=r '7 5'c2if7 Surface des rectangles 25=r '7 5c2for!ach items)&OAsessionScope.arrayRectC& var)&rect&7 ,7 5c2out value)&OA(rect."4 , rect."3) T (rect.y4 , rect.y3)C&'75=r '7 5'c2for!ach7

3ffichage rsultant
/as d;IlIment d;inde" 4 dans le ta=leau Surface des rectangles 2 ,7 3?? ,7 V??

@C

$ervlet vs %$P

ervlet
C'est du 6ava standard $ui est e)cut 1es lignes 87out.println(+79 servent ? gnrer le code GTM1 $ui sera affich "ro-l!e * une -onne partie de ce code GTM1 est stati$ue

Ent5te. affichage du titre ... 'n peu lourd ? gnrer de la sorte

"age P "

"er!et de 87!langer79 du code GTM1 standard avec du Pava standard Meilleure dcoupage des diffrentes parties $u'avec des servlets Moins lourd ? progra!!er $u'une servlet

i!plification des affichages des donnes. surtout si co!-in avec 'E1 et P T1 Mais !oins structur du point de vue du code Pava

BD

$ervlet et %$P

ervlet = P "
Technologie cot serveur per!ettant donc la gnration d%na!i$ue de page GTM1 Intr5t est de profiter de la puissance d'un langage L-6et 1e code e!-ar$u dans les ervlet = P " n'intgre pas de prfrence le code et la logi$ue !tier

En prati$ue

Ln s'appuie sur d'autres l!ents (co!posants EP2 par e)e!ple+ 1ogi$ue de prsentation

"our un serveur applicatif ,e-. dcouper son r`le en

Manire de prsenter et de gnrer les pages au) clients 3ppele par la logi$ue applicative pour gnrer les pages

1ogi$ue !tier

B1

ra!ewor"s de persistance . introduction ; /ibernate

B2

Probl!atique

E)e!ple si!ple d'application


&rer une liste de personnes "rogra!!ation partie !tier = client en Pava

Classe $ui contient les infor!ations sur une personne pu=lic class /ersonne A String nom( #nt age( C 1ors du stocMage d'une personne. on lui associera un identifiant uni$ue '' mIthodes d;accLs au" attri=uts age et nom

<eu) techni$ues de stocMages de l'ense!-le de personnes


<irecte!ent en Pava via une GashMap Hashmap5#nteger, /ersonne7 personnes( Hia un &2< avec accs en O1 au) donnes

tocMage sous for!e de ta-les O1

personne (int id, varchar(4?) nom, int age)

B#

Probl!atique

Code pour rcuprer une personne via son id


"ur Pava
pu=lic /ersonne get/ersonne(int id) thro s #nvalid#d!"ception A '' si la personne n;e"iste pas, lLve e"ception if ( 8 (personnes.containsWey(ne #nteger(id)))) thro ne #nvalid#d!"ception(&invalid inde" value 2 &Bid)( '' sinon, retourne son identifiant return (personnes.get(ne #nteger(id)))(

Manipule directe!ent la GashMap personnes Code 87naturel79. progra!!ation Pava standard


B4

Probl!atique

Pava avec stocMage 2<< et accs via P<2C


pu=lic int get#d(/ersonne p) thro s #nvalid#d!"ception A try A Statement requete ) connection.createStatement()( '' requMte SX> pour rechercher la personne ResultSet result ) requete.e"ecuteXuery(&S!>!C% @$F, HG! +R$F /!RS$@@! 0H!R! #J)Y&&BidB&Y&&)( '' regarde si la requMte a renvoyI quelque chose 2 si Za n;est pas '' le cas, la personne n;e"istait pas if (8result.ne"t()) thro ne #nvalid#d!"ception(&invalid inde" value 2 &Bid)( '' sinon, N partir du rIsultat retournI, instancie une personne '' avec les valeurs du rIsultat else return ne /ersonne(result.get#nt(&age&), result.getString(&nom&))( C catch(SX>!"ception e) A System.err.println(e)( C C

B;

Probl!atique

Pava avec stocMage 2<< et accs via P<2C


Ecessite des re$u5tes O1

'tilisation d'un fra!eForM ddi * P<2C

ort du for!at 87standard79 de reprsentation Pava des donnes

'ne re$u5te de t%pe E1ECT retourne un Iesult et

C'est ? dire un ense!-le de ligne de plusieurs colonnes

Ln accde au) l!ents du Iesult et en naviguant selon les lignes et les colonnes "eu prati$ue !ais difficile de faire autre!ent vu ce $ue retourne de !anire native les re$u5tes O1

auf ? passer par des &2< o-6et-relationnel

B>

Probl!atique

Pava avec stocMage 2<< et accs via P<2C


3u dela de l'accs ? faire ? distance

Oui co!ple)ifie forc!ent les choses !ais ne peut pas % couper Cot 2<<

Ieprsentation des donnes trs diffrentes

tructure en ta-le avec langage de re$u5te ddi Icupre tou6ours une 87sous-ta-le79 via le rsultat de l'e)cution d'une re$u5te de t%pe E1ECT Instances de classe ("ersonne ici+ * o-6ets 1es o-6ets sont associs entre eu) et for!ent un graphe d'o-6et dans l'application

Cot Pava

_
B@

Probl!atique

<oit 5tre capa-le de faire la correspondance d'une reprsentation ? une autre


"as si!ple * d'une reprsentation o-6et ? une reprsentation relationnelle

olution
1e faire ? la !ain

Co!!e pour notre e)e!ple Cot 2<<. la structure de stocMage intgrera des concepts o-6ets "assage plus facile du progra!!e au stocMage dans la -ase Mais tou6ours -esoin de faire des re$u5tes e)plicites BB

'tiliser une -ase de donnes relationnelle oriente o-6et


'tiliser un fra!eForM de persistance

ra!ewor" de persistance

"rincipes
'a-straire des pro-l!ati$ues de stocMage des donnes

"ouvoir !anipuler directe!ent des entits !tiers indpenda!!ent de leur stocMage ph%si$ue 1a structure des classes utilises dans l'application 1e stocMage ph%si$ue utilis par le support de persistance

<finition de !appings entre


&nrale!ent. un &2< relationnel

1ors de l'e)cution de l'application


Cration. suppression. !anipulation. collections d'o-6ets ... grs de !anire classi$ue. progra!!ation 87standard79 1e fra!eForM fait le lien entre le graphe d'o-6et en !!oire dans l'application et le stocMage ph%si$ue

T%pi$ue!ent * envoi de re$u5te O1 au &2< pour rcuprer des donnes. les !odifier. les a6outer = suppri!er

BC

ra!ewor" de persistance

Intr5t des fra!eForMs de persistance


"lus -esoin de se proccuper du stocMage ph%si$ue et des pro-l!es de correspondance Co!!e on le voit dans notre e)e!ple de l'atelier

Ecriture des re$u5tes O1 via P<2C est asseJ lourd 1'i!pl!entation des accs au) donnes peut reprsenter un te!ps i!portant lors du dveloppe!ent d'une application

Ln gagne ainsi en te!ps de dveloppe!ent et en indpendance des supports ph%si$ues

uffit de changer les rgles de !appings sans !odifier le code de l'application

Gi-ernate

/ra!eForM de persistance li-re pour le !onde Pava

EGi-ernate pour .Eet

tandard de fait. trs utilis dans l'industrie 'tilis gale!ent par P"3 (fra!eForM standard de persistance sous Pava : Pava "ersistence 3"I+

CD

/ibernate
"rincipes gnrau) d'Gi-ernate
<finition des structures de donnes = entits !anipules

Ielation entre la structure cot 2<< et la structure des entits


Hia des fichiers 0M1 Lu des classes Pava annotes

Cot Pava. l'entit est une classe Pava dite persistante

'n "LPL * "lain Lld Pava L-6et


Classe Pava totale!ent standard avec dfinition d'attri-uts. d'accesseurs. de constructeurs pour gestion donnes de l'entit Ee s'appuie donc pas sur des fra!eForMs ou li-rairies particuliers. contraire!ent par e)e!ple au) entits d'EP2

"ersistante * son contenu est li avec les donnes ph%si$ues sur la 2<< et est sauvegard dans cette 2<< <finition. en 0M1. d'un ense!-le de fichiers de configuration

Mapping d'une entit vers un support ph%si$ue Configuration gnrale de l'accs au support ph%si$ue

C1

/ibernate

"rincipes gnrau) d'Gi-ernate (fin+


"our grer la persistance. on cre une session Gi-ernate Hia cette session. peut

Icuprer sous for!e d'instances de "LPL des donnes stocMes par le support ph%si$ue

'tilisation nota!!ent d'GO1 (Gi-ernate Ouer% 1anguage+

Modifier le contenu de ces "LPL. leurs associations. en a6outer. en suppri!er. ... 1e fra!eForM fera le lien entre les !odifications locales et le stocMage ph%si$ue

/onctionne en !ode transactionnel pour les !odifications


1. Cration d'une transaction 2. Modification des o-6ets #. Halidation de la !odification (co!!it+ ou annulation en cas de pro-l!e (roll-acM+

C2

&#e!ple /ibernate

E)e!ple de gestion de sports et de disciplines


'n sport contient plusieurs disciplines Ta-les du &2< (Lracle ici+

sport (code)sport . intitule+ discipline (code)discipline. intitule. codeasport+

Ici cot Pava. on choisira d'avoirdes o-6ets de t%pe Sport et Jiscipline


3vec les !5!es structures de donnes $ue ce $ui est stocM dans la -ase Mais Sa n'est pas une o-ligation d'avoir e)acte!ent la !5!e chose (voir plus loin+

C#

&#e!ple /ibernate

Contenu des ta-les pour l'e)e!ple


Ta-le sport

code M sport M intitule ,,,,,,6,,,,,,,,,,, 2 M athletisme @ M sAi F M natation code M M code discipline M intitule M sport ,,,,,,,,,,,6,,,,,,,,,,,,,,,,,,6,,,,,, 2 M 200 metres M 2 @ M @00 metres M 2 F M saut en hauteur M 2 G M saut en lon/ueur M 2 N M 200m G na/es M F O M 200m papillon M F P M marathon M 2

Ta-le discipline

C4

/ibernate . e#) con(iguration gnrale

Configuration gnrale d'Gi-ernate


Uhi-ernate-configurationW Usession-factor%W Upropert% na!eX^hi-ernate.dialect^Worg.hi-ernate.dialect.Lracle<ialectU=propert%W Upropert% na!eX^hi-ernate.connection.driveraclass^Woracle.6d-c.Lracle<riverU=propert%W Upropert% na!eX^hi-ernate.connection.url^W6d-c*oracle*thin*@scinfeDCC*1;21*etud1DU=propert%W Upropert% na!eX^hi-ernate.connection.userna!e^WecariouU=propert%W Upropert% na!eX^hi-ernate.connection.passFord^WtotoU=propert%W Upropert% na!eX^hi-ernate.shoFas$l^WtrueU=propert%W U!apping classX^data. port^ fileX^^ 6arX^^ pacMageX^^ resourceX^data= port.h-!.)!l^=W U!apping classX^data.<iscipline^ fileX^^ 6arX^^ pacMageX^^ resourceX^data=<iscipline.h-!.)!l^=W U=session-factor%W U=hi-ernate-configurationW

Ln % trouve. nota!!ent

1es para!tres de conne)ion ? la -ase Lracle (avec le t%pe de driver ? utiliser+

Ln peut voir $ue l'accs en prati$ue se fera via P<2C E)* data.Sport (classe Pava+ dont le !apping est prcis dans C; Sport.h=m."ml

1'association d'un "LPL avec son fichier de !apping

/ibernate . e#) de (ichier de !apping

/ichier port.h-!.)!l

Uhi-ernate-!appingW Uclass na!eX^data. port^ ta-leX^ "LIT^ sche!aX^EC3IIL'^W Uid na!eX^code port^ t%peX^short^W Ucolu!n na!eX^CL<Ea "LIT^ precisionX^4^ scaleX^D^ =W Ugenerator classX^assigned^ =W U=idW Upropert% na!eX^intitule^ t%peX^string^W Ucolu!n na!eX^IETIT'1E^ lengthX^2D^ =W U=propert%W Uset na!eX^disciplines^ inverseX^true^W UMe%W Ucolu!n na!eX^CL<Ea "LIT^ precisionX^4^ scaleX^D^ =W U=Me%W Uone-to-!an% classX^data.<iscipline^ =W U=setW U=classW U=hi-ernate-!appingW

<ans classe data.Sport. attri-ut7codeSport correspond ? la colonne CL<Ea "LIT de la ta-le "LIT <finition d'un ense!-le no!! disciplines dans la classe data.Sport

Pointure avec la ta-le discipline * toutes les disciplines de ce sport

C>

/ibernate . e#) de P<%<

"LPL d'un sport. gnr ? partir du fichier de !apping


pu-lic class port i!ple!ents 6ava.io. erialiJa-le b private short code port[ private tring intitule[ private et disciplines X neF Gash et(D+[ pu-lic port(+ b c pu-lic port(short code port+ b this.code port X code port[ c pu-lic port(short code port. tring intitule. et disciplines+ b this.code port X code port[ this.intitule X intitule[ this.disciplines X disciplines[ c pu-lic short getCode port(+ b return this.code port[ c pu-lic void setCode port(short code port+ b this.code port X code port[ c pu-lic tring getIntitule(+ b return this.intitule[ c pu-lic void setIntitule( tring intitule+ b this.intitule X intitule[ c pu-lic et get<isciplines(+ b return this.disciplines[ c pu-lic void set<isciplines( et disciplines+ b this.disciplines X disciplines[ c

<finition des attri-uts. avec getter et setter associs

<finition des constructeurs (avec un constructeur sans para!tre+ C@


Iedfinir !thodes equals() et hashcode() pour gestion dans collections

/ibernate . e#) acc1s au# donnes

3ffichage de la liste des sports. avec pour chacun la liste de ses disciplines
'' crIation session Hi=ernate (et donc conne"ion au serveur $racle) Session session ) (ne Configuration().configure().=uildSession+actory()).openSession()( '' requMte en HX> 2 rIcupLre la liste de tous les sports, '' sous forme d;une liste <ava Xuery query ) session.createXuery(&from data.Sport&)( >ist sports ) query.list()( '' varia=les utilisIes pour le parcours de la liste des sports Set disciplines( #terator itSport, itJisc( Sport sport( Jiscipline disc(

CB

/ibernate . e#) acc1s au# donnes

3ffichage de la liste des sports. avec pour chacun la liste des disciplines (suite+
'' parcourt les sports itSport ) sports.iterator()( hile (itSport.has@e"t()) A sport ) (Sport) itSport.ne"t()( System.out.println(sport.getCodeSport() B & ,7 & B sport.get#ntitule())( '' rIcupLre l;ensem=le des disciplines du sport disciplines ) sport.getJisciplines()( itJisc ) disciplines.iterator()( '' parcourt les disciplines hile (itJisc.has@e"t()) A disc ) (Jiscipline) itJisc.ne"t()( System.out.println(& &Bdisc.getCodeJiscipline() B & ,7 &Bdisc.get#ntitule())( C CC

/ibernate . e#) acc1s au# donnes

3ffichage rsultant de l'e)cution

3 ,7 athletisme 3 ,7 3?? metres 4 ,7 4?? metres [ ,7 marathon V ,7 saut en longueur . ,7 saut en hauteur 4 ,7 sKi . ,7 natation \ ,7 3??m papillon ] ,7 3??m V nages

"oint intressant

3 partir d'un o-6et de classe Sport. on accde directe!ent ? sa liste de disciplines via getJisciplines() * ense!-le d'o-6ets

1es o-6ets sont chargs ? partir de la -ase directe!ent sans -esoin de traite!ent particulier. c'est transparent i on tait pass par du O1 via P<2C. on aurait du faire une re$u5te e)plicite du t%pe

E1ECT d /ILM <I CI"1IEE ,GEIE CL<Ea "LITX00

1DD

/ibernate . e#) acc1s au# donnes

3 l'e)cution. peut de!ander ? tracer les re$u5tes O1 effectues. ce $ui donne ici

Hibernate: select sport0_.CODE_SPOR as CODE1_0_! sport0_."# " $LE as "# " $LE0_ %ro& EC'R"O$.SPOR sport0_ 3 ,7 athletisme Hibernate: select discipline0_.CODE_SPOR as CODE2_1_! discipline0_.CODE_D"SC"PL"#E as CODE1_1_! discipline0_.CODE_D"SC"PL"#E as CODE1_1_0_! discipline0_.CODE_SPOR as CODE2_1_0_! discipline0_."# " $LE as "# " $LE1_0_ %ro& EC'R"O$.D"SC"PL"#E discipline0_ ()ere discipline0_.CODE_SPOR *+ 3 ,7 3?? metres 4 ,7 4?? metres [ ,7 marathon V ,7 saut en longueur . ,7 saut en hauteur (...)

"re!ier E1ECT * pour rcuprer la liste des sports <eu)i!e E1ECT * pour rcuprer la liste des disciplines du sport courant

1D1

/ibernate . e#) acc1s au# donnes

3utre e)e!ple * a6out d'une discipline au sport natation


try A '' ouvre la session et une transaction session ) (ne Configuration().configure().=uildSession+actory()).openSession()( trans ) session.=egin%ransaction()( '' rIcupLre l;instance de sport correpondant NDnatation (requMte en HX>) query ) session.createXuery(&select sport from Sport sport here sport.intitule);natation;&)( '' a1out du relais V " 3?? dans le sport natation en rendant l;o=1et persistant disc ) ne Jiscipline((short)-, sport, &relais V " 3??&)( session.persist(disc)( '' commit pour valider physiquement l;a1out trans.commit()( C catch (!"ception e) A System.err.println(&!rreur Hi=ernate 2 & B e)( '' pro=lLme 2 on annule la transaction trans.roll=acK()( C session.close()(

1D2

Eotes sur code d'a6out

/ibernate . e#) acc1s au# donnes


Ln passe une rfrence d'o-6et. on ne donne pas une cl identifiant un sport co!!e on le ferait avec O1 Ln est -ien dans de la !anipulation 87standard79 d'o-6ets

Ln cre l'o-6et discipline disc avec l'o-6et sport en para!tre

1e persist() sur cet o-6et per!et directe!ent. sans traite!ent suppl!entaire. de le rendre persistant (voir plus loin pour dtails+

C'est-?-dire l'enregistrer dans la 2<<

i on trace les re$u5tes O1. on o-tient


Hi=ernate2 select sport?^.C$J!^S/$R% as C$J!3^?^, sport?^.#@%#%*>! as #@%#%*>!?^ from !CHR#$*.S/$R% sport?^ here sport?^.#@%#%*>!);natation; Hi=ernate2 insert into !CHR#$*.J#SC#/>#@! (C$J!^S/$R%, #@%#%*>!, C$J!^J#SC#/>#@!) values (U, U, U)

1a pre!ire re$u5te est un E1ECT $ui rcupre les donnes du sport 87natation79 1a deu)i!e re$u5te est un IE EIT $ui a6oute la discipline 1D# $u'on vient de crer

&#e!ple plus dtaill

Modlisation !tier de l'application de sports avec a6out d'une classe = entit sportif

1D4

&#e!ple plus dtaill

Classes Sport et Jisciplines

Ieprend les !5!es contenus $u'on vient de voir

'ne discipline est associe ? un sport

36oute une entit Sportif

'n sportif prati$ue plusieurs disciplines et une discipline est prati$ue par plusieurs sportifs

3ssociation -idirectionnelle T 5,7 T pratique entre les 2 classes 1e no!-re de disciplines se dter!ine ? partir de l'association prati$ue E). en LC1 * conte"t Sportif def2 n=Jisciplines 2 int ) pratique ,7 siGe()

3ttri-ut n=Jisciplines est driv


'n sportif a un no! et une adresse 3ssociation unidirectionnelle drive 'sports entre Sportif et Sport

1es sports prati$us par le sportif e dter!ine de l'association pratique en rcuprant les sports 1D; de ces disciplines * pratique.sport ,7 asSet()

&#e!ple plus dtaill

Ta-les associes dans le &2<


Conserve les ta-les sport et discipline d6? vues

sport (code_sport, intitule) discipline (code_discipline, intitule, code^sport)

code^sport * cl trangre venant de sport

<onnes sur un sportif

'ne adresse est spcifi$ue ? un sportif * peut inclure les donnes de l'adresse avec les donnes du sportif

sportif(code_sporti%, nom, rue, code^postal,ville)

3ssociation entre disciplines et sportifs * ncessite une ta-le d'association

pratique(code_sporti%! code_discipline)

Cl pri!aire * co!-inaison de code^sportif et code^discipline Cls trangres * code^sportif de sportif et code^discipline 1D> de discipline

&#e!ple plus dtaill

"oint fonda!ental lors de l'utilisation d'un fra!eForM de persistance

"as de ncessit=peu reco!!and d'avoir un !apping 1 vers 1 entre une ta-le de la 2<< et une classe cot !tier

Ln !odlise d'un cot le !tier et de l'autre la 2<< en s'attachant ? faire les !eilleures !odlisations selon le do!aine

Cot !tier * structure logi$ue et facilit de !anipulation des donnes Cot 2<< * opti!iser la sauvegarde des donnes et perfor!ance d'accs

Ln dfinira ensuite les !appings ad$uats

<ans notre e)e!ple

1es donnes de la classe Hdresse et de la classe Sportif sont stocMes via une seule ta-le et non pas deu) ta-les diffrentes 1a ta-le d'association pratique n'a pas ? 5tre reprsente par une classe

1D@ 1'attri-ut n=Jisciplines est utile=pertinent seule!ent cot !tier

Ln aura directe!ent des !thodes dans les classes Sportif et Jiscipline pour rcuprer les l!ents correspondants 1e fichier de !apping per!ettra de directe!ent grer cette association

'apping pour la classe $porti(

Contenu de la classe Sportif * "LPL


pu=lic class Sportif implements 1ava.io.SerialiGa=le A private int codeSportif( private String nom( private Set disciplines ) ne HashSet(?)( private int n=Jisciplines( private Hdresse adresse( pu=lic Sportif() A C (...)

<finition des attri-uts


3vec disciplines $ui est une association ? cardinalit !ultiple donc utilise un et Cha$ue attri-ut doit possder un getter et un setter "eut en dfinir d'autres en plus 1DB

L-ligation d'un contructeur sans para!tre

'apping pour la classe $porti(

/ichier de !apping pour la classe Sportif

5hi=ernate,mapping7 5class name)&data.Sportif& ta=le)&sportif& catalog)&sports&7

1a classe persistante data.Sportif se -ase sur le contenu de la ta-le sportif 5id name)&codeSportif& type)&int&7 5column name)&code^sportif& '7 5generator class)&assigned& '7 5'id7 <finition d'un attri-ut codeSportif correspondant ? la colonne code^sportif de la ta-le 1a -alise 5id7 prcise $u'on est en train de dfinir un attri-ut 6ouant le r`le particulier d'identification de l'o-6et

2alise non o-ligatoire !ais forte!ent reco!!ande "ar principe. elle sera en gnral lie ? la cl pri!aire de la ta-le assigned * gr ? la !ain par celui $ui cre les classes "eut utiliser d'autres valeurs pour une gnration auto!ati$ue (voir plus loin+

1a -alise 5generator7 prcise co!!ent l'identifiant est gnr


1DC

'apping pour la classe $porti(

5property name)&nom& type)&string&7 5column name)&nom& length)&4?& '7 5'property7

2alise 5property7 dfinit une proprit au sens des Pava 2eans. concrte!ent. un attri-ut si!ple (autre $u'une collection. ta-leau ...+ de la classe

Ici l'attri-ut nom !appe la colonne nom de la ta-le

5property name)&n=Jisciplines& type)&integer& formula ) &(select count(T) from /RH%#X*! p here code^sportif ) p.code^sportif)& '7

Cha!p formula (ou -alise 5formula7+ per!et de dfinir une for!ule (e)pression O1+ au lieu d'un !apping vers une colonne d'une ta-le

Ici on co!pte le no!-re de disciplines associes au sportif courant via une re$u5te sur la ta-le pratique 1'appel du setter associ (set@=Jisciplines+ ne servira ? rien ... 11D

'apping pour la classe $porti(

5component name)&adresse& class)&data.Hdresse&7 5property name)&rue& type)&string&7 5column name)&rue& length)&]?& '7 5'property7 5property name)&code/ostal& type)&string&7 5column name)&code^postal& length)&]& '7 5'property7 5property name)&ville& type)&string&7 5column name)&ville& length)&3]& '7 5'property7 5'component7

2alise 5component7 dfinit un l!ent co!pos (relation 'M1 de co!position+ dans la classe courante

Ici on dfinit un attri-ut adresse de classe Hdresse $ui contient les attri-uts rue. code/ostal et ville !appant les colonnes $uivalentes dans la ta-le sportif (la ta-le de la classe englo-lante+ 1a classe Hdresse est dfinie co!!e un "LPL car sera persitante pu=lic class Hdresse implements 1ava.io.SerialiGa=le A private String rue( private String code/ostal( private String ville(

111

'apping pour la classe $porti(

5set name)&disciplines& inverse="false" ta=le)&pratique&7 5Key7 5column name)&code^sportif& not,null)&true& '7 5'Key7 5many,to,many entity,name)&data.Jiscipline&7 5column name)&code^discipline& not,null)&true& '7 5'many,to,many7 5'set7

2alise 5set7 dfinit un ense!-le de donnes Correspond ici au !apping d'une association avec une cardinalit !ultiple sur une autre ta-le (ici pratique+ 2alise 5Key7 * cl trangre sur la ta-le avec la$uelle on fait la 6ointure

ur la ta-le pratique. la cl trangre est code^sportif 2alise 5many,to,many7 dfinit une association en T 5,7 T

Ln fait la 6ointure sur la colonne code^discipline de pratique Ietournera des instances de la classe Jiscipline 1'attri-ut disciplines de la classe Sportif correspond donc ? l'ense!-le des disciplines trouves dans pratique avec le !5!e 112 code^sportif $ue le sportif courant

Association bidirectionnelle

<ans la classe Jiscipline. on trouvera l'association inverse. de discipline vers sportif


<ans la classe Jiscipline. attri-ut

private Set sportifs( 5set name)&sportifs& inverse="true" ta=le)&pratique&7 5Key7 5column name)&code^discipline& not,null)&true& '7 5'Key7 5many,to,many entity,name)&data.Sportif&7 5column name)&code^sportif& not,null)&true& '7 5'many,to,many7 5'set7 Ense!-le de sportifs correspondant ? la 6ointure via la ta-le pratique et la cl code^discipline 11#

<ans le !apping de la classe Jiscipline

Association bidirectionnelle

Contrainte pour un !apping d'association -idirectionnelle

<'un des deu) cots. on doit avoir un inverse ) true dans la dfinition du set (et un false. par dfaut. de l'autre+

Ici c'est dans le !apping pour la classe Jiscipline

<ans les classes. pour assurer la -idirectionnalit. on doit faire un a6out dans les deu) ense!-les des deu) l!ents

Classe Sportif

pu=lic void addJiscipline(Jiscipline disc) A this.disciplines.add(disc)( disc.getSportifs().add(this) C pu=lic void addSportif(Sportif sportif) A this.sportifs.add(sportif)( sportif.getJisciplines().add(this)( C

Classe Jiscipline

114

Association et cardinalits

Ouatre t%pe d'associations. par 6ointure en prcisant la cl trangre


Uone-to-oneW

'n vers un 'n vers plusieurs * sport vers discipline "lusieurs vers un * discipline vers sport "lusieurs vers plusieurs * entre discipline et sportif Ecessite une ta-le d'association entre les 2 ta-les 11;

Uone-to-!an%W

U!an%-to-oneW

U!an%-to-!an%W

'apping pour la classe $porti(

Ieste ? dfinir l'ense!-le (driv+ des Sports


Consiste ? rcuprer les sports des disciplines du sportif courant En O1. 6ointure sur les 4 ta-les pratique. discipline. sportif et sport. en fonction de la valeur code_&onSporti%

select distinct(sport.code^sport), sport.intitule from discipline, pratique, sportif, sport where sportif.code^sportif ) code_&onSporti% and discipline.code^discipline ) pratique.code^discipline and pratique.code^sportif ) sportif.code^sportif and sport.code^sport ) discipline.code^sport

<ifficile ? e)pri!er par un !apping Gi-ernate. on va passer par une re$u5te

Ia6oute dans la classe Sportif la !thode suivante

pu=lic Set5Sport7 getSports() A ... C

"as -esoin d'un attri-ut sports car il ne sera pas persistant

11>

7equ=te get$ports34

"re!ire (!auvaise+ i!pl!entation

'tilisation de Pava au !a)i!u!

pu=lic Set5Sport7 getSports() A Set5Sport7 sports ) ne HashSet5Sport7()( #terator it ) this.getJisciplines().iterator()( hile (it.has@e"t()) sports.add(((Jiscipline)it.ne"t()).getSport())( return sports( C "arcourt les disciplines du sportif et rcupre pour chacun le sport associ Ln place ces sports dans un et ($ui par principe ne contiendra pas de dou-lon+ Ln o-lige en effet ? charger en !!oire (de la 2<< vers le progra!!e Pava+ toutes les disciplines du sportif alors $u'on n'en a pas -esoin 11@ "ro-l!e potentiel de perfor!ance

Trs !auvaise ide T

2onne i!pl!entation

7equ=te get$ports34

"asser par une re$u5te en GO1 (Gi-ernate Ouer% 1anguage+


E$uivalente ? celle $u'on aurait faite en O1 ... !ais en plus si!ple
Set5Sport7 sports ) ne HashSet5Sport7()( '' crIation de la requMte Xuery query ) session.createXuery( &select distinct(sport) from data.Sport sport, data.Jiscipline disc&B & here disc.sport ) sport and :leSportif in elements(disc.sportifs)&)( '' le sportif est l;o=1et courant query.set/arameter(&leSportif&, this)( '' construit le set N retourner N partir de la liste rIsultat de la requMte #terator it ) query.list().iterator()( hile (it.has@e"t()) sports.add(it.ne"t())( return sports( C pu=lic Set5Sport7 getSports() A

Eote * ne pas ou-lier de grer en plus les e)ceptions

11B

Langage de requ=te />L

Ie$u5te GO1 prcdente


e lit asseJ si!ple!ent * rcuprer la liste des sports des disciplines $ui sont associes au sportif pass en para!tre 'tilisation d'un para!tre no!! pour prciser le sportif

query.set/arameter(;;nom/aram;;, valeur)( 3vec la valeur pouvant directe!ent 5tre un o-6et

Co!!e ici * c'est une instance de la classe Sportif

E)cution de la re$u5te

3ppel de list() sur l'o-6et re$u5te $ui retourne la liste des rsultats Ln peut ensuite associer un itrateur ? cette liste 3ttention T

Il e)iste une !thode iterate() appela-le directe!ent sur l'o-6et re$u5te #terator it ) query.iterate()( Cette !thode ne charge pas en !!oire les o-6ets persistants retourns par la re$u5te 'ils taient d6? chargs. Sa !arche. sinon on ne rcupre rien <onc privilgier l'usage de * #terator it ) query.list().iterate()( 11C

Langage de requ=te />L

GO1 est un langage de re$u5te aussi puissant $ue O1 et $ui est en plus orient o-6et

"er!et de !anipuler directe!ent des o-6ets (instances de "LPL+

<finir une 87varia-le79 sport correspondant ? une instance de la classe data.Sport 2 ... data.Sport sport ... Icuprer l'o-6et sport associ ? une discipline 2 ... disc.sport ...

"er!et de naviguer sur les associations entre o-6ets

M5!es fonctionnalits $ue O1. gestion du pol%!orphis!e...

3u final. les re$u5tes GO1 sont gnrale!ent (-ien+ plus si!ples $ue les re$u5tes O1 $uivalentes

Trace de la re$u5te O1 e)cute

select distinct sport?^.code^sport as code3^[^, sport?^.intitule as intitule[^ from sports.sport sport?^, sports.discipline discipline3^ where discipline3^.code^sport)sport?^.code^sport and (U in (select sportifs4^.code^sportif from pratique sportifs4^ where discipline3^.code^discipline)sportifs4^.code^discipline)) 12D <eu) re$u5tes E1ECT i!-ri$ues sur 4 ta-les

Langage de requ=te />L

i l'on sait $u'une re$u5te ne renvoie $u'un seul rsultat


"eut utiliser uniqueResult() au lieu de list() pour rcuprer le rsultat

query ) session.createXuery(&select sport from data.Sport sport here sport.codeSport ) ;4; &)( Sport sport ) (Sport)query.uniqueResult()( if (sport )) null) System.out.println(&/as de sport 4&)( else System.out.println(&>e sport 4 est 2 &Bsport.get#ntitule())(

i une re$u5te slectionne plus d'une valeur. on rcupre un ense!-le de ta-leau). un ta-leau par rsultat

query ) session.createXuery(&select sportif.nom, sportif.adresse.ville from data.Sportif sportif&)( #terator it ) query.list().iterator()( System.out.println(&@om des personnes avec leur ville&)( hile(it.has@e"t()) A $=1ectPQ res ) ($=1ectPQ)it.ne"t()( System.out.println(&nom 2 & B resP?Q B &, ville 2 & B resP3Q)( 121 C

5ycle de vie d'un ob:et persistant

Toutes les fonctions de gestion du c%cle de vie d'un o-6et se font par rapport ? une session Gi-ernate ouverte Toute !odification d'tat se fait en !ode transactionnel

Iendre persistant un o-6et. !odifier le contenu d'un o-6et persistant. suppri!er un o-6et persistant. ... ch!a gnral ? appli$uer de prfrence

En cas d'erreur (e)ception leve+ lors de la transaction. e)cuter s%st!ati$ue!ent un roll-acM pour annuler ce $ui a pu 5tre !odifi
session ) (ne Configuration().configure().=uildSession+actory()).openSession()(

(...) try A trans ) session.=egin%ransaction()( '' faire les modifications voulues (...) '' pas d;erreur, on commit trans.commit()( C catch (!"ception e) A '' pro=lLme 2 on annule tout if (trans 8) null) trans.roll=acK()( C

122

5ycle de vie d'un ob:et persistant

"lusieurs !thodes pour charger un o-6et persistant ? partir de la 2<<


E)cuter des re$u5tes GO1 co!!e on l'a vu 'tiliser des re$u5tes natives O1

SX>Xuery query ) session.createSX>Xuery(...)( Connection conn ) session.connection()(

Icuprer une conne)ion P<2C puis faire des re$u5tes O1

'tiliser l'3"I Criteria i on connait l'identifiant d'un o-6et * load() ou get()


Charger le sportif d'identifiant gal ? 2

Sportif sportif ) session.load(Sportif.class, 4)( i ne trouve pas l'o-6et (identifiant ine)istant+. load() lve une e)ception et get() renvoie null Contraire!ent ? get(), load() ne charge pas forc!ent tout de suite l'o-6et en !!oire. l'e)ception potentielle sera donc leve 12# seule!ent $uand on accdera au) donnes de l'o-6et

<iffrence entre load() et get()


5ycle de vie d'un ob:et persistant

Crer un o-6et et le rendre persistant


Instantier de !anire nor!ale un "LPL et positionner la valeur de ses attri-uts i l'on ne veut pas grer soi !5!e la cl pri!aire associ au "LPL dans la 2<<

<ans fichier de !apping. -alise 5id7, -alise 5generator7. cha!p class peut prendre diffrentes valeurs

assigned * ? la charge de celui $ui instancie l'o-6et de fi)er la cl pri!aire (valeur par dfaut si aucun gnrateur n'est prcis+ native * laisse le &2< dter!iner la cl pri!aire (valeur entire seule!ent+ selon ses fonctionnalits uuid * identifiant sous for!e de chaine. en utilisant l'adresse I" de la !achine ....

Ensuite. on rend l'o-6et persistant via l'appel de persist() ou save() sur la transaction courante

Sport sport ) ne Sport()( sport.set#ntitule(;;pMche;;)( session.persist(sport)(

124

5ycle de vie d'un ob:et persistant

Crer un o-6et et le rendre persistant (suite+

<iffrence entre persist() et save()


save() ralise i!!diate!ent la gnration de la cl !ais l'enregistre!ent ph%si$ue se fera plus tard persist() fait les deu) actions si!ultan!ent et i!!diate!ent %ransaction trans ) trans.=egin%ransaction()( Sport sport ) ne Sport(;;pMche;;)( Jiscipline disc ) ne Jiscipline(;;mouche;;, sport)( session.persist(disc)( trans.commit()( Ce code gnrera une e)ception car le sport associ ? la discipline n'a pas t rendu persistant

3ttention au) dpendances entre o-6ets crs

Il faut donc le faire e)plicite!ent Lu prciser dans les fichiers de !apping $ue la persistance se fait auto!ati$ue!ent en cascade <ans une dfinition d'association (U!an%-to-oneW. ...+ a6outer le cha!p * cascade ) ;;persist;;

12;

<tacher = rattacher un o-6et

5ycle de vie d'un ob:et persistant

Tout o-6et persistant (charg depuis la 2<<. instanti puis rendu persistant+ est attach ? la session

1'tat de l'o-6et est li avec le contenu de la 2<< tant $ue la session e)iste

<ans certains cas. on peut vouloir dtacher un o-6et


Mthodes evict() ou close() Il n'est plus associ ? la session !ais e)iste encore en 2<<

es !odifications ne sont plus rpercutes sur la 2<<

"eut ensuite rattacher l'o-6et ? la session et rpercuter ses !odifs

Mthodes merge(). locK(). update(). save$r*pdate()

uppri!er un o-6et persistant


Mthode delete() * session.delete(sport)(

1e contenu de l'o-6et est suppri! de la 2<< (!ais l'o-6et Pava e)iste tou6ours lui. il n'a 6uste plus aucun lien avec la 2<<+ <ans fichier de !apping. utiliser au -esoin des cha!ps * cascade);;delete;; et cascade);;all,delete,orphan;;

3ttention au) dpendances entre o-6ets lors de la suppression

12>

5ycle de vie d'un ob:et persistant

Modifier un o-6et persistant

Modifier son contenu via l'appel des setters et autres accs au) collections

sportif.getHdresse().setRue(;;rue !mile GuichennI;;)( sportif.getHdresse().setCode/ostal(;;\V???;;)( sportif.getHdresse().set:ille(;;/au;;)( sportif.addJiscipline(disc)(

1a dtection de la !odification et la !ise ? 6our sur la 2<< sont faites auto!ati$ue!ent par Gi-ernate

En prati$ue. la !thode flush(o=1) est appele pour faire la !ise ? 6our ph%si$ue

Iecharger le contenu d'un o-6et persistant


Mthode refresh(o=1) Il n'% a pas de raison d'appeler e)plicite!ent cette !thode vu $ue les !odifications sont trans!ises. sauf si on sait $u'un trigger a t e)cut 12@

Autres (onctionnalits de !apping

Collections

Ln a dfini des !appings correspondant ? des 6ointures retournant une collection 6ava de t%pe Set via une -alise 5set7 Ln peut dfinir d'autres t%pes de collections. correspondant au) t%pes Pava $uivalents

-ag. list. !ap. arra%. collections inde)es ...

2alise 51oin7

"er!et de !apper des donnes venant de plusieurs ta-les dans une seule classe cot Pava Mappings pour une hirarchie d'hritage Trois stratgies possi-les

Gritage

'ne ta-le uni$ue pour toutes les classes 'ne ta-le par classe logi$ue (!apping pour la classe !re A !appings pour les classes filles+ 12B 'ne ta-le par classe 87concrte79 (pas de !apping pour la classe !re+

"erfor!ance

5oncurrence 9 per(or!ances

1es perfor!ances sont principale!ent lies au charge!ent en !!oire des donnes Co!!e le graphe d'o-6ets lis est potentielle!ent grand. on essa%e de charger les o-6ets uni$ue!ent ? la de!ande

Cha!p laGy);;true;; dans les !appings des collections "ar dfaut. $uand Gi-ernate charge un o-6et. il ne charge pas ses collections associes tant $u'on % accde pas

E)e!ple avec code prcdent. et sa trace. accdant au) sports et leurs disciplines

'n pre!ier E1ECT rcupre tous les sports


"our cha$ue sport. un autre E1ECT est e)cut pour rcuprer la liste des disciplines $uand on % accde (au !o!ent du sport.getJisciplines()+

&estion de la concurrence

M5!es fonctionnalits $ue dans les &2< pour grer de !anire prcise les accs concurrents * verrous sur donnes. ... 12C 1a gestion dtaille des transactions est i!portante

'apping par annotation

Eos !appings se -asent sur des couples de fichiers

1a classe Pava (le "LPL+ et son fichier 0M1 de !apping

"eut aussi directe!ent a6outer des annotations dans la classe Pava pour prciser les !appings

9!ntity 9%a=le(name ) &sport&) 9@amedXueries(A9@amedXuery(name ) &Sport.findHll&, query ) &S!>!C% s +R$F Sport s&), 9@amedXuery(name ) &Sport.find_yCodeSport&, query ) &S!>!C% s +R$F Sport s 0H!R! s.codeSport ) 2codeSport&), 9@amedXuery(name ) &Sport.find_y#ntitule&, query ) &S!>!C% s +R$F Sport s 0H!R! s.intitule ) 2intitule&)C) pu=lic class Sport implements SerialiGa=le A private static final long serial:ersion*#J ) 3>( 9#d 9_asic(optional ) false) 9Column(name ) &code^sport&) private #nteger codeSport( 9Column(name ) &intitule&) private String intitule( 9$ne%oFany(mapped_y ) &codeSport&) private Collection5Jiscipline7 disciplines( (...)

1#D

5onclusion sur /ibernate

/ra!eForM de persistance trs puissant (on n'en a vu $u'une introduction dtaille+


Indpendance des supports ph%si$ues &estion des caractristi$ues o-6et (hritage ...+ "oliti$ues de charge!ents des o-6ets (? la de!ande ...+ 1angage de re$u5te GO1

'n O1-liMe orient o-6et 1a gestion des donnes est principale!ent du Pava natif. pas ? soucier de co!!ent sont gres et accdes les donnes

"er!et vrai!ent de se consacrer sur la logi$ue !tier

3u niveau du progra!!e en tout cas. car il faut $uand !5!e concevoir la -ase de donne et les !appings Cot Pava. on !anipule donc directe!ent les entits !tiers telles $u'on les a conSues 1#1 M5!e si on doit avoir en t5te $u'elles ont une persistance en 2<<

?ocu!entation /ibernate

ite officiel d'Gi-ernate


http*==FFF.hi-ernate.org 3vec -eaucoup de docu!entation

Traductions franSaises du !anuel de rfrence du site d'Gi-ernate


http*==FFF.dil.univ-!rs.fr=e!assat=docs=hi-ernate-#.1=reference=fr=ht!l=inde).ht!l http*==docs.6-oss.org=hi-ernate=core=#.#=reference=fr=ht!l=inde).ht!l

1ivre
87Gi-ernate #.D : &estion opti!ale de la persistance dans les applications Pava=P2EE79. 3nthon% "atricio. E%rolles
1#2

Co!-inaison de Gi-ernate. servlets. pages P " avec 'E1 et P T1 pour afficher les sportifs avec leurs disciplines et sports prati$us
"age GTM1 via un lien envoie une re$u5te ? la servlet SportServlet ervlet SportServlet.1ava (d;*R> `D'SportsDE)

&#e!ple (inal

Icupre via une re$u5te GO1 l'ense!-le des sports 36oute cet ense!-le ? la re$u5te GTT" reSue par la servlet "uis fait suivre (forFard+ la re$u5te GTT" ? la page afficherSports.1sp Icupre l'ense!-le des sports dans la re$u5te GTT" Hia 'E1 et P T1. !et en page leur affichage

"age afficherSports.1sp

1a servlet ne gnre aucun code GTM1. c'est le 1## r`le de la page P " ? $ui on a forFard la re$u5te

&#e!ple (inal

1ien dans la page GTM1

5a href)&SportsUoperation)listeSportif& target)&operation&7 Hfficher la liste des sportifs5'a7 pu=lic >ist5Sportif7 get>isteSportifs() thro s !"ception A Session session ) this.openHi=ernateSession()( Xuery query ) session.createXuery(&from data.Sportif&)( return query.list()( C protected void processRequest( ... request, ... response) A String operation ) request.get/arameter(&operation&)( if (operation.equals(&listeSportif&)) A '' rIcupLre la liste des sports et l;associe N la requMte H%%/ request.setHttri=ute(&sportifs&, get>isteSportifs())( '' for arde la requMte N la page <S/ getServletConfig().getServletConte"t().getRequestJispatcher( &'afficheSportifs.1sp&).for ard(request,response)( 1#4 C (...)

Code de SportServlet.1ava

"age P " afficheSportifs.1sp

&#e!ple (inal

UV@tagli- uriX^http*==6ava.sun.co!=6sp=6stl=core^ prefi)X^c^ VW Uh2W1iste des sportifs et de ce $u'ils fontU=h2W Uc*forEach ite!sX^fbre$uest cope.sportifsc^ varX^sp^W Uh#Wfbsp.no!cU=h#W UpWU-W3dresse * U=-Wfbsp.adresse.ruec - fbsp.adresse.code"ostalc fbsp.adresse.villecU=pW Uc*chooseW Uc*Fhen testX^fbe!pt% sp.disciplinesc^W UpWUiWEe prati$ue aucune discpline sportiveU=iWU=pW U=c*FhenW Uc*otherFiseW UpWU-W1iste des disciplines prati$ues * U=-WU=pW UulW Uc*forEach ite!sX^fbsp.disciplinesc^ varX^disc^W UliWfbdisc.intitulecU=liW U=c*forEachW U=ulW UpWU-W1iste des sports * U=-W U=pW UulW Uc*forEach ite!sX^fbsp.sportsc^ varX^sport^W UliWfbsport.intitulecU=liW U=c*forEachW U=ulW U=c*otherFiseW U=c*chooseW U=c*forEachW

1#;

&#e!ple (inal

1#>

You might also like