Sunteți pe pagina 1din 290

Introducere1

În volumul intitulat „Ghidul managerului pentru noile tehnologii informatice şi


de comunicaţie”2, elaborat de aceiaşi autori, care a apărut în editura Lucman în
noiembrie 2002, am vizat în partea a cincea doar o prezentare frugală a
tehnologiei ASP. Am acordat mai multă atenţie XML.
Aici vom avea în vedere aplicaţii elaborate cu trei tehnologii: JSP, ASP şi PHP,
deci ne vom întâlni şi cu limbajele respective.
Ideea că un sit comercial poate fi realizat doar cu ajutorul pachetului Microsoft
FrontPage este greşită din start. Un sit comercial este mult mai complex decât un sit
obişnuit. Şi el se bazează pe unul dintre limbajele de tip script, deci pentru scenarii:
Java, JavaScript, VBScript, JScript, PHP sau PERL (Practical Extraction Report
Language), PerlScript.
PHP şi PERL merg pe filozofia Common Gateway Interface. Acest CGI se bazează pe
un formular completat de vizitator dar atenţie, pentru fiecare client Web care accede un
sit elaborat cu PHP sau PERL, se încarcă în memoria serverului atât programele cât şi
câte o copie a interpretorului. Este o risipă de memorie!
ASP şi JSP au schimbat puţin filozofia CGI. Avem tot timpul să vă lămurim cum!
Stimate manager, veţi fi nevoit să citiţi această carte sau să apelaţi la un cunoscător al
unuia din aceste limbaje. Oricum, vă mai trebuie ceva bani pentru achiziţionarea unui
mediu de dezvoltare serios (vezi mai jos, medii IDE) şi pentru un pachet software pentru
administrarea bazelor de date.
Java şi VBScript sunt limbajele de bază ale tehnologiilor JSP, Java Server Pages şi
respectiv ASP, Active Server Pages.
Medii IDE pentru proiectarea siturilor comerciale
Mai oportun este ca situl comercial să se realizeze cu ajutorul unui mediu de dezvoltare
aşa-zisul IDE, Integrated Development Environment. Un astfel de mediu are

1
Cursul « Aplicaţii de comerţ electronic şi tehnologii » predat de profesorul dr. Somnea Dan, la
facultatea R.E.I. an II, din anul 2002/2003 în locul cursului de Internet.

2
Puteţi comanda la editura Lucman (tel./fax: 021-223-7755, sau comenzi@lucman.ro) un exemplar.
Editura are depozitul la adresa: Bucureşti, str. Sevastopol nr.24. Mai sunt cca- 30 exemplare. Dacă
lucrarea s-a epuizat, sunteţi trecut în lista de aşteptare. Rotativa se porneşte dacă se adună cel puţin
300 comenzi ferme. Până acum s-au scos două tiraje, unul de 250 (sept. 2002) şi al doilea de 330
exemplare (nov. 2002). Urmează ca în luna sept. 2003 să se scoată un număr de cca. 350 exemplare,
plus câte comenzi ar apare între timp. Exemplarele au fost destinate în principal formelor de
învăţământ de zi şi distanţă, pentru facultatea R.E.I. Au fost şi cumpărători izolaţi care au ... apucat
cartea, pentru că ştiau de aceşti autori de la editura tehnică, când publicau acolo.
instrumente pentru crearea unui proiect, scrierea programelor, depanarea lor (punerea la
punct) . Programele sunt componentele sitului.
Există medii care sunt orientate spre suprafeţe grafice. Iată câteva denumiri: Allaire
JRun Studio, Apache Tomcat Servlet and JavaServer Pages Development with
VisualAge for Java, Borland /Inprise JBuilder, Microsoft Visual InterDev, seria de
servere .net Microsoft Entreprise (vezi mai jos), Macromedia Dreamweaver MX etc.
Containere pentru servleturi/pagini JSP alias servere de aplicaţii Web
Ca să dezvoltaţi şi să testaţi un sit comercial trebuie şi o reţea de PC-uri pentru încercare.
Ultima condiţie este extrem de greu de simulat. De aceea s-au scris diverse simulatoare
de încercare pentru a afla cum se comportă situl la diverse trafice de încărcare şi condiţii
de reţea.
Pentru producţia de situri comerciale dinspre platforma JSP sunt containerele pentru
servleturi şi pagini JSP: Allaire JRun, Apache Tomcat, BEA Weblogic Entreprise
Server, iPlanet Web Server Entreprise Edition, Sun NetObject, IBM WebSphere
Application Server, Oracle Application Server, Inprise Application Server.
Lumea serverelor Microsoft .Net Entreprise şi Visual Studio
Dinspre platforma ASP cităm strategia materializată de Microsoft Distributed Network
Architecture, adică arhitectura unui sistem distribuit de la corporaţia cu acelaşi nume, ce
a stat la baza unei serii de zece servere plus serverul Windows 2000.
Despre aceste servere nu putem emite pretenţii de a le avea în A.S.E.! Instrumentul de
dezvoltare al acestora a fost precis mediul IDE Microsoft Visual Studio InterDev!
Sunt în total vreo zece servere. Pentru alte detalii, vezi şi Epilog şi referinţa /8/, o
documentaţie plină de fraze ditirambice, aşa cum sunt majoritatea comunicărilor şi
broşurilor celor care caută să se facă înţeleşi posibililor lor consumatori de produse
software. Pentru conformitate redăm o mostră de frază: « Microsoft Commerce Server
2000 permite afacerilor ?! din diferite domenii construirea de soluţii e-commerce
scalabile (Sic !) personalizate, care optimizează experienţa clientului şi le oferă
managerilor un timp real (hopa !!!) de analiză şi control al afacerilor online. » Spuneţi şi
dumneavoastră domnule profesor Pruteanu ce ditrambi sunt aceşti … ! Aţi înţeles
ceva stimaţi actuali şi posibil viitori manageri? Să ştiţi că nu învinuim pe traducător ci,
pe creatorii unor atari fraze cu salarii sfidătoare. Dar mai bine să ne oprim ! Şi ce este
mai grav este că cei îndrituiţi a-şi face publică « marfa », îşi bat joc de munca celor care
concep aceste produse software din interiorul corporaţiei Microsoft !
Iată deci o veritabilă dilemă pentru un potenţial administrator de sit comercial ca …
lumea! Nu este cazul să fiţi dezorientaţi!
Să revenim pe pământ !
Ca să aflaţi ceva despre efortul de realizare al unui sit comercial mai nepretenţios,
încercaţi să parcurgeţi acest manual, jumătate scris în limba română şi jumătate în limba
franceză.
În capitolele scrise în limba română ne ocupăm de tehnologiile JSP şi ASP, plecând de
la instrumente freeware fără a avea acces la pachetul Macromedia Dreamweawer MX.
Capitolele scrise în limba franceză constituie o parte din cursul predat studenţilor
economişti de către profesorul dr. Mihai Calciu la Universitatea Lille I şi, care are în
vedere tocmai acest pachet alături de aplicaţiile EasyPHP, phpMyAdmin sub Windows
şi mai ales Linux.
Afirmam mai sus ceva legat de acel soft pentru bazele de date. Fiecare din siturile
comerciale trebuie să apeleze la baze de date. Deci trebuie să aveţi în vedere ca
programatorul pe care îl angajaţi să mai ştie şi unele comenzi ale limbajului de
interogare structurat, SQL, Structured Query Language.
Dacă vreţi să recurgeţi la tehnologia PHP, deci şi la limbajul mySQL (tot SQL),
examinaţi şi referinţa /5/, dar mai ales să aruncaţi un ochi în capitolele scrise în franceză
din această carte.
Pentru partea dedicată tehnologiei ASP parcurgeţi capitolele 7-10, unde am explicat un
exemplu de sit comercial testat în stadiul preliminar şi care poate fi îmbunătăţit.
Pentru o privire asupra fiecăreia dintre tehnologiile JSP, ASP şi PHP, bazate pe
Macromedia Dreamweaver MX, citiţi şi capitolele din partea a doua. În ce ne priveşte,
în A.S.E. nu avem acces la Dreamweaver şi ne mulţumim şi cu ce avem. Şi avem unele
instrumente din platforma Windows!
Am fi avut mai multe şi pe partea de dezvoltare a aplicaţiilor de e-commerce, dacă am fi
acceptat instalarea pe staţiile din laboratoarele studenţeşti a unuia dintre dialectele Linux
în varianta WorkStation, de pildă Suse, cu o suprafaţă grafică KDE!
În partea dedicată prezentării tehnologiei JSP veţi afla că, cu modestul cadru de
dezvoltare (se foloseşte termenul kit în engleză) J2SE, Java 2.0 Standard Edition al
corporaţiei Sun MicroSystems, cu un container pentru servleturi şi pagini JSP Resin
1.1.4 sau JRun Standard 3.0, ambele cu regim de freeware, fără drept de folosire pentru
producţia de situri comerciale aducătoare de profit şi, cu un programator cunoscător al
limbajului Java, înzestrat cu multă răbdare, puteţi încropi un sit comercial. Pentru acesta
citiţi capitolele 1-6.
Între pachetele cu funcţia de container pentru servleturi şi pagini JSP cităm în primul
rând pe Jakarta Tomcat. Un serios concurent este însă JRun, al firmei Allaire în două
variante: Standard şi Studio. Ultimul este pe bani! Primul este shareware! Vezi şi mai
jos.
Tehnologia JSP a fost şi este dezvoltată cu asiduitate de corporaţia Sun Microsystems,
în timp ce tehnologia ASP este opera celor de la Microsoft.
Cadrul de lucru J2SE se poate descărca de la adresa: http://java.sun.com/products/jdk.
Mai indicat este însă să procuraţi ediţia Entreprise a aceluiaşi cadru şi anume J2EE.
Aceasta este însă distribuită sub licenţă cu prealabila perioadă de testare (shareware).
Atât J2SE cât şi J2EE nu folosesc suprafaţa grafică. Tot atunci se instalează automat şi o
bibliotecă de pachete cu clase Java, denumită JRE, Java Runtime Environment, adică
maşina virtuală Java, Java Virtual Machine (vezi capitolul 1). Există câte un JRE pentru
fiecare cadru de lucru.
Cadrele de lucru J2SE şi J2EE mai sunt denumite şi SDK 2 Standard Edition, respectiv
pentru SDK 2 Entreprise Edition.
Versiuni de motoare servlet
Recomandăm în ordine pe: Tomcat. Acesta a ajuns la versiunea 5. Merg foarte bine şi
versiunile mai vechi 3.1 sau 3.2, care au regimul de licenţă deschisă.
Există apoi aplicaţia firmei Caucho Technologies denumită Resin. Prin anul 2000 a fost
o versiune distribuită sub licenţă deschisă cu numărul 1.1.4. Pe aceasta o vom
implementa pe staţiile studenţeşti din corpul 1000, etajul 4. Pachetul este creaţia lui
Ferguson Scott. Dacă aţi vizita portalul www.Caucho.com aţi constata că versiunile mai
noi sunt pe bani cu trecere prin perioada de evaluare.
În sfârşit, compania Allaire posedă pachetul JRun (versiunile Standard şi Studio).
Regimul de open source nu are decât versiunea 3.0 standard. Intraţi şi la:
http://www.allaire.com ca să vă convingeţi că totul este acum shareware deci pe bani!
Pentru a crea cu trudă un sit în ASP, recurgem la Microsoft FrontPage, MS Access,
editorul wordpad şi cam atât!
Ar fi fost mai bun Microsoft Visual InterDev. Nu emitem pretenţii la Microsoft SQL
Server în loc de MS Access.
Acasă aveţi de regulă Windows 98. Sub acesta există Microsoft Personal Web Server,
versiunea a patra. Sub Windows 2000 Workstation Professional, dacă îl aveţi, se recurge
la Microsoft Information Internet Server 5.0. IIS a apărut pe vremea sistemului
Windows NT/4 varianta Server. IIS nu este acceptat şi de Windows NT/4 Workstation!
Din păcate toate acestea nu suportă servleturi Java, decât dacă cumpăraţi de la firmă
adausurile de rigoare! Folosesc însă cu dezinvoltură limbajul VBScript şi obiectele
ActiveX Data, ADO. ActiveX este dezvoltat după modelul obiectelor din componente,
COM, Component Object Model. Acest ActiveX căruia în „romgleză” i se spune
„controale ActiveX” este accesibil atât pe partea client (deci MSIE, nu şi Netscape) cât
şi pe partea de server.
Insistăm! Sub browserul Netscape obiectele ActiveX sunt ignorate!
Înainte de a trece mai departe, Windows 98 etc. permit instalarea motorului Caucho
Resin 1.1.4.
Dar ce oferă alţii în materie de motoare servlet?
Începem cu AOL / Netscape. Până de curând a tronat Netscape Java Web Server ca
server Web. El a fost înlocuit însă de către mai noul iPlanet Web Server Entreprise
Edition. Acesta a înlocuit şi un alt server Web de la Netscape, denumit Netscape
Entreprise Server.
Există piese software şi pentru platforme Unix, AIX/Linux. Despre aceste platforme
vezi referinţa /2/. Sub Linux tronează Tomcat.
Pro XML!
Toate browserele se „feresc să rămână în urmă” şi încearcă să se alinieze la standardul şi
limbajul XML şi la standardele XSL, XLST, Xpath etc. în mod tot mai hotârît. Conduc
detaşat doar editorul/browserul Mozilla de la NCSA şi total necunoscutul editor/browser
InDelv de la www.indelv.com. Sunt singurele care se descurcă în XSLT, adică XLS
Transformations.
Nici nu îndrăznim a vă indica să procuraţi şi răsfoi o altă referinţă de peste 800 pagini,
cu fraze întortocheate, chiar din limba în care a fost concepută, engleză. Este totuşi o
muncă meritorie şi enormă depusă de către doamna sau domnişoara Lee Anne Phillips,
un exeget în materie de documentare asupra standardelor XML / XHTML. Este vorba
de: XML, XPath, XLink, Xpointer, de limbajele de stil, precum: CSS1, CSS2, DSSSL,
XSL, XSLT. Cartea s-a numit în original „Special Edition Using XML” şi a fost tradusă
la editura Teora sub denumirea de XML. A apărut la editura americană QUE, în anul
2000 iar la noi, un an mai târziu. Bravii noştri traducători nu au descâlcit şi unele fraze
prea lungi din lucrarea originală! What a pitty!
Am presupus poate greşit că aţi răsfoit referinţa /1/, pag. 208-233. Aţi fi aflat destule
despre folosirea intensă a limbajului XML în schimburile electronice de documente
finanicar-contabile dintre verigile implicate în tranzacţii din siturile: B2B, B2C, C2C.
Vezi totuşi şi partea a doua din limba franceză.
Pentru ai fi independenţi întrucâtva de referinţa /1/ am alcătuit anexa A. Aici tratăm
HTML, DHTML şi o scurtă iniţiere în XHTML, ca să depăşim această referinţă. În
IT&C intervalul de timp ideal pentru actualizarea documentaţiilor este semestrul! Anul
este … prea lung!
Să pornim la drum într-o manieră cât de cât metodică.

Convenţiile de scriere
Textul obişnuit este cules cu acest set de caractere (font). Listele de programe sunt
culese cu acest corp de literă:
<html>
<head><title>Razboiul din Irak!</title>

când nu sunt numerotate sau aşa:


01. <html>
02. <head><title>Razboiul din Irak!</title>

când sunt numerotate.


Procedeele de operare sunt anunţate prin pictograma alăturată.
Observaţiile importante sunt anunţate prin pictograma alăturată
1
Capitolul

Universul termenilor platformei


Java
Vom explica pe înţelesul dumneavoastră o serie de termeni din universul Java.
Au trecut destul de mulţi ani de când acest limbaj concurează cu deosebit succes
familia de limbaje C/C++. Java este adulat şi de către IBM et. Co, în ciuda
efortului venerabilei corporaţii Microsof. Din cauza proliferării unui număr
imens de pachete de clase şi componente, se poate spune că Java îşi trăieşte a
doua tinereţe, acum în perioada programării orientate spre componente.

Client Web şi server Web

A şadar să intrăm în universul termenilor platformei Java!


Să adâncim faţă de referinţa /1/ două noţiuni şi anume, cea de client Web şi cea
de server Web. Două calculatoare comandate fiecare de câte un program,
comunică între ele. Unul dintre programe serveşte la răsfoirea spaţiului Web. I se mai
spune program de vizitare, de navigare. Cine nu a folosit Microsoft Internet Explorer
(MSIE)! Acestuia să îi spunem client Web sau browser.
Pe celălalt calculator, gazdă a sitului vizitat, se află un alt program denumit server Web.
El este specializat în executarea programelor scrise într-unul din limbajele pentru
scenarii.
Să complicăm puţin lucrurile! Există şi un server Web dar poate exista şi un aşa-zis
server de aplicaţii Web. I-am spus mai sus motor servlet.
Deşi tratăm tehnologia JSP, admiteţi o paranteză! În tehnologia ASP, serverul MS IIS
este şi gazda aplicaţiilor. Acest IIS „interpretează” pe loc instrucţiunile programelor cu
extensia .asp, componente ale unei aplicaţii şi generează dinamic un document tip html
care ajunge la PC-ul gazdă a browserului MSIE. Terminat paranteza!
Aici este vorba însă de tehnologia JavaServer Pages. Serverul de aplicaţie poate prelua
şi sarcina serverului Web clasic, pe lângă aceea de container pentru servleturi. Mai poate
să se întâmple însă şi aşa: să trimită serverului Web clasic servleturile ca să le
gestioneze, adică să le pună la dispoziţia cererilor clienţilor Web. Oricum, serverul de
aplicaţii are în această a doua ipostază doar funcţia producător de servleturi.
Protocolul http şi dialogul dintre client Web – server Web. Lanţul …
slăbiciunilor !
Spuneam mai sus că serverul Web dialoghează cu clientul Web pe baza unui protocol.
Cel mai adesea acesta este http. Acesta nu este legat de servleturi. Vizitatorul vede pe
ecranul PC-ului gazdă a browserului MSIE un formular. Cum credeţi că a apărut el aici?
A fost generat de către programul servlet. Vizitatorul completează datele în rubricile
formularului. Ele pleacă la server, când s-a recurs la butonul pentru trimitere. Datorită
unui alt program dinainte proiectat şi anunţat în servlet, ce este asociat acestui formular,
se analizează aceste date şi se construieşte răspunsul. El este expediat înapoi la clientul
Web tot sub forma unui document generat în HTML.
Acest schimb de replici client – server respectă oricum protocolul http deci formatul
HyperText Transport Protocol, care nu ne interesează pe noi nespecialiştii IT!
În lumea browserelor şi … din nou obsesia XML!
Apropo, pe lângă programul de navigare (sau vizitare) browser MSIE, se folosesc cu
aplomb şi altele cum sunt: Netscape Navigator sau Communicator. Poate aţi auzit şi de
NCSA Mozilla sau venerabilul NCSA Mosaic. Ultimul este opera celor de la Centrul
pentru Arhitecturi de Supercomputere al Universităţii Minnesota, Illinois. La NCSA,
(National Center for Supercomputing Architecture) cu un deceniu în urmă, Mark
Andersen a conceput şi elaborat Mosaic. Era primul browser grafic. Mai înainte Tim
Berners Lee a conceput Viola, un browser de tip text orinetat spre emultaor de terminal
VT-xxx. Studenţii din anii terminali, urmaşii lui Mark, dezvoltă cu dezinvoltură în
referatele lor, nucleul unei noi versiuni de browser denumit Mozilla. Este aliniat la
standardul XML 1.0! Cunoaşte şi interpretează corect structurile acestui limbaj extins
pentru marcaje, eXtensible Markup Language şi chiar şi şabloanele limbajului de stiluri,
XSL, eXtensible StyleSheet Language.

Ce este XSL?
Să zicem că am descris în XML (vezi şi: /1, 2, 9, 16/) un articol de revistă şi descrierea
arată astfel:
LISTA 1.1 Aspectul documentului de intrare (scris în XML)

01. <?xml version=”1.0”>


02. <article fname=”19990101_xsl”>
03. <title>XML Style Sheets</title>
04. <date>January 1999</date>
05. <copyright>1999, Benoit Marchal</copyright>
06. <abstract>Style sheets add flexibility to document viewing.</abstract>
07. <keywords>XML, SXL … </keywords>
08. <section>
09. <title>Styling</title>
10. <section>
11. <p>Style sheets are inherited form SGML, an XML ancestor. Style sheets
originated in publishing and document management applications. XSL is XML’s
standard style sheet, see <url>http://www.w3.org/Style</url>.</p>
12. </section>
13. <section>
14. <title>How XSL Works</title>
15. <p>An XSL style sheet is a set of rules where each rule specifies how to format
certain elements in the document. It has rules for title, paragraphs and
keywords.</p>
16. <p>With XSL, these are powerful enough not only to format the document but
also to reorganize it, e.g. by moving the title to the front of page or extracting
the list of keywords. This can lead to exciting applications of XSL outside the
realm of traditional publishing. ...</p>
17. </section>
18. <section>
19. …
20. </section>
21. </article>

Am reprodus o parte din exemplul clasic al lui Benoit Marchal (referinţa /9/) care l-a
pasionat tocmai acest XSL şi XSLT mai mult decât XML în sine. Observaţi o serie de
balize inventate pentru descrierea componenţei unui articol. E vorba de titlul articolului
(liniile 02 şi 03), de data apariţiei sale (linia 04) etc. Mai jos vedem baliza abstract care
înfăşoară conţinutul (liniile 06 şi 21), de o serie de titluri de secţiuni şi de secţiunile în
sine. În fine intrăm şi pe teritoriul oarecum al HTML, unde apar balize pentru paragrafe,
deci pentru frazele textului.
Acum să presupunem că dispunem de un procesor XT, cum este cel al lui James Clark,
vezi /14/, care citeşte la intrare documentul de mai sus de tip XML. Procesorul are un
transformator XSL, deci un XSLT. Acesta foloseşte un limbaj cu instrucţiuni în toată
regula! Iată pentru cazul nostru acest transformator de aspect de document:
LISTA 1.2 Instrucţiunile de transformare (scrise în limbaj XSLT)

01. <?xml version=”1.0” encoding=”ISO-8859-1”?>


02. <xsl:stylesheet xmlns=”http://www.w3.org/1999/XSL/Transform”
xmlns=”http://www.w3.org/TR/REC-html4.0”>
03. <xsl:output method=”html”/>
04. <xsl:template match=”/”>
05. <HTML>
06. <HEAD>
07. <TITLE>About Style Sheets</TITLE>
08. </HEAD>
09. <BODY>
10. <xsl:apply-templates/>
11. </BODY>
12. </HTML>
13. </xsl:template>
14. <xsl:template match=”section/title”>
15. <P><I><xsl:apply-templates/></I></P>
16. </xsl:template>
17. <xsl:template match=”article/title”>
18. <P><B><xsl:apply-templates/></B></P>
19. </xsl:template>
20. <xsl:template match=”url”>
21. <A TARGET=”_blank”>
22. <xsl:attribute name=”HREF”>
23. <xsl:apply-templates/>
24. </xsl:attribute>
25. <xsl:apply-templates/>
26. </A>
27. </xsl:template>
28. <xsl:attribute name= ”HREF”>mailto :<xsl :apply-templates/>
29. </xsl:attribute>
30. <xsl:apply-templates/>
31. </A>
32. </xsl:template>
33. <xsl:template match=”p”>
34. <P><xsl:apply-templates/></P>
35. </xsl:template>
36. <xsl:template match=”abstract | date | keywords | copyright”/>
37. </xsl:stylesheet>

Pe scurt ce se realizează mai sus! A fost scris conform regulilor limbajului XSLT un
grupaj de instrucţiuni de comandare a procesorului XSLT. Priviţi documentul iniţial.
Acolo am întâlnit categoriile sintactice: article/title adică titlu de articol, date, copyright,
abstract, keywords, article/section, url şi href. Pentru fiecare în lista de mai sus stă scris
ce să se genereze în XHTML când se întâlneşte o atare categorie sintactică.
Pe baza acestor reguli de producţie, transformatorul a generat la ieşire un document cu
structura XHTML (vezi şi anexa A). Mai mult nu detaliem.
Iată acest document XHTML:
LISTA 1.3 Documentul rezultat la ieşirescris în limbaj XHTML)

01. <!DOCTYPE html PUBLIC –


02. <HTML><HEAD><TITLE>About Style Sheet</TITLE></HEAD>
03. <BODY>
04. <P><B>XML Style Sheets</B></P>
05. <P><I>Styling</I></P>
06. <P>Style sheets are inherited form SGML, an XML ancestor. Style sheets
originated in publishing and document management applications. XSL is XML’s
standard style sheet, see <A TARGET=”_blank”
href=”>http://www.w3.org/Style”>http://www.w3.org/Style</A>.
07. <P><I>How XSL Works</I></P>
08. <P>An XSL style sheet is a set of rules where each rule specifies how to format
certain elements in the document. It has rules for tile, paragraphs and
keywords.</P>
09. <P>With XSL, these are powerful enough not only to format the document but
also to reorganize it, e.g. by moving the title to the front of page or extracting
the list of keywords. This can lead to exciting applications of XSL outside the
realm of traditional publishing. ...</P>
10. …
11. </BODY>
12. </HTML>
Dacă priviţi cu atenţie lista 1.2, toate balizele sunt scrise cu litere mari! Cum arăta la
intrare documentul XML (lista 1.1) şi cum arată acum, după transformare (lista 1.3).
Toate browserele MSIE 5.x, nu cunosc versiunea 1.0 XML ci, una din versiunile
anterioare: 0.91 şi 0.92 care impuneau şi respectarea unor alinieri canonice la marginea
stângă, faţă de versiunea 1.0!
Ca să nu rămânem datori la întrebarea „Ce este XML?” vă spunem pe scurt că este un
fel de limbaj pentru marcaje, în care însă inventăm propriile balize (tags). Stricteţea
sintactică vă va stresa. Orcie scrieţi, trebuie verificat sintactic cu un document ... pe post
de veritabil ... grămătici, acel DTD adică definiţia tipului de document, Document Type
Definition!
În fişierul XML spuneţi care document va fi verificatorul şi aici începe chinul, dacă
scrieţi dumneavoastră în XML. Noroc că sunt generatoare automate de documente
XML (vezi : /13/) ca şi convertoare de structuri XML – XHTML(vezi : /14/).
XML este limbajul în care comunică curent verigile implicate în lanţul unei tranzacţii de
comerţ electronic (vezi şi /3/).
Protagoniştii lanţului unei tranzacţii de comerţ electronic.
Primul este cumpărătorul secolului XXI, posesorul unei cartelele de credit. Îi spunem în
engleză consumer. Este vorba apoi de banca care a emis acest „card”, denumită în
engleză issuer, apoi de banca verificatoare, acquirer, de banca creditoare a reţelei de
depozite, merchant bank şi în sfârşit, de angrosistul sistemului de depozite denumit în
engleză, merchant. Toate documentele financiar-bancare circulă între aceste verigi graţie
mijloacelor de comunicaţie şi calculatoarelor cuplate la aceasta, înzestrate cu programe
adecvate. Programele instalate la diversele sedii ale acestor verigi „vorbesc“ în XML,
deci înfăşoară (balizează spun snobii XML) datele documentelor fianciar-contabile în
… haina pretenţiosului XML. « Etapa » XML a reprezentat transpunerea „birocraţiei
unificate” EDIFACT a ţărilor din defuncta Piaţă Comună. EDIFACT înseamnă
Exchange Data Interface for Administration, Commerce, and Transport. Evident, se
respectă într-un mod riguros rigida sa sintaxă.

Modelul master slave cu trei straturi


Să insistăm puţin asupra comunicării dintre programele client şi server. În jargon i se
spune model cu două, trei sau n starturi, 2-tier, 3-tier, respectiv n-tier master-slave. Să ne
oprim la modelul 3-tier: stratul client, client tier, stratul intermediar, middle tier şi în
sfârşit, stratul final, data tier, unde se află fişierele bazei de date.
La nivelul client, programul de vizitare trimite cererea (adică datele completate în
rubricile formularului) la serverul Web. Acesta are acum rol de strat intermediar. El nu
poate interoga direct baza de date. Poate aţi solicitat ca să vi se furnizeze sortimentele de
articole vândute de depozitele acelui sit comercial vizitat. Atunci se adresează unui
server specializat de baze de date.
Lumea bazelor de date
Bazele de date sunt deservite de alte sisteme specializate precum: Oracle, IBM DB2,
Ingres, Informix, mySQL, PostGRES, etc.
Serverul intermediar nu traduce el cererea într-un limbaj ştiut serverul specializat în
căutări de informaţie prin bazele de date. Este instruit prin program (servlet în jargon
JSP). Întrebarea ajunge la stratul data tier. Aici se alcătuieşte un răspuns. I se spune tabel
cu rezultatele găsite.
Revenim la servlet. Acesta primeşte tabelul rezultat şi construieşte un alt tabel cu balize
HTML după care, cu ajutorul serverului Web, îl trimite mai departe clientului Web. Pe
ecranul staţiei gazdă a browserului se redă acest document şi vizitatorul află ceea ce a
solicitat. În fine acum vă e clar!
Applet, servlet, container
În tehnologia JSP, limbajul folosit este Java vezi figura 1.1. Fluxul de caractere
(răspunsul) ajunge la client, unde este interpretat de către MSIE. Datorită unei piese
software de care nu am vorbit, browserul MSIE interpretează şi aşa-zisele miniaplicaţii
Java, applets.
În dreptunghiul startului intermediar observaţi două subnivele, unul pentru prezentare şi
altul pentru accesul la bazele de date. Este nivelul denumit EJB, Entreprise Java Bean.
Aici se află un servlet construit cu un veritabil arsenal de mijloace EJB!

FIGURA 1.1 Cele trei niveluri ale modelului 3-tier master-slave


(reproducere din manualul devapp.pdf al Allaire JRun, varianta standard)

Cum am spus mai sus termenul applet, un diminutiv de la application, este tradus lejer
prin miniaplicaţie. Aveţi unul mai bun? Până găsiţi dumneavoastră o traducere mai bună
să vă spunem ce este!
Este un program scris iniţial în limbajul Java, care a fost compilat, deci tradus, din forma
sursă într-o formă intermediară, cea de cod de octeţi (bytecode). Acest cod este
interpretat pe PC-ul care găzduieşte clientul Web. O condiţie însă! Pe acest PC trebuie
să fi fost instalat în prealabil un component software, alături de browserul MSIE. Este
aşa numita „maşină virtuală Java”.
Servlet este tot o miniaplicaţie rulată la server. I se mai spune şi miniaplicaţie server.
Termenul are două sensuri.
Primul se referă la o întreagă activitate desfăşurată în spatele serverului Web şi aţi aflat
mai sus care este aceasta.
Al doilea sens, este acesta: dacă aplicaţia este complexă (deci cuprinde clasele tip
Entreprise Java Bean), ea va include programe care conversează optim cu bazele de
date.
Noi nu ne-am permis în acest manual să ajungem până la nivelul cadrului de lucru
J2EE, oprindu-ne la J2SE. Motivul ? Un software cu regim shareware nu are ce căuta la
un laborator studenţesc.
Component, pachet, clasă, metodă, et. Co.
Un component este o parte a aplicaţiei. Pe de altă parte, în diversele locuri ale
componentului se apelează la metodele şi clasele unor pachete. Pachetul nu este o
subdiviziune a componentului! Un pachet are mai multe clase gata dezvoltate.
Dacă aplicaţia sitului comercial nu conţine clase simandicoase „tip EJB”, ne mulţumim
cu clasele cadrului de lucru J2SE. Containerul care o execută nu este container EJB ci
unul simplu ! Dacă am avut fericita ocazie de a dezvolta aplicaţii de e-commerce
pornind de la J2EE, avem ocazia de a ne întâlni şi cu containerul EJB!
În 1999, firma BEA Systems a oferit aplicaţia Weblogic pe CD-ul care a însoţit referinţa
/4/, pentru o perioadă limitată de timp ancorată absolut la acea perioadă calendaristică.
Era o demonstraţie a unei aplicaţii de tip EJB. Acum ea este neoperaţională din motivul
arătat mai devreme!
Tot pe acelaşi CD sunt însă trei motoare servlet open source: Caucho 1.1.4, Allaire Jrun
3.0 Standard şi Tomcat 3.0. Ele pot fi folosite în compania fişierelor cadrului JDK2
varianta SE şi este totuşi ceva decât nimic!
JDK este un instrument pentru dezvoltarea de programe scrise în limbajul Java. Maniera
de lucru este primitivă! Instrumentele sale din care este alcătuit acest cadru nu sunt
pregătite pentru suprafeţe grafice de lucru. Programatorul care le foloseşte trebuie să
memoreze tot felul de comenzi lungi şi greoaie. Este un adevărat chin pentru cel căruia
i-aţi trasa sarcina construirii sitului comercial!
Veţi remarca la partea scrisă în limba franceză, recomandarea justă de folosire a
aplicaţiei Macromedia Dreamweaver MX, ca substitut al acestei primitive abordări.
Între altele acest Dreamweaver ştie Java, VBScript, VBasic şi PHP!
Diferenţa dintre servlet, scriptlet şi pagina JSP
Un program scris în limbajul Java este un fişier de tip text cu extensia .java.
Pagina JSP este tot un program scris conform regulilor sintactice ale limbajului JSP. Şi
ea este tot un fişier de tip text dar are extensia .jsp.
În lipsa unui mediu de dezvoltare (Dreamweaver nu este un mediu de dezvoltare în
adevăratul sens al cuvântului) recurgem la editorul Wordpad. În corpul paginii JSP se
pot întâlni şi instrucţiuni Java. Sunt aşa-zisele scenarii, scriptlets. Comenzile din
limbajul JSP împreună porţiuni de cod Java pur din aceşte scenarii sunt transformate de
către motorul servlet (Tomcat, Caucho, JRun etc.) în fişiere cu extensia .java. Deci
motorul este un … programator automat, care va genera cod sursă Java. Tot acesta
comandă compilarea în cod de octeţi, deci vă scuteşte de a memora complicatele
comenzi ale cadrului JDK2!

Maşina virtuală Java


Maşina virtuală Java (în engleză Java Virtual Machine JVM) reprezintă marea revoluţie
a platformei Java Sun Microsystems. A ajuns până în cuptoarele cu microunde, celulare,
PDA-uri. Este într-un cuvânt cheia portabilităţii platformei! Această „JVM” a fost scrisă
într-un limbaj tradiţional, de regulă C. JVM este în fond un program şi nu un dispozitiv
hardware. Este un fel de mediu de execuţie. Pentru fiecare platformă hard/soft există
câte o … maşină JVM. Este implantată într-o memorie flash a unui terminal portabil. La
PC-ul staţionar sau la laptop, notebook, nu este nevoie de memorie flash! Rostul său
este să … „ronţăie” codul de octeţi de care vorbeam mai sus.
Gazda maşinii JVM poate fi un:
• PC al platformei IBM (bazată pe Pentium IV, III, II) ;
• Laptop cu microprocesor Pentium IV, III Mobile sau Pentium II MMX ;
• PDA Palm, Compaq sau HP, cu microprocesor de tipul Motorola sau ;
• Apple model iBook, IMac, cu microprocesor PowerPC.
Pentru fiecare există câte o maşină virtuală Java!
Notaţi că sunt destule sisteme de operare. Amintim:
• Familia Windows, 95, 98, Me, NT/4, 2000, 2002;
• Linux cu cele vreo şapte dialecte ale sale: Caldera, Red Hat, Debian, SuSE,
Mandrake, Turbo, Slackware;
• În lumea celularelor: GeOS, Palm OS, Windows CE, actualul Pocket PC;
• Pentru platforma Macintosh: Apple OS şi MacOS;
• Pentru staţii Sun, Solaris,
• Pentru mainframes IBM ES 9000, multe sisteme de operare pe care nu le mai
enumerăm ;
• Pentru megaminicalulatoare IBM AS/400 la fel ;
• Pentru arhitecturi IBM RISC/6000, AIX-ul, Unix-ul corporaţiei IBM ;
• Pentru defuncta corporaţie DEC cu ale sale miniuri PDP-11, megamini-uri
VAX 780, Ultrix, etc.
Citiţi părţile a doua şi a treia a referinţei /1/. Lumea nu stă pe loc.
Atât codul sursă cât şi codul de octeţi sunt coduri absolut independente de platformă.
Maşina virtuală este dependentă de idiosincraziile sistemului de operare ca şi de
arhitectura hardware! Cei mai mari realizatori de maşini virtuale Java sunt corporaţiile
Sun Microsystems şi IBM. Ei îşi oferă gratis maşinile JVM!
În platforma IBM PC, unul din fişierele cadrului JDK „instanţiază” maşina virtuală
Java. Nu ne interesează care este acea componentă a JDK. Cum o instanţiază? JVM „se
trezeşte” în clipa în care îi daţi să execute un applet sau un servlet.
Dar oare nu este mai lent să se interpeteze un cod de octeţi decât să se ruleze un cod
maşină nativ! Aşa este, dar nu uitaţi că dispunem azi de microprocesoare teribil de
puternice şi mai sunt şi atâţia bolnavi mintali amatori de creare de viruşi informatici!

Applet şi servlet
Atât appletul cât şi servletul sunt programme, adică aplicaţii. Sunt stocate în fişiere cu
extensia .class. Nu mai sunt de tip text ci binar! Appletul este interpretat la PC-ul gazdă
de către browser (MSIE etc.) graţie faptului că acest browser colaborează cu maşina
JVM. Servletul rezidă la calculatorul gazdă a serverului Web. Şi aici se află o maşină
JVM.

Clase Java beans


Clasa, instanţierea, constructorul, obiectul
Clasa este un tipar, aşa cum foloseşte croitorul ! Dar este mai mult de atâta! În ea s-au
înmagazinat datele, parametrii dar şi inteligenţă! Inteligenţa este găzduită de metodele,
algoritmele dacă vreţi, care operează cu aceste date şi parametri trimişi din exterior prin
interfaţa clasei.
Şablonul clasei „naşte“ obiectul clasei. A instanţia spun programatorii şi înţeleg ce am
afirmat adineaori.
La instanţiere, fiecare clasă recurge la un aşa-zis „constructor”. Este tot un program. El
produce obiectul. Asimilaţi rezultatul constructorului cu imaginea memorată, după
folosirea declanşatorului aparatului foto!
Ce vor să însemne aceste clase tip „Java Beans”. Mai întâi etimologia cuvântului: Bean
îl traducem prin păstaie (de fasole sau mazăre dar este prea grotesc). Băutării înrăiţi de
cafea ce lucrează la sediul general al corporaţiei Sun Microsystems au adoptat
denumirea Bean, fiindcă tot începuseră cu Java. Java este denumirea cafenelei unde se
prepară la nisip cafeaua. Probabil că nu e a unui român! Dacă era, i-ar fi spus Ada-
Kaleh-ul iar corporaţia poate l-ar fi … adoptat în loc de Java!
Clasele Beans sunt tot clase Java care respectă un tipic de programare (vezi
capitolul 6).
Program, subprogram
Ca să explicăm afirmaţia de mai sus, să folosim jargonul generaţiei a treia de limbaje de
programare. Fie două programe P1 şi P2. P1 cheamă P2 de multe ori. Spunem că P2
este o subrutină, o funcţie, un subprogram. La generaţia a patra, deci aceea a limbajelor
orientate spre obiecte, i se spune metodă. P1 trimite date lui P2. Nu intrăm în detalii
cum! În jargon spunem acestor date, parametri reali, argumente reale. P2 aplică
algoritmul, adică „îşi face numărul său” şi prelucrează aceste valori, şi întoarce
rezultatele. Că le transmite sau nu lui P1 şi cum le transmite, aceasta este mai puţin
important. Algoritmul este conceput şi scris dinainte. El trebuie să se refere la aceste
date prin adrese de memorie. Adresele nu sunt cele din spaţiul programului P1 ci sunt
zone de memorie interne lui P2. Sunt deci locuri din memorie, cărora li s-au asociat în
mod convenţional denumiri simbolice dacă vreţi. Aceste locuri le numim argumente
fictive, parametri fictivi. Aici se aduc valorile parametrilor reali.

Ce conţine o aplicaţie complexă de sit


comercial
În figura de mai jos, reproducere din manualul de firmă al pachetului Allaire JRun
varianta Standard, se disting două categorii de componente.
Primele sunt aplicaţiile care conţin obişnuitele pagini JSP şi servlet-uri. Motorul servlet
JRun mai are destule alte fişiere şablon (template). Evident, există şi alte componente
dar din motive didactice nu mai le enumerăm. Şi aşa nu ne ocupăm aici de biblioteci
taglib şi de şabloane.
A doua categorie este constituită din aşa-zisele clase tip Entreprise Java beans, EJB.
Sunt tot fişiere. Li se spun şi biblioteci de clase EJB. Accesul se efectuează prin
intermediul unei interfeţe adecvate EJB. Aceasta, la rându-i, este alcătuită dintr-o suită
de fişiere parametru, care conţin valorile unei proprietăţi (consideraţi-le un fel de
parametri fictivi).
Faptul că sunt mai multe aplicaţii Web, nu trebuie să constituie o nelămurire! Un motor
servlet JRun (dar şi alte tipuri de motoare servlet) este în stare să se ocupe simultan de
mai multe situri comerciale.
FIGURA 1.2 Osatura unor aplicaţii complexe de tipul sitului comercial
(reproducere din manualul devapp.pdf al Allaire JRun, varianta standard)

Relaţia dintre serverul Web şi motorul servlet


Până acum nu a apărut poate prea clar această nuanţă. Caucho Resin este un motor
servlet ca de altfel şi Allaire JRun.
JRun poate să funcţioneze ca server propriu Web clasic şi, în acelaşi timp pe post de
container pentru servleturi şi pagini JSP, deci de server de aplicaţie.
De asemeni, admite ca treaba serverului Web clasic să nu o mai facă el ci un server Web
extern. Deci comunică cu unul dintre serverele Web clasice.
Tomcat este mai comod decât Jrun ! Nu se oboseşte ci, recurge la serviciile serverului
clasic extern Apache Web Server.
În figura de mai jos se văd care servere Web clasice pot fi folosite de către motorul
servlet JRun. Este vorba de: Personal Web Server (PWS, Windows 95/98), Information
Internet Server (IIS, Windows 2000, 2002), Netscape Entreprise Server (NES) sau, în
sfârşit de Apache. Mai observaţi acele dreptunghiuri mici denumite conector, connector.
Ei bine conectorul este un program specializat (i se mai spune în engleză şi driver). Nu
divagăm!
Serverul propriu Web al aplicaţiei JRun apare pe figură sub numele de JRun Web
Server. Aceasta pe de o parte. Pe de altă parte, remarcaţi că pe acelaşi PC pot funcţiona
mai multe motoare servlet JRun.
Ele sunt procese (tasks, vezi mai jos). Unul „dialoghează” datorită rulării aplicaţiilor de
comerţ electronic cu Apache, NES şi cu IIS, iar celălalt, cu serverele Web Apache şi
JRun.
FIGURA 1.3 Relaţia dintre diversele categorii de servere implicate
(reproducere din manualul devapp.pdf al Allaire JRun, varianta standard)

Deci :
Există pe de o parte un container pentru servleturi şi pagini JSP, căruia îi spun unii
pe scurt server JRun şi prodcu confuzie. Mai bine spuneţi-i server de aplicaţii
Web.
Există un alt server denumit server Web care se ocupă de prelucrarea cererilor de la
PC-uri ce găzduiesc clienţi Web şi administrează uneori şi servleturile.
Conţinutul unui răspuns al serverului este fie o pagină statică, fie una dinamică.
Pagina statică este un fişier cu extensia .html, adicp un docmuent anost de tip
HTML. Poate avea una sau mai multe appleturi sau nici un applet.
Pagina dinamică este ceva generat. Este un fişier cu una dintre extensiile .jsp, .asp,
.php etc. Când se solicită această pagină, are loc mai întâi o prelucrare la server.
Rezultă mai întâi un flux de caractere HTML care, odată ajuns la PC, este redat pe
ecran.

Arhive de fişiere ale unui sit comercial


Fişierele care au extensia .jar sunt de fapt arhive. Ştiţi poate de zip, arj sau rar. Sunt
arhive construite cu winzip, arj sau winrar!
Şi în cadrul de lucru JDK există un program pentru crearea şi administrarea arhivei de
fişiere, cum poate folosiţi cu dezinvoltură pe WinZip sau WinRAR.
Apropo, WinZip ştie structura tip JAR. Nu am informaţii dacă şi aplicaţia WinRAR a
aflat de această structură! Un sit comercial are fişiere care au diverse extensii.
Ce tipuri de documente pot intra într-o arhivă:
• Fişierele cu pagini statice de casă.
• Fişiere cu extensia .java (servlet-uri java).
• Fişiere executabile .class.
• Documente care descriu structura aplicaţiei sitului comercial, după rigoarea
limbajului XML. Acestea au extensia .xml.
• Şi alte tipuri dar preferăm pentru motive didactice a le ignora.
Toată această colecţie de fişiere alcătuiesc o anume ierarhie de directoare. Fiecare firmă
realizatoare de motor servlet a căutat să îşi impună propria structură de desfăşurare. Va
fi acceptat până la urmă tipicul structurii grupului Jakarta. Veţi observa uneori în acest
manual două tipuri de ierarhii, pe de o parte aceea proprie firmei Allaire şi pe de alta,
aceea a firmei Caucho.
Ei bine, aceste fişiere sunt comprimate şi arhivate cu un utilitar denumit jar, ce se află în
J2EE şi J2SE. JAR înseamnă Java ARchive.
Development phase, Deployment phase
Desigur de la maşina pe care s-a conceput situl până la maşina ţintă, deci gazdă a sitului,
aplicaţia este transportată în mod comprimat. Faza de punere la punct se numeşte în
engleză development. Componentele aplicaţiei sunt înglobate într-o arhivă. Aici se
conservă întreaga ierarhie. Aceasta trebuie în prealabil desfăşurată (în engleză,
deployment). Rezultă ierarhia de directoare cu fişierele sitului.
Desfăşurarea trebuie efectuată mai înainte de momentul lansării în exploatare a sitului.
Cei de la Allaire au voit ca extensia să se cheme WAR şi nu JAR, adică Web Archive.
De fapt un fişier cu extensia .war este o structură de date .jar. (J de la Java).
Fake-root directory
Nu este cazul să intrăm în amănunte tehnice de genul unde este directorul de implantare
tip rădăcină deplasabilă, fake-root, ce se poate planta în undeva în ierarhia generală a
sistemului de operare. Fiecare motor servlet are propriul său … fake-root.
Nu pe dumneavoastră stimate manager trebuie să vă intereseze unde se află exact acest
director ci, pe cel care se ocupă de implementarea şi întreţinerea programelor sitului
comercial. Poate sunteţi chiar dumenavoastră şi, vă felicităm atunci, fiindcă sunteţi un
manager modern!
Proces, multitasking, multithreading, soclu şi
port
Deşi am explicat primele două noţiuni în referinţa /1/, le reluăm şi aici.
Proces
Să considerăm că folosiţi editorul Winword ca să puneţi la punct un document. La un
moment dat, fiindcă sunteţi cuplat prin modem la linia telefonică, vine un caracter (literă
sau cifră) prin linie. Acesta nu trebuie pierdut, altfel s-ar altera înţelesul mesajului. Este
grija sistemului de operare existent pe maşina dumneavoastră de calcul să „întrerupă”
executarea programului WinWord fără să simţiţi şi „să transfere controlul spre”
programul care se ocupă de recepţia caracterelor. Să zicem că acest program este
clasicul dialer.exe. Winword trebuie să nu îşi piardă contextul până unde aţi ajuns cu
punerea la punct a documentului, ca să fiţi în stare să vă continuaţi treaba. Există un
planificator de aşa-zise procese, task scheduler, care se ocupă de această trecere de la un
proces la altul.
Procesul (task) este un program ajuns într-un anume context.
Multitasking
Sistemul de operare a alocat zona de memorie pentru păstrarea acestui context. Aici „a
fost salvat”, adică s-a memorat conţinutul registrelor microprocesorului, după care
acelaşi task scheduler s-a ocupat de aplicaţia dialer.exe. Şi ea ajunsese într-un anume
context. El este păstrat altundeva, nu peste contextul lui WinWord ! În consecinţă,
planificatorul va reîncarca registrele microprocesorului cu valorile specifice de la
contextul anterior unde rămăsese dialer.exe. Apoi se va ocupa de preluarea caracterului.
După preluare, va „dezactiva” aplicaţia dialer.exe, păstrându-i noul context, după care
va reface contextul aplicaţiei WinWord, ş.a.m.d. Şi aceasta poate de sute de ori într-o
secundă, fără ca dumneavoastră să sesizaţi!
Acesta este mediul tipic de lucru denumit multitasking, multiproces.
Multithreading
Java permite şi multithreading-ul. Este un fel de multitasking care face risipă de spaţiu
de memorie. De data aceasta, microprocesorul apelază la o instrucţiune specială de
schimbare a „spaţiului de adresare”. Are loc o comutare ultrarapidă de conţinut de
registre ale microprocesorului spre spaţiile de adresă. Deci descarcă-încarcă aceste
registre speciale. Se zice că se trece de la un fir de execuţie la altul. Un program ocupă
un anume spaţiu din memoria operativă. Contextul acum nu se mai limitează la doar cei
câţiva zeci sau sute de octeţi, cum era în cazul multitasking-ului. Pur şi simplu aplicaţia
X are mai multe astfel de spaţii mari rezervate în memorie
Portul, soclul
Portul şi soclul sunt cu totul altceva O aplicaţie tip server dialoghează cu o aplicaţie tip
client prin mesaje. Mesajele aparţin protocolului întrebuinţat: http, ftp, smtp etc. Trebuie
neapărat o zonă de memorie, un bôite de lettre. Să-i zicem şi pe româneşte, cutie poştală.
Acesta este soclul. Soclul are un număr, o adresă. Este portul. Nu intrăm în alte
amănunte tehnice, dar soclul respectă cerinţele protocolului respectiv. De pildă ftp
foloseşte porturile 20 (pentru handshaking) şi 21, http recurge la portul 80. Sau Allaire
Jrun „ascultă” la portul 8100, în timp ce serverul Web Apache, portul 80, Tomcat şi
Resin folosesc portul 8080 etc.
După ce lansăm browserul vom anunţa în fereastra de adresare a sa (în cazul Netscape
se operează cu noţiunea de Location, nu Address) că vrem să lansăm un sit, de pildă aşa:
http://localhost:8080/test/mysit.jsp
Aici situl comercial se afla pe aceiaşi maşină de calcul, dar bine mersi putea ca să se afle
undeva pe alt fus orar şi atunci, în loc de localhost trebuia să menţionăm adresa
serverului gazdă a sitului comercial.

Jalonul alias cookie


Protocolul http este unul care nu are posibilitatea să înregistreze faptul că un vizitator a
efectuat mai multe intrări tip cerere/răspuns la acelaşi sit. Specialiştii numesc acest
protocol HTTP drept unul „fără stări”.
Când s-a născut acest sistem Web (vezi detalii în referinţa /1/), cam tot atunci a apărut şi
HTML. Era pe la începutul anilor ’90. HTTP a avut un succes formidabil, deşi nu s-a
preocupat să memoreze la serverul Web starea unei sesiuni. Atât clientul cât şi serverul
folosesc protocolul http. Internatutul cere. Serverul caută şi găseşte documentul. Apoi
trimite răspunsul.
S-a urmărit ca HTTP să fie cât mai rapid, mai simplu, deci cât mai compact. De aici
succesul!
Fiecare cerere a clientului Web este tratată separat de către server. Este un eveniment
izolat. HTTP nu ştie că internautul a mai vizitat acel sit şi nu îşi propune să memoreze
acest istoric al vizitelor sale.
Atunci, undeva trebuie păstrate aceste jaloane, identificatoare de sesiune, cookies! Mai
departe, vezi în capitolul 6 şi în cazul aplicaţiei complexe a sitului comercial din partea
dedicată tehnologiei ASP (capitolele 7-10).
2
Capitolul

Primii paşi cu tehnologia JSP


JSP, Java Server Pages este o tehnologie de vârf. Stă la baza celor mai mari
situri comerciale. Este concurată de tehnologia ASP. Prima a fost dezvoltată de
către corporaţia Sun Microsystems, a doua, de către corporaţia Microsoft.

Paşii procesului de generare ai unui servlet


Modurile de solicitare a servletului de la serverul Web de către clientul Web

P entru început să contemplăm figura 2.1. Ce observăm din ea? Faptul că clientul
Web solicită servletul fie:
• în modul indirect, prin adresarea clasică în stilul URL, aşa cum am arătat
http://adresa-sit/dir/.../dir/pagina.jsp, fie
• în mod direct, prin schema de adresare tot tip URL, dar în forma următoare:
http://adresa-sit/dir/.../dir/servlet.
Nu descriem aplicaţii lansate prin schema a doua în cartea de faţă. Faptul că se
întrebuinţează una sau alta din cele două scheme de mai sus, îi este total indiferent
serverului Web, aflat la mijloc în figura 2.1.
Pagina JSP poate conţine linii cu text tip HTML şi scenarii (scriptlet în englezeşte),
scrise în limbaj Java, mai rar în JavaScript. La prima apelare a unei pagini JSP are loc
generarea unui fişier sursă .java şi traducerea în foma .class. Toate accesele ulterioare
efectuate de către clientul Web sunt rezolvate imediat, deoarece imaginea servletului
(.class) rămâne în memoria cache a serverului Web (vezi referinţa /1/ pentru termenul
cache). Deci se vor ocoli paşii de compilare şi încărcare.

FIGURA 2.1 Cei trei protagonişti implicaţi într-o sesiune la un sit comercial
(reproducere din manualul devapp.pdf al Allaire JRun, varianta standard)
şi paşii enumeraţi mai sus:

FIGURA 2.2 Paşii de transformare ai unei pagini jsp (reproducere din manualul
devapp.pdf al Allaire JRun, varianta standard)

Un prim exemplu de pagină JSP în câteva


variante
1. Mai întâi de toate să reţinem că trebuie pornit unul din motoarele
servlet. La staţii am implementat doar motorul Caucho 1.1.4, acesta
fiind cel mai rapid în comparaţie cu JRun şi cel mai mic consumator de
spaţiu. Totuşi paşii următori vor releva şi cazul motorului JRun 3.0.
2. Creăm apoi cu editorul Notepad (Windows) următorul document în care apar
banalele balize ale limbajului pentru hipertexte. Este bine să vă reamintiţi acest
limbaj. Vă recomandăm să citiţi anexa A.
LISTA 2.1 Un prim exemplu banal, welcome1.jsp

<html>
<head>
<title>Welcome!</title>
</head>
<body>
<H3 ALIGN="CENTER">Welcome to our store!</H3>
<CENTER><FONT FACE="Verdana" COLOR="darkgreen" SIZE="4">We sell the
&lt;&lt;BEST&gt;&gt; products!</FONT>
</CENTER>
</body>
</html>

3. Stocăm (salvăm) pagina în directorul dedicat aplicaţiilor curent testate.


În cazul motorului JRun, directorul de casă (fake-root) va fi notat cu
<HOME_JRun>. Concret acesta va fi c:\Program Files\Allaire\JRun.
În cazul motorului Caucho Resin îl vom nota <HOME_Resin> şi, concret se află
în directorul c:\Resin1.1.4\doc. Să nu confundăm însă aceste directoare de
casă cu directoarele aplicaţiilor curent testate. Directorul aplicaţiei curente este
la:
¾ (JRun ) <HOME_JRun>/servers/default/default-app
¾ (Resin) <HOME_Resin>/test
Ultimele observaţii:
Nu vom intra în amănunte de implementare a motoarelor. Semnalăm doar că JRun
şi Resin, la pornirea lor la cald, rulează automat un aşa numit scenariu de
configurare. În cazul JRun el se cheamă local.properties, iar în contextul
motorului Resin, httpd.conf. El conţine tot felul de comenzi şi valori necesare
iniţializării motorului respectiv.
Vă rugăm să nu ştergeţi din greşeală aceste fişiere cu scenarii sau, să salvaţi
exemplele în alte directoare. În caz contrar, ar trebui să învăţaţi cum să modificaţi
aceste scenarii pentru configurare!
Lansăm browserul MSIE. Schemele URL vor fi următoarele:
http://localhost:8080/test/welcome2.jsp (pentru Resin1.1.4), respectiv
http://localhost:8100/welcome2.jsp (pentru JRun)
Fiecare motor va genera în mod automat servletul sub forma unui cod sursă Java,
dacă pagina conţine una sau mai multe porţiuni cu scenarii (scriptlets în engleză).
Motorul va realiza de asemeni traducerea (compilarea) codului sursă în cod de
octeţi (.class). Va avea aceiaşi denumire.
Pentru aplicaţia de mai sus nu a existat nici un scenariu. Deocamdată!
Fiindcă fişierul a avut extensia .jsp, motorul a generat în mod automat un program scris
în limbajul Java în directorul:
<HOME_Resin>/work/_test/_jsp
În urma compilării, alături de fişierul sursă va fi înregistrat şi fişierul cu denumirea
_welcome1__jsp.class.

FIGURA 2.3 Aspectul documentului din lista 1.1

Rostul său a fost să creeze şi să trimită la clientul Web acel text din lista de mai sus.
Deci pagina a fost generată dinamic!

Primul scriptlet
Fişierul welcome1.jsp putea foarte bine să aibă una dintre extensiile .html sau .htm,
deoarece este un document tip html, fără nici un scriptlet. În acel caz ar fi fost o pagină
statică, moartă! Fişierul welcome2.jsp în schimb are un scenariu, scriptlet.
Scriptletul e delimitat de „separatorii”: <% şi %>. Priviţi aplicaţia welcome2.jsp.
LISTA 2.2 Fişierul welcome2.jsp

01. <html>
02. <head>
03. <title>Welcome!</title>
04. </head>
05. <body>
06. <%
07. out.println("<H3 ALIGN=\"CENTER\">" + "Welcome to our store !" + "</H3>");
08. out.println("<CENTER><FONT FACE=\"Verdana\" COLOR=\"DARKGREEN\"
SIZE=\"4\">" + "We sell the &lt;&lt;BEST&gt;&gt; products!" +
"</FONT></CENTER>");
09. %>
10. </body>
11. </html>

Explicaţii
În cazul de faţă, scriptletul este alcătuit din două instrucţiuni 07 şi 08. Denumirea out se
referă la obiectul implicit out al JSP. El are misiunea de a reda un flux de caractere la
fişierul logic de ieşire al aplicaţiei (de regulă ecranul). Denumirea println se referă la
metoda pentru realizarea dezideratului amintit. În lista aplicaţiei welcome1.jsp erau
aceste linii:
<H3 ALIGN="CENTER">Welcome to our store!</H3>
<CENTER><FONT FACE="Verdana" COLOR="darkgreen" SIZE="4">We sell the
&lt;&lt;BEST&gt;&gt; products!</FONT>

Cu ce diferă? Prin mai multe lucruri. Primul lucru care sare în ochi este faptul că apare o
paranteză rondă deschisă, apoi un grup de aşa-zis literali, delimitaţi de semne plus şi la
final de o paranteza rondă închisă. În sfârşit, totul se termină prin caracterul punct şi
virgulă. Orice instrucţiune Java se termină cu acest caracter « ; ».
Literalul este un şir de litere şi cifre (caractere) flancate de ghilimele. Semnul plus
serveşte la alipirea acestor literali.
Argumente reale şi fictive (parametri reali şi fictivi)
Metoda println() este un fel de subprogram, aşa cum afirmam mai sus. În consecinţă,
acest subprogram va avea o listă de parametri reali (argumente reale). O astfel de listă
este înconjurată de parantezele ronde. În cazul exemplului nostru s-a folosit un singur
parametru. Dacă lista ar fi avut mai multe argumente, atunci ar fi avut forma: (arg1,
arg2, ... ). Deci virgulele urmau fiecărui parametru, excepţie făcând ultimul.
Să descifrăm acum acest lung şir de caractere al unicului argument. Observaţi existenţa
balizelor din HTML dar şi a textului obişnuit. Vă recomandăm totuşi să recitiţi sau să
citiţi anexa A, pentru a vă explica mai departe la ce se referă aceste balize şi secvenţe
escape (adică notaţiile: &lt; , &gt; ).
Iată o parte din textul generat de către Caucho pentru pagina welcome2.jsp:
LISTA 2.3 Codul generat de către motorul servlet Resin la prima executare
a fişierului welcome2.jsp
/*
* JSP generated by Resin 1.1.4 -- Thu Sep 7 09:00:17 PDT 2000
*/

package _jsp._test;
import java.io.*;
import javax.servlet.*;
import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*;
import javax.servlet.http.*;

public class _welcome2__jsp extends com.Caucho.jsp.JavaPage{

public void
_jspService(javax.servlet.http.HttpServletRequest request,
javax.servlet.http.HttpServletResponse response)
throws IOException, javax.servlet.ServletException
{
javax.servlet.jsp.PageContext pageContext =
com.Caucho.jsp.QJspFactory.create().getPageContext(this, request, response, null, true, 8192,
true);
javax.servlet.jsp.JspWriter out = (javax.servlet.jsp.JspWriter) pageContext.getOut();
com.Caucho.jsp.ByteWriteStream _jsp_raw_out;
_jsp_raw_out = (com.Caucho.jsp.ByteWriteStream) out;
javax.servlet.ServletConfig config = getServletConfig();
javax.servlet.Servlet page = this;
javax.servlet.http.HttpSession session = pageContext.getSession();
javax.servlet.ServletContext application = pageContext.getServletContext();
com.Caucho.jsp.QBodyContent _jsp_endTagHack = null;
try {
_jsp_raw_out.write(_jsp_string0, 0, _jsp_string0.length);

out.println("<H3 ALIGN=\"CENTER\">" + "Welcome to our store!" + "</H3>");


out.println("<CENTER><FONT FACE=\"Verdana\" COLOR=\"DARKGREEN\" SIZE=\"4\">" +
"We sell the &lt;&lt;BEST&gt;&gt; products!" + "</FONT></CENTER>");
_jsp_raw_out.write(_jsp_string1, 0, _jsp_string1.length);
} catch (Exception e) {
pageContext.handlePageException(e);
} finally {
JspFactory.getDefaultFactory().releasePageContext(pageContext);
}
}
...
<html>\r\n<head>\r\n<title>Welcome!</title>\r\n</head>\r\n<body>\r\n".getBytes();
_jsp_string1 = "\r\n</body>\r\n</html>\r\n".getBytes();
}
}

Nu vă vom cere să scrieţi aşa ceva niciodată! Citiţi însă cu luare aminte observaţiile
extrem de importante de la sfârşitul acestui prim capitol.
Aspectul ferestrelor document ale ambelor aplicaţii welcome1.jsp şi welcome2.jsp sunt
identice din punct de verdere al browserului. El este redat în figura 2.3.
Fereastra tip document a browserului
Programul de vizitare, navigatorul sau browserul, cum vreţi să îi spuneţi, este o aplicaţie.
O aplicaţie poate exista la un moment dat sub forma a unuia sau mai multe procese.
Fiecărui proces îi este asociată o fereastră de tip document. La urma urmei, browserul
poate gestiona una sau mai multe fişiere cu extensia .htm/.html. Fiecărui fişier îi
corespunde o fereastră document, un anume context. Fereastra document este în cadrul
ferestrei de aplicaţie.

Expresii
Iată următorul caz :
LISTA 2.4 Fişierul welcome3.jsp

01. <html>
02. <head>
03. <title>Welcome!</title>
04. </head>
05. <body>
06. <%="<H3 ALIGN=\"CENTER\">" + "Welcome to our store!" + "</H3>" %>
07. <%="<CENTER><FONT FACE=\"Verdana\" COLOR=\"DARKGREEN\"
SIZE=\"4\">" + "We sell the &lt;&lt;BEST&gt;&gt; products!" +
"</FONT></CENTER>" %>
08. </body>
09. </html>

Explicaţii şi parafraze
Ce observăm acum? Faptul că în pagina welcome3.jsp apar două scenarii în loc de unul.
Pot fi oricâte! Mai remarcăm apoi că se foloseşte câte un semn egal.
Să ne fixăm atenţia asupra textelor ce urmează semnelor egal (liniile 06 şi 07). Textele
sunt aproape identice cu ce am scris mai sus la welcome2.jsp. Este totuşi o diferenţă!
Priviţi acele bare inverse ce apar din loc în loc în faţa ghilimelelor.
Am fost obligaţi să folosim aceşti dubleţi de caractere \" din motivul următor: HTML
foloseşte ghilimelele pentru atributele balizelor sale. Deoarece limbajul Java foloseşte
tot ghilimele pentru literali (nu numai apostrofii), trebuie adaugat sistematic această bară
inversă (backslash) înaintea ghilimelei care delimitează o valoare de atribut HTML.
Forma echivalentă a textului de mai sus se exprimă din punct de vedere sintactic în felul
acesta:
<%=expresie_Java %>

Semantica, adică înţelesul acestei transcrieri este: „evaluează pe loc expresia aflată în
dreapta semnului egal şi execută ce se cere în cadrul ei”. Expresia de mai sus este o
alipire (concatenation, concatenare cum spun informaticienii) de literali.
Să apară data şi ora!
LISTA 2.5 Pagina welcomets0.jsp în care apar data şi ora

01. <%@ page import='java.text.*, java.util.Date' %>


02. <html><head><title>Welcome!</title></head>
03. <body><font color="ultramarine">
04. <center>
05. <%
06. String data_ora = DateFormat.getInstance().format(new Date());
07. %>
08. <p>Today is: <%=data_ora %>
09. </center></font></body>
10. </html>

FIGURA 2.4 Aspectul documentului

Explicaţii şi parafraze
Constatăm pe prima linie a listei directiva page. Limbajul JSP este alcătuit din: etichete,
directive şi comenzi din cadrul scenariului JSP.
Scenariul JSP l-am întâlnit până acum sub forma expresiei şi instrucţiunii din limbajul
Java. Unii le spun declaraţii. Dar să nu ne pierdem în terminologie!
Directivele stabilesc proprietăţile unei pagini JSP. Una dintre directive este şi page
(pagină). Ea are multe funcţii. Nu ne propunem a le înfăţişa ca într-un manual de
referinţă.
În cazul de faţă, directiva page asumă că limbajul va fi Java (lipseşte atributul language
= ”nume-limbaj”), dar anunţă motorul să preia informaţiile deja definite dintr-o serie de
pachete externe aplicaţiei.
Întregul eşafodaj de clase Java se bizuie pe o ierarhie de clase grupate în pachete.
Pachetele sunt ataşate unor noduri ale ierarhiei.
Ce înseamnă a importa ?
Să traducem: „preia” tot ce este nevoie în acest exerciţiu din nodul java.text.* şi din
clasa java.util.Date. Aşadar cuvântul import este al doilea atribut al directivei page.
Prezenţa asteriscului indică faptul că vor fi moştenite datele şi metodele claselor care
„cuplate” la nodul ierarhic java.text.
În al doilea caz, se va prelua exact clasa java.util.Date, care se ocupă de tratarea datei
calendaristice. Acum urmează ceva cu totul nou! Scenariul din liniile 06-08 conţine o
instrucţiune de atribuire Java. Mai întâi şi întâi se declară o variabilă denumită data_ora.
Ea are tipul şir de caractere (adică String). Instrucţiunea de atribuire are forma sintactică:
tip variabila = expresie;

Tipul ei poate lipsi. În dreapta semnului egal se află o expresie cam ciudată, care constă
dintr-o înlănţuire de denumiri separate prin puncte. DateFormat este numele unei clase
care aparţine clasei părinte java.text.Format.
În schimb, getInstance() este denumirea uneia dintre metodele acestei clase. Faptul că
după denumirea aceasta urmează paranteze, ne dăm seama că este o metodă. Ea „va
prelua o instanţă a obiectului Date, deci un şir cu data şi ora momentului. Acest
instantaneu are un anumit tipic de scriere anglo-saxon. Denumirea format este numele
unei metode a clasei java.text.Format, clasa părinte a clasei java.text.DateFormat. Deci
observaţi ce afirmam mai sus cu privire la moştenire.
Clasa java.text.Format este fiica clasei părinte java.lang.Object. Aşadar obiectul Format
moşteneşte o parte din caracteristicile obiectului generic Object, căruia îi ataşează şi alte
însuşiri specifice!
Să reluăm firul explicaţiei simpliste. Mai observăm că imediat după cuvântul format
urmează paranteze, dar nu una după alta, ca la getInstance(). Între paranteze apar două
cuvinte new şi Date(). Date este un obiect? Nu! Fiindcă este scris cu literă mare! Şi
totuşi este urmat de paranteze, deci ar trebui să fie o metodă. Şi aşa şi este! Este o
metodă specială.
Orice clasă are o metodă specială denumită constructor, care are respectă denumirea
exactă a clasei. Momentul vizitării sitului comercial este exprimat printr-un număr cu
zecimale (în jargon Java … double). Este o valoare cu un format anume, căruia
programatorii îi spun double (vezi şi capitolul următor). Metoda format converteşte
această valoare într-un şir de caractere (String), ca informaţia să devină inteligibilă. Se
respectă tipicul fusului orar pe care a fost generat sistemul de operare la maşina
respectivă. PC-ul pe care am alcătuit acest manual avea un Windows NT „instalat” pe
fusul orar GMT+2, deci ora Balcanilor. De aceea observaţi în figura 2.4 un mod mai …
familiar nouă, anume: zz.ll.aaaa. Nu s-a asumat tipicul anglo-saxon (adică: aaaa.mm.dd
hh:mm:ss, unde aaaa este anul din patru cifre, mm, a câta lună din an, dd, a câta zi din
lună, hh a câta oră din zi, al câtelea minut, a câta secundă).
Odată adusă această valoare a momentului la forma de şir, din el preluăm cu metoda
getInstance() partea referitoare la dată şi cea referitoare la oră.
Iată şi o altă manieră de anunţare a momentului vizitării sitului (vezi figura 2.5).

FIGURA 2.5 Aspectul ferestrei documentului browserului MSIE, pentru fişierul wts.jsp
Adică în loc de 04 apare denumirea aprilie. Mai mult chiar, apar şi patru iniţiale : EEST
ba chiar şi secunda! Ca să realizăm un aspect similar celui din figura 2.5, aplicaţia a
trebuit să fie modificată astfel:
LISTA 2.6 Pagina wts.jsp, o altă manieră de publicare a datei şi orei vizitării sitului

01. <%@ page import='java.text.*, java.util.Date' %>


02. <html><head><title>Welcome!</title></head>
03. <body>
04. <center>
05. <%
06. int FULLDATE = 0;
07. int FULLTIME = 0;
08. String data_ora =
DateFormat.getDateTimeInstance(FULLDATE,FULLTIME).format(new Date());
09. %>
10. <p>Today is: <%=data_ora %>
11. </center></body>
12. </html>

Explicaţii
Apar două variabile FULLTIME şi FULLDATE, fiecare iniţializate cu zero. Metoda
getInstance() s-a înlocuit cu metoda getDateTimeInstance(), ca să se preia întregul flux
de caractere. Anterior, am ignorat în mod deliberat secundele şi tipul orei standard!
Observaţi secundele şi iniţialele EEST, adică ora standard a Europei de Est. Denumirea
aprilie a apărut ca urmare a faptului că FULLDATE a fost egal cu zero.
Acum să facem să apară semnificaţia prescurtării EEST. Priviţi lista şi aspectul
corespunzător din figura 2.6.
LISTA 2.7 Lista fişierului wts1.jsp

01. <%@ page import='java.text.*, java.util.Date' %>


02. <html><head><title>Welcome!</title></head>
03. <body>
04. <center>
05. <%
06. int FULLDATE = 0;
07. int FULLTIME = 0;
08. String data_ora =
DateFormat.getDateTimeInstance(FULLDATE,FULLTIME).format(new Date());

09. String acronim = data_ora.substring(25,29);


10. %>
11. <p>Today is: <%=data_ora %></p>
12. <p>Acronim <%=acronim %> means Eastern Europe Standard Time!</p>
13. </center></body>
14. </html>
FIGURA 2.6 Aspectul ferestrei documentului browserului MSIE, pentru fişierul wts1.jsp

Explicaţii
Scenariul nu s-a complicat decât cu câteva linii. Am declarat variabila acronim.
Limbajul Java cere obligatoriu ca o variabilă să fie nu numai declarată ci, şi iniţializată
cu o valoare! Obiectului data_ora i-am ataşat metoda substring. Metodei i-am dat două
jaloane şi anume de la ce literă şi până la ce literă să „extragă” o porţiune de literal. Aici
am punctat exact locul celor patru litere, EEST. Şirul este reprezentat în memorie din
caractere care ocupă fiecare câte un octet. Indexul începe de la zero, vezi figura 2.7.
1 0 a p r i l i e 2 0 0 3 1 2: 0 7: 3 6 E E S T
coloana 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8
FIGURA 2.7 Reprezentarea şirului de caractere în memorie

Şi … numele vizitatorului sitului!


Priviţi figura 2.8.

FIGURA 2.8 Aici apare şi denumirea clientului

Iată codul care conduce la un astfel de aspect:


LISTA 2.8 Un scenariu în care prelucrăm doi parametri pasaţi prin adresa în stilul URL

01. <%@ page import='java.text.*, java.util.Date' %>


02. <html><head><title>Welcome!</title></head>
03. <body><font color="ultramarine">
04. <center>
05. <%
06. int FULLDATE = 0;
07. int FULLTIME = 0;
08. String data_ora =
DateFormat.getDateTimeInstance(FULLDATE,FULLTIME).format(new Date());
09. %>
10. <p>Today is: <%=data_ora %>
11. <p></font>
12. <font color="blue" size="+4">
13. <%
14. String firstName = request.getParameter("fName");
15. String lastName = request.getParameter("lName");
16. out.println("Welcome dear Mr/Mrs/Miss " + lastName + " " + firstName);
17. %>
18. </center></font></body>
19. </html>

Ca să funcţioneze acest exemplu, trebuie să recurgeţi la specificaţia URI (URL)


următoare:
http://localhost:8080/test/welcome4.jsp?fName=numele_dvs.&lName=prenumele dvs.

Explicaţii
Remarcaţi scenariul din liniile 14-16. Am declarat variabilele firstName şi lastName.
Le-am iniţializat cu valori. În acest sens am folosit tuplul
nume_obiect.denumire_metodă

deci request.getParameter(). Obiectul s-a numit request (vezi capitolul următor) iar
metoda, getParameter().

Să adăugăm un fond muzical şi un efect de


animaţie sitului!
Vă rugăm să rulaţi următorul exemplu de pagină JSP (lista 2.8) pe o configuraţie care să
aibă placa de sunet, difuzoare, browserul MSIE (neapărat, fiindcă pe alte browsere nu
este recunoscută baliza MARQUEE din HTML), iar browserul să fie instalat în mod
standard, adică să fie în stare să recunoască obiecte multimedia muzicale (fişierele cu
extensia .au, .avi şi/sau .voc). Fişiere cu unul dintre aceste sufixe ar trebui să existe pe
PC-ul dumneavoastră.
Plasaţi în final secvenţa muzicală, pe care să o redenumiţi melos.au, chiar în acelaşi
director test, ca şi exemplul welcome5.jsp, acesat fireşte, dacă fişierul muzical a avut
tipul de date „.au”. Lansaţi apoi motorul servlet şi daţi comanda care se vede în linia
Address, din figura 2.9.
LISTA 2.9 Un sit muzical!

01. <html>
02. <head>
03. <title>Welcome!</title>
04. </head>
05. <body>
06. <%="<H3 ALIGN=\"CENTER\">" + "Bine ati venit stimate cumparator!" + "</H3>"
%>
07. <%="<CENTER><br><EMBED SRC=\"melos.au\" >" %>
08. <%
09. int m = 5;
10. String marfuri[] = { "electronice", "mobila", "cosmetice", "pentru gradinarit",
"camping" };
11. out.println("<MARQUEE>Azi va oferim o bogata gama de sortimente de marfuri:
</MARQUEE>");
12. for (int i = 0; i < m; i++ ) {
13. switch (i) {
14. case 0: out.print("<font color=\"brown\">" + marfuri[i] + "</font>");
15. break;
16. case 1: out.print("<br><font color=\"blue\">" + marfuri[i] + "</font>");
17. break;
18. case 2: out.print("<br><font color=\"darkblue\">" + marfuri[i] + "</font>");
19. break;
20. case 3: out.print("<br><font color=\"green\">" + marfuri[i] + "</font>");
21. break;
22. case 4: out.print("<br><font color=\"darkgreen\">" + marfuri[i] + "</font>");
23. break;
24. }
25. }
26. %>
27. <%="</CENTER>" %>
28. </body>
29. </html>

FIGURA 2.9 Mult zgomot pentru ... nimic!

Explicaţii şi parafraze
Să îl descifrăm, mai ales că este plin de obiecte de efect! Mai întâi şi întâi suntem de
acum experţi în scriptlet-uri. Vedem în acest exerciţiu vreo patru scenarii. Primele două
sunt identice cu cele din lista 2.3.
Al doilea scriptlet „se ocupă de muzică”! Remarcaţi baliza EMBED (linia 07) din
HTML, prin care anunţăm browserul că urmează să interpreteze cu ajutorul unui add-
on, adică al unui program terţ (un player) partitura melos.au.
Să privim al treilea scriptlet (liniile 09-26). Este primul contact cu instrucţiunile
limbajului Java. Se declară (adică se alocă şi se iniţializează) o variabilă de tip întreg,
denumită m. Ea are valoarea 5. Se declară apoi un masiv de şiruri denumit marfuri.
Valorile fiecărui element al său sunt literalii. Sunt în total cinci elemente, exact cât am
stabilit pentru m. Mai departe remarcaţi instrucţiunea deja familiară, out.println().
Vedeţi baliza MARQUEE, ce este specifică doar browserelor Microsoft. Textul flancat
de perechea <MARQUEE>, </MARQUEE> va aluneca pe ecran.
Ce înseamnă notaţia for (int i = 0; i < m; i++)? Este o instrucţiune Java. Se citeşte aşa:
„pentru i (variabilă de indexare de tipul întreg) cu valori de la 0, până la 5, mai puţin
valoarea 5 (i < 5) din 1 în 1, execută grupul de instrucţiuni aflat între acolade”. Acest
grup îl denumim şi corp. Este compus aici doar dintr-o singură instrucţiune, switch. Pot
fi oricâte instrucţiuni. Dacă este doar o instrucţiune nu mai trebuie folosite acoladele. Nu
am greşit că le-am scris, dar ca să nu uităm aceste acolade le vom adăuga sistematic.
Citim aşa: „când i va avea valoarea egală cu 0, se execută instrucţiunile cazului zero
(case 0:). Apoi se sare după instrucţiunea switch. Variabila i creşte cu o unitate datorită
notaţiei i++. Valoarea i se va compara cu 5. Fiindcă ea este egală cu 1, se va executa
out.println şi break-ul acestui caz (case 1), ş.a.m.d. V-aţi prins!
Mai observaţi ceva şi anume că out.print() adresează câte un singur element al
masivului. Priviţi figura 2.9, unde apar aceste valori în mod distinct. Să nu vă deranjeze
că au diverse culori. Noi le comandăm cu acele balize font color! Deci în cazul i ne
referim la al i-lea element, marfuri[ i ]. Când i a ajuns la valoarea 5, nu se mai intră în
corpul for.

Câteva observaţii extrem de motivate


1. Categoric, nu ne propunem a vă învăţa limbajul Java, ca pe studentul facultăţii
de Informatică Economică. Nu ar avea nici un rost să insistăm, întrucât profilul
facultăţii R.E.I. nu este cel de formare de dezvoltatori de situri comerciale.
2. În postura posibilă de manager, am dori să aflaţi în urma audierii acestui curs şi
să apreciaţi corect efortul celui care a primit de la dumneavoastră misiunea de a
se ocupa de crearea şi întreţinerea unui sit comercial.
3. Foarte mulţi dintre dumneavoastră sunteţi absolvenţi de secţie reală. În ultimele
clase v-aţi întâlnit cu … programarea! Unii aţi avut şi destule ore, alţii mai
puţine pe semetru.
4. Majoritatea aţi deprins a lucra cu suprafeţe de lucru ale familiei Microsoft
Windows de la primul curs de Iniţiere în informatică! Oricum, vă văd colindând
cu dezinvoltură prin situri după ştiri, bârfe, muzică MP3, aveţi frecvent căsuţe
poştale la Hotmail, Yahoo etc.!
5. De-a-lungul timpului am observat un interes aparte la unii dintre studenţii ai
anului doi, spre teme de casă practice nu numai de copia la mântuială un referat
din Internet, cumpărat pe bani de la binevoitori, fără să vă mai înţelegeţi
conţinutul! Este o modă dăunătoare ! La ce aţi mai intrat în facultate!
6. Există între dumneavoastră oameni care publică curent pe Web! Nu este mare
scofală! Facem aceasta la lucrările de laborator, la Yahoo Geocities, de vreo trei
ani încoace!
7. Ultimele cinci serii de studenţi au deprins limbajul HTML. Nu am avut timp ai
învăţa pe studenţii seriei anului universitar 2002/2003 şi ASP, deoarece am
consacrat prea multe cursuri unor elemente despre reţele, aşa cum era structurat
anterior cursul denumit Internet!
8. Am ataşat în această carte o parte din cursul profesorului Mihai Calciu, pe care
acesta îl predă studenţilor economişti de la Universitatea Lille I. Se referă la trei
tehnologii JSP, ASP şi PHP.
9. Noi nu o să ne rezumăm decât la a „vă sensibiliza“ în JSP şi ASP la stadiul nu
de scriere de programe ci de recunoaştere de secvenţe. De aceia o să vi se admită
şi la proba de verificare cartea pe masă. Vai acelora care nu citesc în prealabil
cartea ! Dacă v-ar cădea în mână „Birotica şi Internet la cumpăna mileniilor”,
elaborată de către aceiaşi autori, apărută la editura Lucman în dec. 2000, aţi
constata că în ultima parte vorbeam de limbajul de scenarii PERL sub mediul
Linux.
10. Ca şi la Universitatea Lille, avem şi noi de vreo doi ani încoace un server
propriu de Linux SuSE. Nu este vizibil de la staţiile laboratoarelor, decât într-o
fereastră DOS, întrucât aici nu s-a admis includerea şi a unei suprafeţe grafice
Linux. De la etajul 4 se poate lucra în fereastră tip Term-Linux, din linia de
comandă. Este prea … !
11. Vrem să micşorăm acest decalaj stimaţi studenţi între studenţii români şi cei
francezi. Destul cu mânuirea mausului! Destul cu învăţarea lejeră a folosirii PC-
ului doar pentru colindarea prin spaţiul Web! Din liceu şi din şcoala primară
deprindeţi aceste lucruri!
Concluzia: Trecem la un alt stadiu de profesionalism, de fapt mergem în pas cu ...
lumea!
Înainte de a încheia iată o procedură :
Este absolut necesar ca înaintea folosirii browserului de serviciu (de regulă MSIE), să
porniţi motorul servlet Resin.

Efectuaţi un clic pe pictograma httpd aflată pe suprafaţa de lucru. Vor apare


două ferestre cu fond negru. În fereastra mare se anunţă că motorul aşteaptă mesaje
la portul cu numărul 8080. Pe durata testării nu închideţi aceste ferestre. Minimizaţi-
le sau plimbaţi-le oriunde pe ecran. Dacă le-aţi închideţi opriţi motorul!
La final de capitol
Aşadar în acest capitol am învăţat:
1. Modurile prin care un client Web solicită servicii unui servlet. Am aflat că sunt
trei protagonişti implicaţi: MSIE, adică clientul Web, serverul Web şi în sfârşit
motorul. Toate trei pot fi pe aceiaşi staţie, dar pot fi în puncte diferite!
2. Că sunt cinci paşi prin care se metamorfozează o pagină JSP, ajungând la final
în a fi executată pe serverul Web.
3. Care sunt specificaţiile de adresă în stil URI (URL) pentru lansarea în lucru a
unei pagini JSP în contextul celor două motoare, Allaire JRun şi Caucho Resin.
4. Ce este acela un scriptlet. Am şi elaborat vreo câteva scenarii.
5. Ce înseamnă out.println.
6. Ce înseamnă şirul <%=expresie_Java %>.
7. Cum declară şi se iniţializează variabile.
8. Ce semnificaţie are scrierea de denumiri cuplate prin puncte, specifică mediului
programării orientate pe obiecte.
9. Destule despre limbajul Java, în ultimul listing cu situl muzical!
3
Capitolul

Directive şi obiecte JSP


Pentru a putea răsfoi câteva din caracteristicile acestui limbaj, nu mai putem
pleca de la o aplicaţie de e-commerce, deoarece dacă am face aşa, ar trebui să
venim acum în faţa dumneavoastră stimate cititorule cu exemple complicate şi v-
am bulversa!

S
ă o luăm pe îndelete! Nu avem ce face, trebuie să trecem în revistă doar câteva
dintre „virtuţile” acestui limbaj. Numai în acest capitol se va întâmpla să puem pe
primul loc limbajul, nu aplicaţia ! Şi totuşi vom avea şi aici aplicaţii utile.

Directiva include file


Mecanismul directivei include file
În capitolul precedent aminteam de directiva page. JSP posedă mai multe directive. Să
ne referim acum la directiva include. Sintaxa ei este următoarea:
<%@ include file=”path” %>

Aici path este termenul englezesc şi înseamnă specificaţie de cale. Se ştie încă de la MS-
DOS că un fişier se află undeva într-un anume director, care este fiul altui director…
Deci specificaţia se poate scrie: dir/dir/.../dir/nume-fişier.extensie.
Să privim cazul de mai jos. Sunt două pagini JSP. Iată listele :
LISTA 3.1 Din pagina welcome6.jsp apelăm pagina antet.jsp

01. <%@ page import='java.text.*, java.util.Date' %>


02. <%@ include file="antet.jsp" %>
03. <html>
04. <body><font color="#2288ef"><center>
05. <%
06. String datum = DateFormat.getDateInstance().format(new Date());
07. %>
08. <p>Heute ist am: <%=datum %>
09. </font></center></body></html>
şi pentru pagina antet.jsp:
01. <body>
02. <center><table width="90%" border="0">
03. <tr>
04. <td><font color="#2288ef"><H1 align="center">Willkommen im ... Obst und Gemüße
Haus! </H1></td>
05. </tr>
06. <tr><td><%="<CENTER><br><EMBED SRC=\"melos.au\" >" %></td></tr>
07. </table>
08. </center>
09. </body>

Explicaţii şi parafraze
Să ne fixăm atenţia pe prima dintre liste. Observăm pe linia 02 directiva include. La
întâlnirea unei atari directive, motorul va prelua liniile listei a doua, după care va
continua cu parcurgerea listei welcome6.jsp. În tot acest timp, motorul servlet va
verifica sintaxa comenzilor JSP. Dacă le va găsi în regulă, va genera codul java.
În lista antet.jsp distingem un obiect de tip multimedia (coloana sonoră, melos.au). Este
în linia 06. Mai vedem şi câteva balize ce se referă la un tabel. Nu ieşim din subiectul
acestui capitol. Veţi citi singuri partea referitoare la HTML, pentru a pricepe ce
înseamnă aceste balize!
Şi încă ceva! Literele naţionale germane sunt admise şi afişate corespunzător. Ele fac
parte într-adevăr din pagina de cod ISO 8859-1. Ea se referă la primele 256 caractere
din Unicode. Dacă în primele 128 simboluri apar simbolurile alfabetului englez şi
american, în următoarele 128 coduri se află diacriticele câtorva naţiuni europene
privilegiate.
Acum să contemplaţi aspectul acestei pagini rezultate din fuzionarea paginilor
welcome6.jsp şi antet.jsp.

FIGURA 3.1 Aspectul ferestrei documentului paginii rezultante welcome.jsp şi antet.jsp

Aceasta a fost metoda statică de pasare a informaţiei între pagini. De fapt, aici nu s-a
transmis nimic, decât comanda ca să fie incluse liniile fişierului antet.jsp în fişierul
welcome6.jsp.
Să examinăm în continuare modalitatea de pasare efectivă a parametrilor între două
pagini.

Cum pasăm parametrii între paginile JSP


Recurgem la obiectul implicit request şi la două metode ale sale, getAttribute() şi
setAttribute(). Fişierul a1.jsp trimite fişierului b1.jsp valoarea parametrului titlu.
LISTA 3.2 Parametrul pasat între pagini

<html><body>
<%request.setAttribute("titlu", "Salutare!"); %>
<%@ include file=b1.jsp %>
<%-- Aici urmeaza alte linii ale fisierului a1.jsp -->
</body></html>

şi
<head>
<title><%=request.getAttribute("titlu")%></title>
</head>

FIGURA 3.2 Aspectul ferestrei browserului după „rularea” acestor două pagini

Explicaţii
Observaţi cuvântul „Salutare” afişat în titlul ferestrei. Pasarea are loc prin metodele
getAttribute() şi setAttribute() ale obiectului request.

Diferenţa dintre jsp:include şi jsp:forward


Există şi alt mod de pasare de valori a parametrilor între pagini şi anume, prin etichetele
jsp:include şi jsp:forward.
Notaţia jsp:action este cunoscută sub numele de acţiune standard. I se mai spune
etichetă, deoarece se face un salt de la un program la altul. Sunt mai multe astfel de
etichete, dar ne referim doar la jsp:include, fără a-i arăta sintaxa mai greoaie şi la
jsp:forward, pentru care venim cu un exemplu practic.
Cu jsp:action apelăm o pagină statică (extensia .htm/.html) sau o pagină dinamică
(extensia .jsp) din pagina curentă .jsp. Parametrii reali sunt pasaţi paginii apelate cu
eticheta jsp:param. Mai mult vedem în anexa B. O explicaţie la cele scrise în această
anexă se impune.
Eticheta jsp:include este însoţită de două atribute, page şi flush. Ambele sunt obligatorii.
Sintaxa este următoarea:
<jsp:include flush=”true” page=”adresa_URL” />

sau aşa:
<jsp:include flush=”true” page=”adresa_URL”>
<jsp:param name=”denumirea_parametrului” value=”valoarea_sa” /> …
</jsp:include>

Pentru ambele descrieri sintactice se recurge la descrierea sintactică din XML. Când
observăm o terminaţie de genul />, nu urmează nici un corp. Precis nu cunoaşteţi XML !
Să o luăm prin HTML. Când scriem fluxul:
<p>Acesta este un paragraf.</p>

observăm un marcaj p cu cele două balize. Corpul marcajului este textul în sine. Când
vrem să referim o poză, în HTML scriem aşa:
<img src=”poza”>

Observaţi că după această baliză nu mai este nici o altă baliză </img> . Nu urmează nici
un corp între cele două balize. În HTML este permisă această lejeritate. În XML, ea este
taxată drept eroare sintactică! Şi atunci nu se admite decât scrierea:
<img src=”poza” />

Deci după /> nu urmează nici un corp.


Să privim din nou cele două forme sintactice ale etichetei jsp:include. La prima formă
sintactică se merge pe ideea că nu pasăm nici un parametru. A doua formă sintactică are
în schimb un corp, pe rândul al doilea. Pe rândul al treilea apare iar denumirea, etichetei
precedată de o bară înclinată. Corpul este alcătuit din una sau mai multe etichete
jsp:param. Cele trei puncte înseamnă o posibilă repetare a etichetei jsp:param. Fiecare
parametru are deci o astfel de etichetă.
Deci paginii apelate putem să nu îi trimitem la urma urmei nici un parametru, unul sau
mai mulţi parametri reali.
Fiecare etichetă jsp:param are un nume logic de paramteru (name) şi o valoare (value) a
acestuia.
Să lămurim şi diferenţa dinre jsp :include şi jsp :forward. O pagină JSP generează un
flux de caractere ce sunt destinate clientului Web în ultima instanţă. Acesta, până să
ajungă la clientul Web, este stocat în mod temporar într-o zonă tampon (buffer). Când
atributul flush are valoarea adevărat (true), are loc golirea forţată a acestui tampon.
Pagina spre care este transferat controlul este anunţată prin atributul page.
Priviţi acum figura 3.3.
FIGURA 3.3 Diferenţa dintre etichete jsp:include şi jsp:forward (reproducere
din manualul devapp.pdf al Allaire JRun, varianta standard)

Diferenţa dintre jsp:forward şi jsp:include este unde revine controlul. În cazul forward,
el nu mai revine la pagina apelantă.
Iată un exemplu concret al directivei jsp:forward. Un proprietar de sit (comercial sau
Web) pleacă în vacanţă. El vrea neapărat să treacă la un aspect nou al sitului la o dată
care nimereşte când se află în vacanţă. Noul aspect îl numim newFakeRoot, iar fostul
aspect, oldFakeRoot. Iată acum lista acestui exemplu:
LISTA 3.3 Pagina nachdatum.jsp

01. <%@ page import="java.util.*" %>


02. <%
03. // Exemplu de folosire a evaluarii la momentul executiei paginii tip jsp
04. // cu incepere de la data an luna zi ora min sec trec pe noul fake root
05. // al sitului web. Ich bin im urlaub!

06. String oldFakeRoot = "oldsite.html";


07. String newFakeRoot = "newsite.html";
08. // Creeaza doua instante
09. Calendar h = Calendar.getInstance();
10. Calendar m = Calendar.getInstance();
11. Date hDatum = h.getTime();
12. // Fixeaza momentul trecerii la noul aspect 11 iulie 2003, ora 10.30.00 pe obiectul m
13. m.set(2003,7,11,10,30,00);
14. // Citeste momentul curent
15. Date mDatum = m.getTime();
16. // Compara momentele; s-a ajuns la ora H?
17. boolean resultComp = hDatum.after(mDatum);
18. if ( resultComp ) { // sunt la data lansarii noului aspect al sitului sau dupa? %>
19. <jsp:forward page="<%=newFakeRoot%>" />
20. <% } else { // sunt la un moment anterior datei fixate de comutare a fakerutului! %>
21. <jsp:forward page="<%=oldFakeRoot%>" />
22. <% } %>
Explicaţii şi parafraze
Importăm pachetele java.util.*. Declarăm variabilele oldFakeRoot şi newFakeRoot, care
vor puncta paginile de casă, deci începuturile ierarhiilor directoarelor celor două situri.
Pagina de casă a sitului vechi se numeşte oldsite.html, iar pagina de casă a sitului nou se
va numi newsite.html. Mai departe creăm două instanţe (h şi m) de obiecte tip Calendar.
Când auziţi exprimarea „creează o instanţă...”, maşina virtuală Java va aloca o zonă de
memorie pe care o va pregăti în mod corespunzator. Mai departe, se alocă variabilele
hDatum şi mDatum. Se instanţiază şi aceste două variabile ca obiecte de tipul Date.
Obiectul m primeşte valoarea datei şi orei când se va trece pe noua pagină de casă. În
mDatum se va depune aşadar şirul de caractere 11 iulie 2003, ora 10.30. Obiectul
hDatum trebuie creat şi „încărcat” cu momentul curent. Se compară cele două şiruri
hDatum cu mDatum. Când se ajunge la data şi ora respectivă, se trece automat pe noul
aspect. Urmăriţi instrucţiunea de comparaţie. Atunci conţinutul variabilei resultComp va
fi mai mare decât 0, deci se va executa eticheta jsp:forward. Aici se va evalua dinamic
expresia <%=newFakeRoot%>.
După executarea saltului spre pagina newsite.html, controlul nu mai revine în pagina
chemătoare, nachdatum.jsp, cum s-ar fi întâmplat dacă am fi folosit jsp:include.
În fond şi la urma urmei ce este o pagină JSP? Este un text şablonizat format din
porţiuni HTML şi scenarii scrise în Java (sau JavaScript).

Despre obiecte implicite şi explicite


Nouă obiecte implicite
JSP operează cu obiecte implicite şi explicite. Sunt nouă obiecte implicite. Iată-le:
application (aplicaţia), config (configurarea), exception (tratarea excepţiilor, erorilor),
out (scrierea în pagina curentă a unui flux de caractere), page (pagina), pageContext
(contextul paginii), request (cererea), response (răspunsul) şi session (sesiunea). Aţi
observat în exemplele date până acum directiva import. Cu ea anunţam JVM că avem
nevoie de o serie de clase. Clasele „produc” obiecte. Fiecare clasă are cel puţin unul sau
mai multe metode pe post de constructori, care servesc la crearea obiectului. Spunem: se
instanţiază obiectele!
În cazul obiectelor implicite, maşina virtuală Java este aceea care instanţiază din oficiu.
În cazul propriilor noastre clase sau a sutelor de clase, care nu sunt abstracte şi aparţin
unuia dintre pachetele Java, se recurge la operatorul de instanţiere new.
Maşina virtuală Java importă în mod automat patru pachete de bază. Un pachet conţine
un set de clase aşezate într-o ordine ierarhică.
Ele sunt: java.lang.*, javax.servlet*, javax.servlet.jsp* şi javax.servlet.http*.
Nu ne interesează ce conţin în detaliu.
Obiectul aplicaţie
Să dăm drept exemplu o pagină unde recurgem la obiectul application. Din acest
exerciţiu vom afla deosebirea dintre un obiect implicit (application) şi obiectul explicit
(Date). Iată conţinutul fişierului:
LISTA 3.4 Exemplu de folosire al obiectelor application şi Date

<%@ page import="java.util.Date,java.text.DateFormat" %>


<html>
<head><title>Exemplu de obiecte implicite si explicite</title></head>
<body>
<table>
<tr>
<td>Numele serverului</td>
<td>"<%= application.getServerInfo() %>"</td>
</tr>
<tr>
<td>Specificatia reala de cale</td>
<td>"<%= application.getRealPath("/") %>"</td>
</tr>
<tr>
<td>Ora curenta</td>
<td>"<%= DateFormat.getTimeInstance().format(new Date()) %>"</td>
</tr>
</body></html>

Explicaţii şi parafraze
Lista se referă la un tabel banal care se conformează sintaxei venerabilului HTML. Prin
comanda import anunţăm maşina virtuală Java că vor fi utilizate metodele a două clase
şi anume, java.util.Date şi java.text.DateFormat.
Clasa Date crează un obiect cu acelaşi nume. Este un obiect explicit, dovadă folosirea
operatorului de instanţiere new. Întotdeauna când vedeţi acest cuvânt, să ştiţi că s-a cerut
instanţierea, adică generarea obiectului cu acelaşi nume. Deci notaţia new Date()
înseamnă apelarea constructorului clasei Date. Acesta alocă în memorie un spaţiu
suficient pentru structura de date cerută de către obiect. Informaţia în sine a acestui
obiect este o valoare egală cu numărul microsecundelor scurse de la 1 ianuarie 1970 ora
0 (meridianul Greenwich) până în momentul apelului. Formatul acestei valori este un un
întreg reprezentat pe un număr dublu de octeţi, 8 nu 4.
Cu ajutorul metodei format(), valoarea aceasta este transformată într-un şir de caractere,
unde apar data şi ora.
Metoda getTimeInstance() aparţine clasei java.text.DateFormat. Ea extrage doar ora. Ei
bine, şi obiectul clasei java.text.DateFormat este tot unul de tipul explicit. Veţi zice că
nu este, deoarece nu apare operatorul new, cum a fost în cazul de mai sus! Vă vom
răspunde aşa: clasa DateFormat este o clasă de un tip abstract. Aceasta înseamnă ceva şi
nu mai intrăm în detalii. În acest caz nu este nevoie să fie instanţiată cu new. O clasă
care nu este abstractă creează un obiect numai cu ajutorul constructorului, deci cu new.
Java posedă destule clase abstracte. Din aceiaşi categorie a acestor clase abstracte face
parte şi clasa Enumeration din exerciţiul următor.
Obiectul application este tot unul de tipul abstract. De fapt toate cele nouă obiecte au la
bază clase abstracte. Şi toate sunt la fel de importante. Pentru oricare din cele nouă
obiecte implicite, maşina JVM realizează automat instanţierea. În exemplul analizat aici
se cer informaţii despre motor şi despre specificaţia reală de cale unde se află el.
Motorul este un servlet, deci un fişier. Ca atare se află într-un anume director. Până la
acest director se urmează o cale prin ierarhia directoarelor. În cazul motorului Resin
priviţi răspunsul din figura următoare.

FIGURA 3.4a Răspunsul motorului Resin

Pentru motorul servlet JRun, observaţi aspectul ferestrei documentului în figură.

FIGURA 3.4b Răspunsul motorului JRun

Metoda getRealPath() întoarce directorul unde se află paginile JSP, care urmează ca să
fie transformate în servleturi.
În cazul motorului servlet Resin, directorul este c:/Resin1.1.4/doc. Directorul doc are
drept fiu pe directorul test. De aceea apare în adresă şi test.
În cazul motorului JRun 3.0 directorul este:
c:/Program Files/Allaire/JRun/server/default/default-app.
Deoarece exerciţiul aplicdate.jsp se află chiar în acest director, în adresă nu mai apare
nici un alt director. Porturile celor două motoare diferă. JRun comunică cu browserul
client prin portul 8100, în timp ce Resin, prin portul 8080.
Obiectul implicit request
Iată acum un exemplu de folosire a obiectului implicit request cu unele metode ale sale.
Cu metoda getProtocol() se preiau valorile câmpurilor antetului protocolului http.
Programatorii Java denumesc aceste câmpuri, antete. Orice protocol are un antet format
din octeţ, cu tot felul de câmpuri. Fiecare câmp are o denumire şi un anumit format.
Aplicaţia nu face altceva decât să etaleze conţinuturile acestor câmpuri. Se recurge la
obiectul clasei abstracte Enumeration.
LISTA 3.5 Fişierul aplicatie.jsp

01. <%@ page import="java.util.Enumeration" %>


02. <body>
03. <P>Iata numele protocolului folosit: <%= request.getProtocol() %>
04. <p>Si numarul portului: <%= request.getServerPort() %>
05. <p>Si valorile catorva antete:
06. <% // parcurge lista de denumiri de antete din obiectul request
07. Enumeration enumerare = request.getHeaderNames();
08. while (enumerare.hasMoreElements()) {
09. String headerName = (String) enumerare.nextElement(); %>
10. <LI><B><%=headerName%></B> = <%=request.getHeader(headerName) %>
11. <% } %>
12. </body></html>

FIGURA 3.5 Aspectul ferestrei documentului browserului pentru pagina aplicatie.jsp

Explicaţii şi parafraze
Să privim liniile cu numerele 03 şi 04. Cerem informaţii despre protocolul folosit între
server şi client ca şi numărul portului. Apoi, se instanţiază o variabilă denumită
enumerare (linia 07). Atunci când se execută instrucţiunea din linia 07, variabila
enumerare va conţine o serie de şiruri de caractere cu denumirile „antetelor”
protocolului HTTP.
Ca şi for, şi instrucţiunea while comandă o buclă. Corpul ei (liniile 08-11) este delimitat
de două acolade. În acest corp pot fi una sau mai multe instrucţiuni. Acestea sunt
executate atâta timp cât este adevărată condiţia de după cuvântul while. Condiţia se află
între parantezele rotunde.
Să descifrăm condiţia: „atâta timp cât în obiectul enumerare mai există un element care
trebuie tratat preia acest element”. Fiecare … antet (element) este un şir de caractere.
Creăm variabila headerName (linia 09). Aici preluăm şir după şir conţinuturile antetelor
http, cu metoda nextElement().
Observaţi în figura de mai sus răspunsurile asupra cărora nu ne oprim, deoarece sunt
destul de tehnice. Am recurs iniţial la metoda getHeaderNames() a obiectului request.
Pentru obiectul denumit enumerare, al clasei Enumeration, veţi remarca că nu am recurs
la instanţierea explicită cu new. Totuşi JVM a efectuat instanţierea şi ştiţi şi de ce.
Conversii de tip, cast
Ce să însemne oare cuvântul String scris între parantezele ronde din linia 09? Este o aşa
numită conversie. Mai exact se transformă tipul expresiei din dreapta semnului egal în
alt tip şi anume cel aflat în stânga semnului egal, înaintea denumirii variabilei.
În cazul exemplului, ceea ce rezultă din expresia enumerare.nextElement() nu are
formatul unui şir. Pentru că în stânga semnului egal se aşteaptă un … String, se aplică
această conversie. Nu orice conversie este admisă. Nu intrăm în detalii!
Comentarii în pagina JSP
Să recapitulăm puţin diferitele tipuri de comentariilor în cadrul paginilor JSP.
Forma comentariului de tip „text şi eventual evaluarea expresiilor JSP” este:
<!-- text, expresii JSP -->

Principalul scop este comentarea codului sursă. El acceptă însă şi prezenţa expresiilor
JSP, pe care le şi evaluează. Aceasta cel puţin se poate observa în fereastra afişată pe
traseul View – Source (browserul MSIE). De pildă, dacă scriem:
<!—Aceasta pagina a fost generata la data de <%= (new
java.util.Date()).toLocaleString() %> -->

motorul servlet vede totuşi expresia JSP. În fereastra codului sursă vom observa scris
„Aceasta pagina a fost generata la data de 08 05 02 12:04:50“. Deci se preia momentul
când se execută acest servlet la serverul Web.
Există apoi comentariul „ascunde cod” care are forma:
<%- - fragment de scenariu scos din circuitul transformării JSP în Java servlet -->

şi este util în faza de punere la punct al unei pagini JSP. Orice fragment dintr-o pagină
JSP, încadrat de cei doi „delimitatori”, va fi ignorat de către motorul servlet, inclusiv
expresiile tip JSP.
Ierarhii ale claselor în Java
Ca să înţelegem aceste ierarhii fără a deveni mari cunoscători ai convenţiilor Java, să
apelăm iar la un exemplu din viaţa de toate zilele.
Să ne gândim la oraş cu a sa forfotă şi cu al său aer poluat, cu numărul trăitorilor din
cuprinsul său pe timpul zilei şi al nopţii. Să-i atribuim oraşului rangul de obiect generic.
Strada este o subdiviziune a oraşului. Ea poate fie mai largă, mai îngustă, poate avea
diverse debite orare de vehicule de-a-lungul a 24 ore. Obiectul strada moşteneşte de la
obiectul oraş poluarea, forfota. Introduce o caracteristică nouă şi anume, unde se află în
oraş, în zona ultracentrală, centrală ş.a.m.d.
Blocul se află pe o anumită stradă la o anumită adresă. Obiectul bloc moşteneşte de la
stradă şi oraş toate caracteristici de până aici şi în plus adaugă adresa individuală,
numărul de etaje, cu sau fără curte, cu sau fără scuar etc.
Observaţi deci o ierarhie a obiectelor în natură. Pe măsură ce coborâm tot mai jos pe
scara ierarhică, apar obiecte şi mai precis conturate. Obiectul generic, oraşul, avea o
serie de proprietăţi po1, po2. Obiectul strada moşteneşte aceste proprietăţi şi mai adaugă
altele: ps1, ps2, ş.a.m.d.
Programarea orientată pe obiecte (POO) are în vedere astfel de reprezentări precum:
oraşul, strada, blocul. Obiectele s-au născut datorită unor planuri, unei experienţe ce
conduce la construcţia şablonului, datorită arhitecţilor. Să spunem acestei experienţe
metodă.
Revenim la POO. Metodele aparţin unei clase. Clasa este alcătuită din şabloane şi
metode, deci inteligenţă, experienţă în realizare. V-aţi prins deci!
Şi în platforma Java există un întreg arbore genealogic al claselor. Clasele derivă unele
din altele.
Obiectul exception
Să ne ocupăm acum de obiectul exception. Să ne închipuim că vrem să producem în
mod deliberat o eroare de program, pe care să o trateze obiectul exception. Redăm lista
exemplului. Mai întâi fişierul exception_apel.jsp, unde am declarat variabila denumită d
în formatul dublă precizie cu o valoare foarte mică, 10-324:
LISTA 3.6a Pagina exception_apel.jsp

<%@ page errorPage="exception.jsp" %>


<html><body>
<%
// exceptie de depasire
double d = 1.0E-324;
%>
</body></html>

şi imediat pagina de tratare a erorii, exception.jsp:


LISTA 3.6b Pagina exception.jsp

<%@ page isErrorPage="true" %>


<html>
<body>
<p>Producem o eroare deci recurgem la obiectul exception si pagina
pregatita in acest sens</p>
<br><%= exception %>
</body></html>
Rezultatul este redat în figura de mai jos.

FIGURA 3.6 Aspectul ferestrei în cazul Resin 1.1.4

Explicaţii şi parafraze
Ce se întâmplă aici. Această foarte mică valoare nu poate fi „reprezentată” în Java. Ca
atare, declaraţia de la începutul listei anunţă maşina virtuală că există o rutină care se
ocupă de interceptarea excepţiilor. Denumirea rezervată a parametrului din directiva
page este cuvântul errorPage, scris neapărat cu P mare!
Pagina JSP, care are misiunea de interceptor de erori, va avea obligatoriu atributul
isErrorPage în directiva page. Observaţi maniera de scriere. Primul cuvânt este scris cu
litere mici, urmează apoi cuvinte alipite scrise fiecare cu litere mari. Încă ceva: observaţi
valoarea true, adevărat, în dreapta semnului egal:
<%@ page isErrorPage="true" %>

Deoarece acest element nu poate fi reprezentat, datorită atributului true, JVM preia
tratarea „excepţiei de date” depăşire de valoare la limita inferioară de reprezentare a
numerelor reale, underflow şi implică şi pagina noastră. Remarcaţi insipidul mesaj de
eroare. Între multele sale cuvinte apare şi numeric underflow.

La final de capitol
În acest capitol:
1. Am studiat mecanismul includerii cu ajutorul directivei include file.
2. Apoi a venit rândul lămuririi rostului etichetelor jsp:include şi jsp:forward. Mai
puţin am vorbit despre eticheta jsp:param (vezi şi anexa B).
3. Am enumerat denumirile celor nouă obiecte implicite.
4. Am scos în evidenţă diferenţa dintre un obiect implicit şi unul explicit.
5. Am lămurit ce este instanţierea.
6. Ne-am ocupat de obiectul aplication. Desigur am întâlnit o parte dintre metodele
acestui important obiect.
7. Am scos în evidenţă deosebirea dintre obiectul explicit Date şi obiectul abstract
DateFormat.
8. Ne-am referit apoi la obiectul request şi la unele dintre metodele sale. Ne-am
întâlnit cu „anteturile” protocolului HTTP şi cu o clasă abstractă denumită
Enumeration.
9. Am avut prilejul prezentării conversiei de tip cast.
10. A venit apoi rândul formatelor pentru comentariul din cuprinsul paginilor JSP.
11. A urmat explicarea conceptului de ierarhie a obiectelor şi moştenirea unora
dintre proprietăţile acestora.
12. Şi am încheiat cu prezentarea obiectului exception.
4
Capitolul

Generarea şirurilor de interogare,


a formularelor şi a cadrelor
Ne propunem să vă arătăm cum se pot genera şiruri de interogare. Ne întâlnim
şi cu o aplicaţie mai lungă. Rostul ei este de a înscrie pe vizitatori unui sit.
Înscrierea se face pe bază de formular. Ca să fie mai ergonomic, vizitatorul vede
formularul în cadrul de sus, iar în cadrul de jos apar eventuale mesaje de
eroare, dacă l-a completat greşit. Desigur, în caz de reuşită, va fi înştiinţat despre
o tombola cu premii. Deci vom vedea paginile care administrează aceste două
cadre tip HTML (frames).

Generarea şirurilor de interogare

U
n şir de interogare este un şir de caractere creat şi alipit la adresa în stil URL. El
pleacă la servlet când vizitatorul a selectat acea legătură de tip hypertext.
Probabil că v-aţi întrebat, când aţi colindat situl www.google de pildă, ce sunt
acele şiruri interminabile de caractere, care apar în partea de jos a ferestrei browserului.
Aceasta se întâmplă când punctaţi cu mausul o legătură de tipul hypertext spre o adresă
URL şi, s-a ataşat acesteia un astfel de tren de caractere.
Ei bine, aici vă arătăm cum facem ca să trimitem aceste şiruri de caractere la servlet.
Fireşte, exemplul este doar unul didactic. Iată exerciţiul:
LISTA 4.1 Pagina fruct1.jsp

<html>
<body>
Fructul meu favorit este:
<UL>
<LI><a href="fruct2.jsp?fruct=pepene">pepene</a>
<LI><a href="fruct2.jsp?fruct=struguri">struguri</a>
<LI><a href="fruct2.jsp?fruct=mar">mar</a>
<LI><a href="fruct2.jsp?fruct=mar&fruct=par">mar si par</a>
</UL>
</body>
</html>

Explicaţii şi parafraze
Este o banală pagină HTML. Baliza <UL> anunţă o listă de denumiri. Fiecare element
al listei este marcat prin câte o baliză <LI>. Ceea ce este important urmează acum.
Observaţi că imediat în dreapta balizei <LI> apare baliza <a href=”...”>hot link</a>. Ce
remarcaţi de pildă la legătura:
<LI><a href="fruct2.jsp?fruct=pepene">pepene</a>

Faptul că imediat după jsp urmează semnul întrebării apoi şirul de caractere:
fruct=pepene. Când selectăm cu mausul legătura tip hypertext, în partea de jos apare
acest întreg şir dintre ghilimele, pe care îl vom denumi „specificaţie URL completă”.
Mai observaţi ceva: denumirea servletului care va trata aceste şiruri de interogare este
fruct2.jsp.
Lista acestei pagini este mai jos. Ea recurge la metoda getParameterNames(). Această
metodă întoarce un obiect de tipul Enumeration. Cu acest gen de obiect ne-am întâlnit în
capitolul anterior. Acolo l-am denumit „enumerare”. Nu-i nimic! Aici să îl denumim
„e”. Variabila nume_sir va prelua pe rând denumirile elementelor.
Se spune că se analizează. („parsing”) pas cu pas acest şir de catene
atribut=valoare&atribut=valoare ... .
În cazul de faţă şirul nu a fost format decât dintr-un singură catenă atribut=valoare. În
schimb pentru legătura:
<LI><a href="fruct2.jsp?fruct=mar&fruct=par">mar si par</a>

sunt două catene cuplate prin semnul &. Operatorul & ca notaţie se conservă în multe
limbaje. Este operatorul care serveşte pentru alipirea a doi literali. Este folosit şi în ASP,
nu numai în Java sau JSP. Pe ecran vedem marcat cu altă culoare legătura de tip
hypertext: mar si par. Nu am scris-o cu literele noastre naţionale, deoarece nu am recurs
la pagina de cod ISO-8859-2. Deci paginii fruct2.jsp îi va parveni acum şirul de
interogare:
fruct2.jsp?fruct=mar&fruct=par

Metoda getParameterNames() va detecta aceste două catene, atribut=valoare despărţite


de semnul &.
Masive de date
Ce rost are masivul de date notat aşa: valori[]? El preia valorile catenelor. Masivul va
căpăta din mers dimensiunea doi, când am ales cu mausul legătura „măr şi păr”.
Dimensiunea sa se stabilieşte dinamic. Primul element al masivului valori va conţine
măr iar al doilea, păr.
Cum ştie bucla for să se oprească după cele două elemente în mod automat?
Expresia valori.length() va comunica buclei for să se execute de exact două ori.
Variabila lista_de_valori este o zonă de tip şir (String). Aici se construieşte pas cu pas
un şir de caractere, care constă din aceste valori. Nu se preia fruct=mar, ci numai mar.
Dar după mar apare o virgulă.
Rulaţi şi dumneavoastră acest exerciţiu. Aici nu mai redăm aspectul ferestrei.
LISTA 4.2 Pagina fruct2.jsp

<%@ page import="java.util.Enumeration" %>


<%
for (Enumeration e = request.getParameterNames(); e.hasMoreElements(); )
{
String nume_par = (String) e.nextElement();
String[] valori = request.getParameterValues(nume_par);
String lista_de_valori = valori[0];
for (int i = 1; i < valori.length; i++)
{ //iau la rand valorile din catenele nume = valoare
lista_de_valori += ", " + valori[i];
}
out.println("<br>" + nume_par + " = " + lista_de_valori);
}
%>

Explicaţii şi parafraze
Instrucţiunea out.println() va afişa conţinutul variabilei lista_de_valori.
Ce se întâmplă dacă legătura este formată din mai multe cuvinte. Aceasta dă probleme
unor browsere. MSIE nu are probleme. El substituie fiecare spaţiu dintre cuvinte (cazul
pepene galben) cu câte un semn plus. Netscape Communicator (versiunile mai vechi,
cum este de pildă versiunea a cincea) se opreşte la primul spaţiu.
Ca să nu se întâmple acest lucru, se va apela la metoda encode() a clasei
java.net.URLEncoder. La întâlnirea unor caractere speciale, cum este spaţiul, se produce
o substituire. În locul spaţiului se trimite o secvenţă escape alcătuită din trei caractere şi
anume: % 2 şi 0, deci %20.
Tabelul de mai jos redă o parte din aceste caractere speciale şi ce caractere se trimit
serverului.
TABELUL 4.1 Secvenţe escape ale unor caractere speciale
din specificaţile URL complete

Caracterul special Secvenţa escape Caracterul special Secvenţa escape


Spaţiu %20 sau semnul plus ; %3B
! %21 < %3C
„ %22 = %3D
# %23 > %3E
$ %24 ? %3F
% %25 [ %5B
& %26 \ %5C
( %28 ] %5D
) %29 ^ %5E
Caracterul special Secvenţa escape Caracterul special Secvenţa escape
+ %2B ‘ %60
/ %2F { %7B
: %3A | %7C
; %3B } %7D
< %3C ~ %7E

În continuare, redăm lista integrală a paginii fruct4.jsp.


LISTA 4.3 Pagina fruct4.jsp

<%@ page import="java.net.URLEncoder" %>


<!-- Tratare corecta a valorilor care sunt alcatuite din cuvinte separate prin spatiu -->
<!-- Trebuie daca se executa acest jsp cu Netscape Communicator nu cu MSIE! -->
<html>
<body>
Fructul meu favorit este:
<UL>
<LI><a href='fruct2.jsp?fruct=<%=URLEncoder.encode("pepene
galben")%>'>pepene galben</a>
<LI><a href="fruct2.jsp?fruct=struguri">struguri</a>
<LI><a href="fruct2.jsp?fruct=mar">mar</a>
<LI><a href="fruct2.jsp?fruct=mar&fruct=par">mar si par</a>
</UL>
</body>
</html>

Explicaţii
Ea nu diferă mult de lista anterioară, fruct1.jsp. Singurul element nou este directiva page
unde se importă clasa posesoare a metodei encode şi aplicarea ei doar la prima legătură,
unde apar două cuvinte, pepene galben.
Acum urmează un exerciţiu mai lung.

Generarea unui formular şi a cadrelor


Să ne ocupăm de crearea unui sit denumit MyPisi.com. Acesta înscrie vizitatori pe baza
completării unui formular. Fereastra documentului este împărţită în două cadre (frames).
Cadrul superior afişează formularul unde vizitatorul îşi înscrie datele sale personale. El
va participa la o tombolă cu premii. Ca atare, trebuie să completeze neapărat rubricile
(câmpurile) acestui formular. Răspunsurile nu sunt memorate în vreo bază de date ci,
sunt afişate în cadrul situat în partea de jos a ferestrei documentului. Aspectul ferestrei îl
vedeţi în figura 4.1a. Am mers pe aceast compromis ca să nu complicăm lucrurile şi aşa
complicate!
Se poate observa că vizitatorul a uitat să completeze unele rubrici obligatorii. Ca atare,
va fi înştinţat prin mesaje adecvate în cadrul de jos. Tot în acest cadru, vizitatorul va fi
înştiinţat de răspunsurile date, ce vor fi luate în considerare la tombolă. Fireşte, nu a fost
vizibil întregul formular în această figură ca şi mesajele din cadrul din partea de jos.
Situl este alcătuit din trei pagini JSP: una pentru crearea celor două cadre, denumită
mypisi.jsp, una denumită mypisi_formular.jsp. Ea afişează formularul. Ultima listă,
mypisi_raspunsuri.jsp, conţine eventualele mesaje prin care se atrage atenţia
vizitatorului că nu a completat unele rubrici. Dar tot în acest fişier se tratează şi cazul
când el a completat corect formularul. Doar prima listă este redată complet. Celelalte
fişiere fiind lungi, le-am prezentat doar parţial.

FIGURA 4.1a Aspectul ferestrei sitului MyPisi.com

Aşadar iată prima listă:


LISTA 4.4a Pagina mypisi.jsp

<HTML>
<HEAD>
<TITLE>mypisi.com - Versiunea cu cadre</TITLE>
</HEAD>

<FRAMESET ROWS="300,*" BORDER="Yes">


<FRAME NAME="form" SRC="mypisi_formular.jsp" SCROLLING="Auto"
FRAMEBORDER="yes">
<FRAME NAME="results" SRC="mypisi_raspunsuri.jsp" SCROLLING="Auto"
FRAMEBORDER="No">
</FRAMESET>
</HTML>

Explicaţii şi parafraze
Distingem titlul ferestrei documentului. Prin baliza <FRAMESET> anunţăm că sunt
două cadre. Primul este tratat de fişierul mypisi_formular.jsp, iar cadrul de jos, de către
mypisi_raspunsuri.jsp. Ambele cadre vor afişa automat barete de defilare (scroll), dacă
dimensiunea cadrului va fi mai mare decât porţiunea din ecran destinată ferestrei
respective. Cadrul superior are chenar, celălalt de jos, nu.
Trecem la lista mypisi_formular.jsp al cărui conţinut îl redăm pe parcurs.
Formularul este anunţat aşa :
<FORM NAME='form1' ACTION='mypisi_raspunsuri.jsp' TARGET='results'
METHOD='POST'>

El are denumirea logică form1. În atributul ACTION este menţionat servletul. El va


analiza valorile completate de vizitator. S-a recurs la metoda de tratare POST. Metoda
adaugă specificaţiei URL imediat după semnul „?”, catene unite prin caracterul &. O
catenă arată aşa:
denumire_logică_de_câmp = valoare

Priviţi figura. În partea de deasupra este redată efigia sitului. Ea este aşezată centrat. De
aceea se recurge la baliza <DIV>. Poza ocupă o zonă de 200 pe 80 pixeli. În caz că
browserul client nu o poate reda, el fiind unul de tipul negrafic sau, poate vizitatorul i-a
dezactivat facilitatea de redare grafică, atunci va apărea mesajul „genericul sitului”.
<DIV ALIGN="center">
<IMG SRC="images/peisaj.jpg" WIDTH="200" HEIGHT="80" ALT="[genericul
sitului]" BORDER="0">
</DIV>

Câmpurile sunt: unul nevizualizat aici (tipul hidden), al doilea, numele de familie, apoi
prenumele participantului, mai departe codul său numeric personal, sexul, adresa sa de
e-mail, cele două parole ale căsuţei poştale, un mic loc rezervat unui răspuns al
vizitatorului ce va face cu PC-ul câştigat. Iată partea a întâia a formularului:
LISTA 4.4b Partea a întâia a formularului, pagina mypisi_formular.jsp

<TABLE CELLPADDING=3 CELLSPACING=0 BORDER=0 WIDTH=600>


<THEAD>
<TH COLSPAN=2>Va multumesc ca vizitati situl MyPisi.com unde veti
completa datele ca sa participati la urmatoarea tombola cu premii. Mult
noroc!<P></P>
</TH>
</THEAD>
<TR>
<TD>Numele de familie:</TD>
<TD><INPUT TYPE='text' NAME='nume' VALUE=''></TD>
</TR>

<TR>
<TD>Si codul numeric personal al dvs.:</TD>
<TD><INPUT TYPE='text' NAME='cnp' VALUE=''></TD>
</TR>
<TR>
<TD>Sexul:</TD>
<TD><INPUT TYPE='radio' NAME='sex' VALUE='masc'>masc &nbsp;
<INPUT TYPE='radio' NAME='sex' VALUE='fem'>fem
</TD>
</TR>
<TR>
<TD>Email:</TD>
<TD><INPUT TYPE='text' NAME='email' VALUE='”></TD>
</TR>

Explicaţii şi parafraze
Tabloul nu are chenar (BORDER=0) are 600 pixeli lăţime şi un antet. Atributele NAME
conţin denumirile logice ale fiecărei rubrici.
Codul numeric personal (cnp) va fi verificat şi trebuie să aibă neapărat cele 13 cifre.
Majoritatea rubricilor sunt de tip text, fără o valoare anume preafişată.
Rubrica sex este de tipul buton radio (vezi anexa A) şi are două opţiuni. Nici una dintre
acestea nu este selectată de la început. În schimb, opţiunile au denumirile logice masc şi
respectiv fem. Lângă aceste opţiuni este desenat câte un cerculeţ (de unde şi denumirea
de „radiobutton”). Observaţi prescurtările masc şi respectiv fem, din faţa cerculeţelor.
Următoare rubrică se referă la adresa de e-mail. Servletul va verifica formatul uzual al
căsuţei poştale. Căsuţa se cere a fi completată, deoarece utilizatorul va opta sau nu
pentru trimiterea mesajelor cu caracter promoţional sau, pur şi simplu pentru a fi
înştiinţat că a câştigat PC-ul la tombolă!
Urmează două câmpuri, fiecare cu regim de parolă (password). Este parola căsuţei
poştale. Tot ce tastaţi aici va fi afişat prin asteriscuri.
Acum să privim partea a doua a formularului. Pe aceasta o reproducem integral.
LISTA 4.4c Partea a doua a formularului, fişierul mypisi_formular.jsp

<TR>
<TD>Ce veti face cu PC-ul daca il castigati?</TD>
<TD><TEXTAREA NAME='destinat' VALUE='raspundeti' COLS=30
ROWS=5></TEXTAREA></TD>
</TR>
<TR>
<TD COLSPAN=2><INPUT TYPE='checkbox'
NAME='send_promo'><B>Da, as
dori sa imi trimteti mesaje promotionale prin email!</B>
</TD>
</TR>
<TR>
<TD ALIGN='center'>
<INPUT TYPE='reset' VALUE='Sterg formular'>
</TD>
<TD ALIGN='center'><INPUT TYPE='image' SRC='images/letmewin.jpg'
HEIGTH='300' WIDTH='120' BORDER=0></TD>
</TR>
</TABLE>
</FORM>
Explicaţii şi parafraze
Distingem câmpul HTML de tipul textarea. Aici vizitatorul va răspunde eventual la
întrebarea pusă. Este primul dintre câmpurile opţionale.
Următorul câmp, tot opţional, are denumirea logică send_promo. Are tipul casetei de
bifare, checkbox. Ocupă ambele coloane ale tabelului (COLSPAN=2). Aici vizitatorul
optează între a primi sau refuza mesajele promoţionale.
Ultimele resurse grafice ale formularului sunt: un buton tip reset, pentru ştergerea
rubricilor formularului. Al doilea nu este un buton tip submit ci o poză. De regulă ştiaţi
că prin clic pe un buton de tipul submit se trimit datele formularului (deci şirul de
interogare) la serverul Web. Ei bine, aici am renunţat aparent la un astfel de buton. Fiind
însă ultima resursă a formularului, va fi considerată automat buton de tip submit! Sigla
este denumită letmewin.jpg şi se află în directorul images. Acest subdirector este fiul
directorului ce găzduieşte cele trei pagini ale sitului. Sigla este centrată şi are 300 pe 120
pixeli. Nu este afişată în chenar (BORDER=0).
Să ne ocupăm şi de scriptletul unde apare codul pur Java. Acesta este conţinut în fişierul
mypisi_raspunsuri.jsp. Iată-l:
Lista 4.5a. Prima parte a listei servletului mypisi_raspunsuri.jsp

<%
String afisareContinut = "";
String mesajEroare = "";
boolean bSucces = false; // in caz de reusita a completarii formularului
String vizitator = getValues( request, "vizitator" );
String nume = getValues( request, "nume" );

String cnp = getValues( request, "cnp" );
String sex = getValues( request, "sex" );
String email = getValues( request, "email" );

String cuvant_secret_confirm = getValues( request, "cuvant_secret_confirm" );
String destinat = getValues( request, "destinat" );

Explicaţii şi parafraze
Mai sus declarăm două variabile de tip şir afisareContinut şi respectiv mesajEroare.
Fiecare din ele nu conţin nici un caracter la început. Variabila bSucces are tipul logic.
Remarcaţi convenţia de notaţie şi anume litera b, de la boolean, chiar în faţa denumirii.
Bineînţeles că nu acest b conferă acestei variabile tipul logic ci, cuvântul cheie boolean.
Variabila este poziţionată iniţial pe valoarea logică „false”.
Urmează o serie de declaraţii de variabile de tip şir. Remarcaţi coincidenţa denumirilor
acestor variabile cu denumirile logice ale câmpurilor formularului atât cât au fost
ilustrate în listele de mai sus. Ceea ce a completat vizitatorul în fiecare rubrică este
preluat de metoda getValues(). Aceasta are un scop extrem de ergonomic şi anume,
menţine permanent pe ecran răspunsurile deja date, neobligând pe vizitator ca să
recompleteze tot formularul de la început, dacă a greşit sau a uitat un câmp obligatoriu.
În continuare, redăm lista cu partea de prelucrare pas cu pas a valorilor preluate din
rubricile formularului. Iat-o:
LISTA 4.5b Partea a doua a paginii mypisi_raspunsuri.jsp
// Prelucrare valori ale campurilor ajumse la server
if( "POST".equals(request.getMethod()) ) {

// Realizeaza validarea campurilor


if( nume.equals("") ) {
mesajEroare += "<LI>Trebuie sa specificati numele dvs. de familie.!";
}

if( cnp.equals("") ) {
mesajEroare += "<LI>Trebuie sa specificati codul numeric personal!";
}
if( cnp.length()!= 13 ) {
mesajEroare += "<LI>Codul numeric personal obligatoriu are 13 cifre!";
}

if( email.equals("") ) {
mesajEroare += "<LI>Trebuie sa specificati numele casuta dvs. de email.";
// email prezent, dar e necesar sa vad daca nu ati pierdut pe drum caracterul @
} else {
int atPos = email.indexOf('@');
// Format gresit daca nu-s '@' + '.' dupa semnul '@'
if( atPos == -1 || email.indexOf('.',atPos+2) == -1 ) {
mesajEroare += "<LI>Va rog o adresa corecta de email!";
}
}
if( cuvant_secret.equals("") ) {
mesajEroare += "<LI>Trebuie neaparat parola dvs.!";
}

if(!cuvant_secret.equals(cuvant_secret_confirm) ) {
mesajEroare += "<LI>Trebuie NEAPARAT ca parolele sa se potriveasca!";
}

// Exista cel putin un mesaj eronat, le adaug la antet spre a le anunta vizitatorului
if(!mesajEroare.equals("") ) {
mesajEroare = "<P>Va rugam corectati urmatoarele erori ca sa puteti participa la
concurs cu PC-ul castigator</P>" + mesajEroare;
} else {
// Fara erori, seteaza flagul ca sa afisezi raspunsurile date de vizitator
bSucces=true;
afisareContinut = "… +
"<BR><B>Numele de familie:</B> " + nume +

"<BR><B>Email:</B> " + email +
"<BR><B>Parola:</B> (nu putem reda parola introdusa pentru motive de
secu., dar s-ar putea sa fie blah" + cuvant_secret + "blah)" +

"<BR><B>Sa va trimitem mesaje promotionale:</B> " + send_promo;
}
} // if POST
%>
Explicaţii şi parafraze
Mai întâi prin instrucţiunea
if( "POST".equals(request.getMethod()) ) {

ne asigurăm că metoda de transmitere folosită este metoda POST.


Apoi vedem dacă a rămasă necompletată vreo rubrică. În caz afirmativ, variabila
mesajEroare va alipi mesajul adecvat la alte mesaje deja înscrise în aceasta.
Remarcaţi ceva la instrucţiunile care se ocupă de rubrica cnp. Se verifică lungimea
şirului cnp prin metoda length(). În caz că nu s-au introdus exact 13 caractere, se alipeşte
în mesajEroare mesajul: „Codul numeric personal obligatoriu are 13 cifre!”.
Acum să ne concentrăm atenţia asupra câmpului relativ la căsuţa poştală. Cu funcţia
indexOf(), se caută caracterul „@” din şir. El trebuie ca să fie neapărat prezent, altfel
variabila atPos va conţine valoarea -1. Se mai verifică tot cu aceiaşi metodă prezenţa a
cel puţin unui punct în şirul adresei. Atât indexOf() cât şi length() aparţin clasei String.
Deci formatul adresei căsuţei poştale ar trebui să fie cel puţin aşa:
nume@domeniu.server
Instrucţiunea:
if(!cuvant_secret.equals(cuvant_secret_confirm) ) {
mesajEroare += "<LI>Trebuie NEAPARAT ca parolele sa se potriveasca!";

are menirea de a vedea dacă cele două câmpuri au acelaşi conţinut. În caz contrar,
variabila mesajEroare va prelua mesajul.
Prin intrucţiunile:
if( ! mesajEroare.equals("") ) {
mesajEroare = "<P>Va rugam corectati urmatoarele erori ca sa puteti participa la
concurs cu PC-ul castigator</P>" + mesajEroare;

analizăm dacă variabila mesajEroare a rămas vidă, deci vizitatorul nu a completat greşit
formularul. Semnul mirării situat în faţa denumirii spune acest lucru: dacă variabila
mesajEroare nu este vidă, deci există mesaje de eroare aici, se va afişa „Va rugam
corectati urmatoarele erori ca sa puteti participa la … “ urmat de mesajele acumulate în
variabila mesajEroare. În cazul că variabila mesajEroare este vidă, deci formularul e
completat fără greşeală, bSucces va primi valoarea logică adevărat. În acest caz, în
variabila afisareContinut vor apare toate răspunsurile date de vizitator (ca în figura
4.1b).
Să urmărim acum partea a treia a listei fişierului mypisi_raspunsuri.jsp:
LISTA 4.5c Partea a treia a paginii mypisi_raspunsuri.jsp

01. <HTML>
02. <HEAD>
03. <TITLE>My Pisi Paradise!</TITLE>
04. <STYLE>
05. …
06. </STYLE>
07. </HEAD>
08. <BODY>
09. <%// Afiseaza mesaj de eroare daca bSucces e nul, deci ceva e in
neregula
10. if(!bSucces ) { %>
11. <TABLE CELLPADDING=3 CELLSPACING=0 BORDER=0 WIDTH=600>
12. <TR><TD CLASS='red' COLSPAN=2><%=mesajEroare %></TD></TR>
13. </TABLE>
14. <%// Altfel afiseaza raspunsurile
15. } else { %>
16. <H3>Va multumim pentru ca ati avut rabdare sa completati formularul cu
informatie! Fiti pe faza! Redam raspunsurile date de dumneavoastra.</H3>
17. <%=afisareContinut %>
18. <% } // if!bSucces%>
19. </BODY>
20. </HTML>

Explicaţii şi parafraze
Ce remarcaţi mai sus? Mai întâi marcajele unei foi de stiluri (liniile 04 şi 06) pe care nu
o mai redăm. Apoi faptul că inspectăm variabila bSucces (linia 10). Dacă formularul a
fost corect completat, bSucces va avea valoarea true. Deci nu se va afişa partea cu datele
de eroare ci acel text plasat între balizele <H3> ... </H3> (linia 16). După aceea ar urma
să înştiinţăm pe vizitator despre datele concrete referitoare la tombolă. Aceasta o facem
referindu-ne la afisareContinut (linia 18).

Limbajul Java … amar precum cafeaua!


Acum a venit şi rândul prezentării metodei getValues(), redată în ultima parte a paginii
mypisi_raspunsuri.jsp:
LISTA 4.5d Ultima parte a paginii mypisi_raspunsuri.jsp,
metoda getValues() – redată parţial

<%!
// Folosesc o metoda de convenienta in loc sa tot initializez valoarea asumata cu ""
de fiecare data
public String getValues( HttpServletRequest request, String nume )
{
return getValues( request, nume, "" );
}

public String getValues( HttpServletRequest request, String nume, String


defaultValue )
{
String val_de_retur = defaultValue;
String valori[] = request.getParameterValues( nume );
// Nici o valoare nu a fost furnizata
if( valori == null ) {
// Nu faci decat sa preiei valoarea asumata a variabilei
val_de_retur
// Furnizata numai o valoare
} else if( valori.length == 1) {
val_de_retur = valori[0].trim();

}
return val_de_retur;
}
%>

Explicaţii şi parafraze
Aparent, observaţi două şabloane ale metodei getValues(). Primul şablon are o listă cu
două argumente fictive, în timp ce al doilea, o listă cu trei argumente fictive! Nu este
nici o diferenţă între exprimarea „argument fictiv” şi „parametru fictiv”! Acestui şablon,
programatorul Java îi spune în engleză „method signature”, semnătura metodei!
Metoda este publică, adică este accesibilă din exteriorul fişierului, dovadă prezenţa
cuvântului cheie public din fiecare şablon. Metoda întoarce un rezultat de tipul şir de
caractere (String). Imediat după denumirea metodei, urmează lista de parametri fictivi.
Primul este obiectul denumit request. I-am lăsat denumirea neschimbată în engleză.
Puteam să îl denumim şi altfel! Obiectul aparţine clasei HttpServletRequest. Întrucât am
redat parţial această listă, trebuie să ne justificăm cu o explicaţie totuşi clară!
Dacă aţi instalat un motor servlet, atunci în cadrul maşinii virtuale Java instalate odată
cu J2SE, va fi adăugat un grup suplimentar de clase. Acestea se ocupă de protocoalele
transport. Există o clasa generală a servleturilor denumită GenericServlet. Ea este
destinată servleturilor care nu recurg la un anume protocol. În cazul de faţă este folosit
protocolul http. Vă reamintim că la acest exemplu, indiferent motorul folosit (Resin,
Jrun au altul), specificaţia URL începe mereu cu http://...
Această clasă generică GenericServlet are drept fiu clasa HttpServlet. La rându-i, ea
foloseşte două obiecte implicite, cerere, deci request, şi răspuns, response. În exemplul
de faţă nu avem nevoie decât să preluăm datele completate de vizitator, deci cererea sa.
Metoda getValues() mai are un al doilea parametru fictiv denumit nume. De pildă,
remarcaţi linia:
String cnp = getValues( request, "cnp" );

din lista 4.5a. Se apelează metoda getValues() prin şablonul cu doi parametri fictivi,
specificând că ne trebuie doar câmpul cu denumirea cnp.
În momentul apelului se intră în primul grup de acolade, unde există o singură
instrucţiune:
return getValues( request, nume, "" );

De fapt apelăm metoda getValues() pentru trei parametri fictivi. Este adevărat că se
execută o instrucţiune return. După cuvântul return ar trebui să urmeze eventual un
nume de variabilă. În locul lui, ne-am referit direct la rezultatul întors de către metoda cu
trei parametri.
Acum în ce constă trucul! Al treilea parametru fictiv primeşte valoarea “”. Deci de fapt
înscriem un şir vid în rubrică, adică ştergem rubrica. Ce face acum servletul? El se
pregăteşte pentru primirea unui alt conţinut, înscris de vizitator. În acest timp,
formularul e permanent afişat. Umple, schimbă conţinutul rubricilor până la apăsarea
tastei Enter.
Când apasă această tastă (acţiunea echivalează cu trimiterea înapoi la serverul Web a
noilor valori), la servlet soseşte un nou şir de interogare cu conţinutul cel nou. Când se
execută instrucţiunea:
String cnp = getValues( request, "cnp" );

metoda getValues() îşi face datoria în mod docil!


Să pătrundem în corpul metodei cu trei parametri fictivi. Primul lucru pe care îl face,
este să atribuie variabilei val_de_retur valoarea parametrului fictiv, defaultValue. Dar în
variabila defaultValue s-a încărcat şirul vid. Apoi se preia conţinutul prin intermediul
metodei getParameterValues().
Când vizitatorul apasă pe tasta Enter, se trimit absolut toate valorile câmpurilor
formularului, nu numai cel al cnp! Deci sosesc la servlet atât valorile deja introduse cât
şi cele abia modificate şi, desigur chiar şi cele încă neintroduse! Cum aşa? Da!
Vizitatorul s-a grăbit, nu a mai completat tot formularul, şi a apăsat pe Enter. În stânga
semnului egal al instrucţiunii:
String valori[] = request.getParameterValues( nume );

se aşteaptă un masiv denumit „valori” datorită metodei getParameterValues(), care


întoarce o adresă la o zonă unde vor fi înscrise conţinuturile rubricilor formularului.
Observaţi cele două paranteze drepte, imediat după denumirea masivului. Aceasta spune
că variabila valori este un masiv. Programatorii spun variabilelor simple variabile
scalare. La început masivul nu are nici un element. Fiindcă în faţa denumirii valorii
apare cuvântul cheie String, va avea tipul şir de caractere.
Ce se întâmplă dacă o rubrică ar conţine mai multe cuvinte spearate prin spaţii? De
pildă, câmpul unde se răspunde ce va face în caz că a câştigat. La momentul trimiterii
cuvintelor, se produce o transliterare. În locul spaţiilor apar semne plus între cuvinte.
În rubrica „Ce veţi face cu … “ vizitatorul a răspuns cu „nu stiu”. La server se trimite
fluxul nu%2Bstiu. Conform tabelului 4.1, %2B este atribuit semnului plus. Unde a
dispărut el dintre cuvintele „nu” şi „stiu” ? MSIE l-a eliminat mai înainte de a se reda
valoarea acestui câmp.
Desigur, în cazul celorlalte câmpuri conţinutul este alcătuit dintr-un singur cuvânt. Poate
doar câmpul prenumelui să aibă mai multe cuvinte. Din listă am eliminat o parte a
codului sursă spre a nu complica lucrurile.
FIGURA 4.1b Aspectul ferestrei sitului MyPisi.com

La final de capitol
Aici ne-am ocupat de metodele care ajută la analizarea şirurilor de caractere de
interogare. Ne-am ocupat de metoda getParameterNames() a obiectului request, apoi de
metoda length() obiectului String.
A venit apoi rândul tratării corecte a şirurilor unde se recurge la caractere neacceptate de
unele browsere, acele secvenţe escape, pentru care am redat şi un tabel.
În încheiere am tratat cazul unui sit unde se culeg date prin intermediul unui formular.
Să recunoaştem că în cazul acestui exerciţiu mai complicat v-aţi dat seama că trebuie să
revizuiţi puţin HTML-ul! Şi aici am abordat o serie de metode cum sunt: equals(),
indexOf(), ambele ale clasei String.
Am abordat frontal codul sursă Java al unei metode care nu aparţine vreunui pachet
java. Metoda se numeşte getValues(). A fost unul din puţinele prilejuri de întâlnire cu
limbajul Java! V-am arătat cod Java, v-am explicat destule despre el, dar nu vă cerem a
învăţa acest limbaj insipid ci numai să recunpaşteţi că aceasta este o scriere sintactică
Java!
5
Capitolul

Accesul la bazele de date, clasele


de tip Java beans
După unii bean s-ar traduce prin boabă de cafea! Răposatul profesor Leon
Leviţchi este mai puţin … cosmopolit! În dicţionarul apărut sub îndrumarea sa,
bean înseamnă fasole, bob, dovleac, bostan, în nici un caz bob de cafea.
Vom descrie o aplicaţie Java bazată pe cadrul de lucru J2SE. Am creat baza de
date cu MS Access. Ca atare am fost nevoiţi să recurgem la un program de
comandă (driver) pus la dispoziţie pentru accesul la structuri tip .mdb. Este
driverul de tip punte JDBC:ODBC al corporaţiei Sun Microsystems din J2SE.
El serveşte la accesul o bază de date a platformei ODBC, dar are unele
probleme! Aşa ne explicăm de ce au apărut destule firme, care oferă câte un
astfel de driver tip punte şi care în mod precis că nu au anomalii. De aceea au şi
regimul shareware. J2SE este freeware.
Tot în acest capitol vom arăta că sunt şi alte tipuri de drivere pentru accesul la
baze de date venind dinspre platforma Java. O parte din aplicaţia descrisă aici
conţine şi o clasă pregătită conform tipicului Java beans. Nu vom aminti decât
tangenţial acest tipic.

A
şadar bazele de date sunt surse de date din punct de vedere logic. Ne aflăm în
platforma Java, iar drumul până la platforma Windows este lung! Există multe
structuri de date; unele fac parte din ODBC, altele din OLE DB etc. ODBC
vizeză conectarea la structuri de date tip Asthon Tate dBase, FoxPro, Visual FoxPro,
Borland Paradox Microsoft Access, etc. ODBC înseamnă Object DataBase
Connectivity, deci conectare deschisă spre structurile de baze de date Windows (vezi
partea a treia a referinţei /1/). Auziţi pe un specialişti exprimându-se: „ODBC Data
Sources” sau şi mai ermetic surse de date ODBC!
Dinspre platforma Java spre platforma ODBC se ajunge în vreo patru moduri de acces.
Cel mai ieftin dar şi mai lent mod este cel realizat prin intermediul unui program de
comandă (driver) dezvoltat de către corporaţia Sun Microsystems. Driverul este o punte
de legătură, care comunică cu un alt conector (driver) din platforma Windows. În
engleză această piesă software se cheamă „JDBC:ODBC bridge”.

Puţin despre modelele de acces JDBC


JDBC înseamnă Java DataBase Connectivity, cenctare la baze de date dinspre java. Aşa
cum afirmam adineaori, cel mai lent este driverul de tip punte. Driverul face parte din
cadrul de lucru J2SE. Figura de mai jos redă locul acestei punţi între cele două platforme
ODBC-Windows pe de o parte, şi maşina virtuală Java, pe de alta.
Servletul lansează o comandă de interogare a bazei de date, cu respectarea regulilor
sintactice ale limbajului pentru interogare de tip structurat, Structured Query Language,
repesctând în acelaşi timp şi sintaxa limbajului Java. Deoarece nu vă redăm listele scrise
în cod Java, nu avem cum a vă demonstra că aşa este.

FIGURA 5.1 Modelul de acces la baze de date tip JDBC:ODBC (după referinţa /4/)

Cele două drivere, puntea JDBC:ODBC pe de o parte, şi driverul propriu-zis ODBC pe


de alta, au fiecare sarcini bine stabilite. De la clientul Web se emite cererea. De pildă,
vrem să aflăm toţi cumpărătorii unui magazin virtual, de la litera H. Cererea vine la
servlet. Se interoghează o bază de date MS Access.
În altă ordine de idei, o bază de date este alcătuită dintr-unul sau mai multe tabele. Din
aceste tabele se obţine rezultatul care ne interesează. El are forma tot a unui tabel cu
coloanele: numele şi prenumele vizitatorului. Tabelul aşa cum soseşte de la MSAccess
nu ar putea fi redat direct în fereastra documentului HTML. În consecinţă, prin
intermediul aceluaşi server ce cooperează cu driverele amintite mai sus este adus la
forma familiară limbajului HTML.
Mai există şi alte trei tipuri de modele de acces la bazele de date. Cel mai scump este
acela care asigură accesul direct la structura bazei de date. I se spune în engleză Native
Protocol Pure Java. Evident acest tip de driver costă bani! În schimb, el măreşte în mod
dramatic viteza de răspuns şi merge şi bine (vezi /4/ şi http://www.easysoft.com).

Prezentarea paginilor aplicaţiei


Ne-am gândit să dezvoltăm o aplicaţie cât mai simplă, deoarece driverul JDBC:ODBC
de tip punte din J2SE nu a funcţionat bine, cel puţin în contextul sistemului Windows
2000 Professional! Multe firme oferă în regimul shareware un driver tip punte dar şi
altele evoluate. Nu am testat oferta firmei EasySoft, una dintre multele firme, fiindcă nu
am mai descărcat produsul!
Înţelegem politica celor de la Sun Microsystems, când suportul Entreprise Java Beans,
este cumpărat de manageri cu … stare! Este normal ca aceste piese software să fie
impecabil puse la punct! Nu avem nici o pretenţie!
Am scris o aplicaţie bazată pe un formular cu doar trei câmpuri: numele vizitatorului,
prenumele său şi codul său numeric personal. Aceste trei rubrici alcătuiesc şi câmpurile
unei tabele denumite visitors a bazei de date mydb.mdb. Ca suport pentru baze de date
am ales aplicaţia MS Access.
Observaţie: Trebuie spus că un sit comercial accesat de mai mult de 30 utilizatori, pierde
în viteză în mod dramatic dacă s-a bazat pe MS Access şi nu pe MS SQL Server!
Şi aşa simplă, aplicaţia a avut nevoie de o clasă tip Java Bean, a cărei listă nu a fost
prezentată din motive de lungime.
Închipuiţi-vă această clasă ca pe o „cochilie”. La variabilele clasei tip Bean nu avem
acces direct, ele fiind de tip privat. În schimb avem acces la proprietăţile (metodele) ei,
prin intermediul unor etichete JSP. Reluăm ideea mai jos, după terminarea prezentării
acestei aplicaţii. Veţi observa eticheta jsp:useBean în multe din paginile aplicaţiei.
Toate fişierele cu sufixul .jsp ce aparţin acestei aplicaţii vor aparţine de directorul:
<HOME_Resin>/mydb.
Clasa tip Bean va fi stocată într-un alt director, şi anume:
<HOME_Resin>/mydb/WEB-INF/classes/jsp.
De ce aici şi nu altundeva? Pentru că orice container servlet/JSP respectă convenţia de
amplasare a fişierelor unei aplicaţii complexe din platforma Java într-o ierarhie care are
un anumit tipic. Despre acest tipic nu avem de gând să vă vorbim. Pentru a nu face
urmărirea prea greoaie, am considerat oportun să evităm explicarea fişierului descriptor
al unei atari ierarhii, intitulat web.xml, care cere cunoaşterea XML şi, care este amplasat
conform aceluiaşi standard în directorul:
<HOME_Resin>/mydb/WEB-INF.
Creăm deci cu MS Access o bază de date denumită mydb.mdb. Procedeul este acesta:
1. Activăm aplicaţia MS Access (Start Æ Programs Æ MS Access).
2. Din caseta de dialog alegem opţiunea pentru crearea unei noi baze
de date, Blank Database.
3. Apare caseta denumită fişier nou de tip bază de date, File New DataBase. Aici
precizăm la nume fişier, File name, denumirea bazei: mydb. Denumirea are
automat extensia .mdb. Alegem directorul unde dorim ca să o salvăm. Fie el:
<HOME_Resin>/mydb. Numele acestui director cât şi cel al bazei de date nu
trebuie să vă conducă la confuzie. Sunt două lucruri absolut distincte!
4. Acţionăm butonul Create.
5. Apare o altă casetă de dialog, de unde se alege prima opţiune, creare tabel în
modul de proiectare vedere a structurii, Create Table in Design View. În fapt
vom crea un tabel pe care îl vom denumi în final visitors.

FIGURA 5.2 Aspectul ferestrei de creare a unui tabel cu MS Access

6. Înscriem cele trei câmpuri cnp, nume şi prenume în această ordine. Câmpul cnp
va fi de tipul text şi va avea 13 poziţii. Va servi drept cheie primară. Orice tabel
trebuie să aibă un câmp de indexare. El va conţine cheia primară, fiindcă după
ea se face sortarea sau indexarea. Celelalte două câmpuri, nume şi prenume, vor
fi tot de tipul text şi vor avea câte 20 caractere. Întrucât operarea este extrem de
intuitivă, nu mai redăm acest procedeu. Aspectul structurii este cel din figura
5.3
FIGURA 5.3 Aspectul structurii tabelului visitors

FIGURA 5.4 aspectul casetei de dialog Data Sources (ODBC)

Indiferent că folosim doar driverul ODBC din platforma Microsoft, trebuie să anunţăm
acest driver că va avea acces la o „sursă de date”. Denumirea sursei nu va fi mydb.mdb
ci myVisitors. Pentru aceasta iată procedeul:
7. Dacă folosim sistemul Windows 2000 Professional, activăm Data Sources
(ODBC). Traseul este: Start Æ Settings Æ Control Panel Æ Administrativ
Tools Æ Data Sources (ODBC). Dacă folosim varianta Windows 98, traseul va
fi altul: Start Æ Programs Æ Control Panel Æ ODBC Data Sources. Apare o
casetă complexă, similară cu aceea din figura 5.4. În această figură însă apare
deja dnumirea logică a sursei de date mydb.mdb. Observaţi că ea se numeşte
myVisitors şi este de tip utilizator (user) nu de tipul sistem (system). Nu
divagăm! Închipuiţi-vă că nu este iniţial. Revenind la procedura în sine.
8. Ni se cere denumirea sursei de date. Precizăm de la claviatură denumirea
myVisitors. O scriem exact aşa. Dacă am scrie codul clasei Java bean, am vedea
că exact aşa o menţionăm!
9. Apoi selectăm un driver de tip Microsoft Access (*.mdb).
10. Mai departe, prin clic pe butonul Finish, apare o ultimă casetă denumită
Database. Aici selectăm fişierul cu extensia .mdb. El se află într-un alt director
decât cel afişat iniţial în casetă.
11. Pentru aceasta călătorim, cu butonul browse, în directorul unde se află baza şi,
prin clic pe denumirea ei am terminat procedura.
Am adus la cunoştinţa driverului ODBC că sursa de date myVisitors este asociată
fişierului mydb.mdb.
Redăm integral pagina de bază denumită mydb.jsp, ca de altfel toate fişierele .jsp ale
acestei aplicaţii cu excepţia clasei bean. Nu am vrut a o denumi index.jsp, deşi puteam
foarte bine să îi spunem şi aşa! Pentru uşurarea urmării explicaţiilor am preferat
numeroatarea liniilor.
Lista 5.1 Pagina principală mydb.jsp

01. <%-- mydb.jsp --%>


02. <%@ page language="java" import="java.sql.*, java.io.*, java.util.*"
errorPage="eroare.jsp" %>
03. <jsp:useBean id="bd" scope="session" class="jsp.DBBean"/>
04. <html>
05. <body>
06. <h3 align="center">Lucru cu baza de date mydb</h3>
07. <form action="purgeDB.jsp" method="post">
08. <br>Pentru eliminarea tuturor vizitatorilor din tabelul visitor, BD mydb, clic pe
<b>Golesc tabel</b>.</td>
09. <table border="0" bgcolor="#FFFFAA">
10. <th>Codul numeric personal</th>
11. <th>Numele</th>
12. <th>Prenumele</th>
13. <th><input type="submit" value="Golesc tabel"></th>
14. <%
15. bd.connect();
16. ResultSet rs = bd.viewVisitors();
17. while (rs.next()) {
18. %>
19. <tr>
20. <td><input name="cnp" value="<%= rs.getString("cnp") %>"></td>
21. <td><input name="nume" value="<%= rs.getString("nume") %>"></td>
22. <td><input name="prenume" value="<%= rs.getString("prenume") %>"></td>
23. </tr>
24. <% }
25. %>
26. </table>
27. </form>
28. <% bd.disconnect(); %>
29. <hr>
30. <form action="refillDB.jsp" method="post">
31. <table border="0">
32. <tr>
33. <td>Pentru reumplerea tabelului din BD mydb, clic pe <b>Reincarc
tabel</b>.</td>
34. <td><input type="submit" value="Reincarc tabel"></td>
35. </tr>
36. </table>
37. </form>
38. <form action="delrec.jsp" method="post">
39. <table border="0">
40. <tr>
41. <td>Ca sa elimini vizitatorul, precizezi codul numeric personal, si clic pe
<b>Elimin vizitator</b>.</td>
42. <td><input name="cnp_anume"></td>
43. <td><input type="submit" value="Elimin vizitator"></td>
44. </tr>
45. </table>
46. </form>
47. <form action="addvisitor.jsp" method="post">
48. <table border="0">
49. <tr>
50. <td>Ca sa adaugi un vizitator, clic pe <b>Adaug vizitator</B>.</td>
51. <td><input type="submit" value="Adaug vizitator"></td>
52. </tr>
53. </table>
54. </form>
55. </body>
56. </html>

Explicaţii şi parafraze
Este o listă lungă şi plină de noutăţi! Să o luăm sistematic. Prima linie este un
comentariu unde menţionăm denumirea paginii. Acesta putea fi desigur continuat cu
intrări pentru: autor, data creării, numărul versiunii, data penultimei modificări sau pur şi
simplu toate modificările realizate de la începutul creării acestui program, dar ar fi lungit
lista.
Următoarea linie este una ştiută. Anunţăm cu directiva page ce pachete vor fi importate.
Dar mai apare ceva şi anume atributul errorpage. Şi acesta ne este cunoscut. El anunţă
denumirea paginii care se ocupă de tratarea excepţiilor şi anume fişierul eroare.jsp
În schimb, linia 03 reprezintă un impact. Aici anunţăm pagina mydb.jsp prin intermediul
etichetei jsp:useBean despre o clasă de tip bean. Accesul se va efectua prin intermediul
unei denumiri logice prescurtate, bd, nu prin denumirea fizică jsp.DBBean. Acest
„identificator” cum spun programatorii apare în destule linii după cum se va vedea mai
jos. În continuare, următorul atribut este cel al domeniului (scope=”session”). Este
necesară o paranteză.
Ce este domeniul ?
Orice obiect JSP declarat are un domeniu unde este recunoscut semantic de contextul
programului. Vă amintiţi că unul din obiectele implicite este şi sesiunea, session. Un
obiect cu domeniul session este accesibil atâta vreme cât clientul Web (MSIE) menţine
o sesiune de lucru cu serverul Web. Pot exista la un moment dat mai multe sesiuni la
aceiaşi pagină. Dacă este aşa, atunci motorul servlet va anula după un interval de timp
sesiunea, în cazul când acestea ar rămâne inactivă pentru prea mult timp. Recomandăm
să vă aruncaţi ochii şi prin capitolul 6.
De ce se face aceasta? Pentru motivul că nu există o modalitate de a şti de la serverul
Web, că un vizitator a închis sesiunea la acel PC aflat la distanţă. Acolo rulează clientul
Web. Desigur, există şi posibilitatea închiderii forţate a sesiunii cu metoda invalidate() a
obiectului session. La ea se apelează dacă vizitatorul sitului s-a deconectat în mod
explicit iar legătura de date a funcţionat. Pentru termenul legătură de date vezi referinţa
/1/.
Aşa cum există un domeniu pentru obiectul session, există un domeniu şi pentru
obiectul request. Cererea de la clientul Web durează atât timp cât este prelucrată.
Există şi un domeniu pentru obiectul page, pagină ca şi pentru obiectul application,
aplicaţie.
Un obiect cu domeniul pagină este accesibil doar din pagina unde a fost creat. Nu mai
prelungim paranteza şi revenim la exerciţiul nostru.
Ne reîntoarcem al linia 03. Ultimul atribut din eticheta jsp:useBean este class. Aici se
anunţă că se va folosi un cod de octeţi denumită: jsp.DBBean. Ştim deja că are
terminaţia .class. Denumirea jsp este cea a unui pachet cu clase tip Java bean. Pachetul
în cazul aplicaţiei de faţă a avut doar o singură clasă tip Bean. Pachetul va fi până la
urmă materializat printr-un director care va conţine toate fişierele tip bean. Faptul că am
notat cu litere mari nu este o convenţie anume. DB vine de la DataBase. Nu trebuie
neapărat denumirea Bean!
În linia 07 anunţăm un formular. Când va fi acţionat butonul de tip submit se va
comanda pornirea servletului purgeDB.jsp.
Aţi putea crede că toate liniile de program care urmează se ocupă de golirea tabelului
visitors (purge), dar nu este aşa! Să nu confundaţi denumirea myVisitors dată sursei de
date deci bazei în sine cu denumirea tabelului visitors!
Acest formular adăposteşte un tabel HTML (linia 09) cu trei coloane (liniile 10-12). A
patra coloană va conţine butonul de tip submit pe care scrie „Golire tabel”.
În linia 15 ne conectăm logic la baza de date myVisitors alias mydb.mdb. Am spus că
nu reproducem codul programului DBBean.java. În cadrul rutinei connect() se activează
driverul tip punte. El are o denumire lungă şi neinteresantă.
Linia 16 conţine o instrucţiune de atribuire a limbajului Java. În partea stângă se invocă
metoda viewVisitors() a clasei DBBean. Aceasta are denumirea logică bd. Metodă
„întoarce” un tabel rezultat denumit rs care este un obiect cu structura tip ResultSet.
În linia 17 se intră într-o buclă while. În fond şi al urma urmei, trebuie să vizualizăm
tabelul cu vizitatori. Aceasta o facem cu metoda next() a obiectului ResultSet.
Deoarece afişarea se face cu ajutorul HTML, ieşim din scriptlet. Vezi în linia a 18-a,
separatorul de ieşire. Revenim în scriptlet în linia a 24-a. Veţi întreba de ce? Pentru că
while are un corp delimitat de două acolade şi pentru că următoarele linii se referă la
HTML. Observaţi acolada de încheiere din linia a 24-a.
În cuprinsul liniilor 19 – 23 extragem din tabelul visitors valorile stocate în câmpurile
înregistrării. Pentru aceasta recurgem pentru fiecare câmp în parte la metoda getString().
Deoarece metoda aparţine clasei ResultSet, vom plasa denumirea rs înaintea denumirii
metodei, separând-o printr-un punct, deci scriem rs.getString(nume).
Liniile 26 şi 27 se referă la HTML. Părăsim din nou scenariul în linia 25 pentru a reveni
în linia 28, ca să realizăm deconectarea logică de la bază.
Ce rost au liniile 20–22? Ele redau conţinutul tabelului visitors în fereastra document a
browserului MSIE. Deci pagina aceasta va afişa de fapt conţinutul tabelului visitors.
Anunţăm pe vizitator că are la-ndemână butonul „Golire tabel”, dacă doreşte să elimine
toate înregistările. Linia 30 anunţă un alt formular pentru care este pregătit să îi facă faţă
servletul refillDB.jsp. Formularul are un tabel fără chenar (linia 31, BORDER=”0”),
compus dintr-un singur rând (tr, vezi liniile 32 şi 35, cu două celule (td, liniile 33 şi 34).
Linia 34 conţine butonul „Reincarc tabel”. Dacă se acţionează mai întâi butonul „Golire
tabel” şi apoi butonul „Reincarc tabel”, se vor genera trei înregistări în visitors. Datele
acestor înregistrări sunt declarate în cadrul metodei populateVisitors() din clasa de tip
bean care nu a fost etalată aici.
Începând cu linia 38 observăm un al treilea formular de care se ocupă servletul
delrec.jsp, ştergerea logică a unei înregistrări. V-aţi cam obişnuit cu tipicul de
programare! Şi acest formular are un tabel fără chenar (linia 39) alcătuit dintr-o singur
rând (liniile 40 şi 44). Rândul conţine trei celule definite în liniile 41, 42 şi 43. Aici se
cere furnizarea prealabilă a codului numeric personal. Butonul pentru eliminare are
notat pe el cuvintele „Elimin vizitator”.
Linia a 47-a defineşte al patrulea formular de care se ocupă servletul addvisitor.jsp. Este
un tabel cu un singur rând cu două celule. Butonul „Adaug vizitator” după cum îi spune
numele, declanşează ceva ce nu apare aici explicit ca la cazul de mai sus, delrec.jsp.
Acum să contemplăm fişierul refillDB.jsp. Fiind de acum obişnuiţi cu tipicul de
programare nu am mai numerotat aceste linii.

Lista 5.2 Pagina refillDB.jsp

<%-- refillDB.jsp --%>


<%@ page language="java" import="java.sql.*, java.io.*, java.util.*"
errorPage="eroare.jsp" %>
<jsp:useBean id="bd" scope="session" class="jsp.DBBean"/>
<html>
<head>
<title>Reumplere baza Visitors.</title>
</head>
<body>
<%
bd.connect();
bd.populateVisitors();
bd.disconnect();
%>
Vizitatori adaugati. <br/>
Click <a href="mydb.jsp">here</a> ca sa vezi continutul tabelului visitors.
</body>
</html>

Explicaţii şi parafraze
Şi pagina refillDB.jsp are domeniul sesiune. Şi aici observaţi un scriptlet, unde apar cele
trei metode afiliate la clasa DBBean: connect(), populateVisitors() şi disconnect().
Afilierea se realizează prin asocierea denumirii bd la denumirea metodei. După ce se
efectuează popularea cu trei vizitatori într-o altă fereastră de tip document, se anunţă
mesajul „Vizitatori adăugaţi”. Un rând mai jos apare o legătură tip hypertext cu ajutorul
căreia se revine la pagina de bază mydb.jsp.
Cum arată aspectul paginii principale după adăugarea celor trei înregistrări vedeţi în
figura următoare.
FIGURA 5.5 Aspectul paginii principale a aplicaţiei mydb.jsp

Înainte de a continua cu prezentarea listelor aplicaţiei veţi observa în figură butoanele


celor patru formulare, „Golire tabel”, „Reîncarc tabel”, „Adaug vizitator” şi „Elimin
vizitator”.
Acum să ne ocupăm de pagina purgeDB.jsp. Aici apare ceva nou şi anume linia în care
prin metoda getParameterValues iniţializăm un masiv de tip şir de caractere, care este
denumit cam prozaic s.
Lista 5.3 Pagina purgeDB.jsp

<%-- purgeDB.jsp --%>


<%@ page language="java" import="java.sql.*, java.text.*, java.io.*, java.util.*"
errorPage="eroare.jsp" %>
<jsp:useBean id="bd" scope="session" class="jsp.DBBean"/>
<html>
<body>
<%
String[] s = request.getParameterValues("cnp");
bd.connect();
bd.purgeVisitors(s);
bd.disconnect();
%>

Vizitatori eliminati! <br/>


Click <a href="mydb.jsp">here</a> ca sa vezi rezultatul.
</body>
</html>

Explicaţii şi parafraze
Masivul va conţine la finalul executării acestei pagini toate codurile numerice personale.
Acest masiv este pasat apoi metodei purgeVisitors(). Tot aşa într-o fereastră de tipul
document se anunţă că vizitatorii au fost eliminaţi şi, printr-o legătură tip hypertext se
revine la pagina de bază, mydb.jsp.
A venit rândul paginii addvisitor.jsp. Am remarcat la pagina de bază că nu mai erau
prezente metodele connect() etc. Am schimbat voit locul lor, deşi nu eram îndreptăţiţi să
o facem aici în interiorul acestei pagini. În fişierul addvisitor.jsp aflăm că graţie
formularului definit aici, se apelează altă pagină denumită addrec.jsp. Deocamdată
addvisitor() defineşte un tabel HTML format din trei rânduri, conform celor trei câmpuri
ale tabelului visitors. Fiecare rând are câte două celule. În celula din stânga apare în clar
un text de invitare la dialog. Se cer: codul numeric personal, numele şi prenumele.
Lista 5.4 Pagina addvisitor.jsp

<%-- addvisitor.jsp --%>


<html>
<body>
<h1>Adauga vizitatorul</h1>
<form action="addrec.jsp" method="post">
<table>
<tr>
<td>Codul numeric personal (13 cifre), ex: 1790205400234: </td>
<td><input type="text" name="cnp" size="13"></td>
</tr>
<tr>
<td>Numele: </td>
<td><input type="text" name="nume" size="30"></td>
</tr>
<tr>
<td>Prenumele: </td>
<td><input type="text" name="prenume" size="30"></td>
</tr>
</table>
<br/>
<input type="submit" value="Adauga vizitatorul!" />
</form>
</body>
</html>

Explicaţii
Evident, trebuia să existe şi un buton submit pe care este menţionat „Adauga
vizitatorul!”.
Cât priveşte fişierul addrec.jsp el este tot o pagină referitoare la un obiect tip sesiune,
cum sunt de altfel toate fişierele acestei aplicaţii.
Lista 5.5 Pagina addrec.jsp

<%-- addrec.jsp --%>


<%@ page language="java" import="java.sql.*, java.io.*, java.util.*"
errorPage="eroare.jsp" %>
<jsp:useBean id="bd" scope="session" class="jsp.DBBean"/>
<html>
<body>
<%
String Cnp = request.getParameter("cnp");
String Nume = request.getParameter("nume");
String Prenume = request.getParameter("prenume");

bd.connect();
bd.addVisitors(Cnp, Nume, Prenume);
bd.disconnect();
%>
Vizitator adaugat.
<br>Clic <a href="mydb.jsp">aici</a> ca sa vezi rezultatul.
</body>
</html>
Explicaţii
Aici însă există un scriptlet. În trei rânduri distingem cum se extrag din formular prin
inetrmediul obiectului request conţinuturile câmpurilor tabelului visitors. Odată aflate
aceste valori, se lansează pe rând metodele de conectare, connect(), de adăugare a
vizitatorului, addVisitors() şi la final, de deconectare logică, disconnect(). Toate sunt
codificate în cadrul paginii tip Bean a cărei liste nu o vom reda aici.
Urmează să vorbim despre pagina delrec.jsp. Aceasta preia într-o variabilă String
denumită Cod_np, codul numeric personal. Informaţia se preia din specificaţia URL şi
vine din câmpul denumit logic cnp_anume (priviţi lista). Tot în acelaşi scriptlet se
execută de acum obişnuita secvenţă de conectare, apel de procedură deleteVisitor() şi de
deconectare logică la baza de date.
Ultimele două pagini de mai sus sunt croite după aceiaşi filozofie de afişare a
rezultatului într-o fereastră separată de tip dcoument, cu o legătură de revenire la pagina
de bază mydb.jsp.
Lista 5.6 Pagina delrec.jsp

<%-- delrec.jsp --%>


<%@ page language="java" import="java.sql.*, java.io.*, java.util.*"
errorPage="eroare.jsp" %>
<jsp:useBean id="bd" scope="session" class="jsp.DBBean"/>
<html>
<body>
<%
String Cod_np = request.getParameter("cnp_anume");
bd.connect();
bd.deleteVisitor(Cod_np);
bd.disconnect();
%>
<br>Click <a href="mydb.jsp">aici</a> ca sa vezi efectul!
</body>
</html>

Explicaţii şi parafraze
A rămas de prezentat scurta pagină de tratare a erorii, eroare.jsp. Ştim de la capitolul
anterior ce înseamnă true pentru atributul isErrorPage. Această pagină este într-adevăr
pagina interceptoare a erorilor. După mesajul generic „Semnalăm o eroare”, preluăm
prin intermediul obiectul exception mesajul acelei erori produse. toString() este metoda
de tip şir, care are menirea de publicare a mesajului în sine.
Lista 5.7 Pagina eroare.jsp

<%-- eroare.jsp --%>


<%@ page language="java" isErrorPage="true"%>
<html>
<body>
<h2>Semnalam o eroare.</h2>
<h4>Ea este:</h4><%= exception.toString() %><BR>
<br>Luati legatura cu administratorul retelei!
</body>
</html>

Foarte puţin despre clase tip Bean


O clasă de tipul Bean trebuie să ne-o închipuim ca pe o cochilie în care s-a înmagazinat
inteligenţă! Mai departe similtudinea nu merge.
Dispunem de trei etichete pentru a avea acces în interiorul … cochiliei şi anume:
jsp:setProperty, jsp:getProperty şi jsp:useBean.
Proprietăţile sunt metode publice ca şi clasa de tip Bean de altfel. Denumirea unei
metode are un tipic pe care îl vom explica mai uşor pe exemplul simplu care urmează.
Cu eticheta jsp:setProperty transmitem valori spre proprietatea respectivă.
Cum arată formatul sintactic al etichetei jsp:setProperty? Unul dintre formate arată cam
aşa:
<jsp:setProperty name=”nume_clasa_Bean”, property=”numeProprietate”,
value= ”şir_de_caractere”>

În cadrul clasei Bean trebuie să existe o astfel de proprietate dar care, remarcaţi felul
cum este ea scrisă:
public tip setNumeProprietate(tipProprietate argument) {
corpul metodei
}

Constructorul clasei tip Bean trebuie să aibă şi el un tipic de scriere pe care îl veţi
remarca din exemplul de mai jos.
Iată acest exemplu. El este format dintr-o pagină JSP şi o clasă tip Bean. Directorul se
denumeşte stridie. Directorul stridie este fiu al directorului:
<HOME_Resin>.
Mai întâi redăm intergral codul sursă al paginii JSP:
Lista 5.8 Pagina stridie.jsp

<jsp:useBean id="stridia" class="jsp.AusterBean" />


<jsp:setProperty name="stridia" property="molusca" value="Nu stiu, n-am mancat" />
<html>
<body><table border="0">
<tr>
<td>Ce gust are stridia?</td>
<td><jsp:getProperty name="stridia" property="molusca" />
</tr>
</table></body></html>

Clasa bean se află la fel ca în cazul exemplului de mai sus în directorul:


<HOME_Resin>/stridie/WEB-INF/classes/jsp.
Iată acum codul sursă al clasei de tipul Bean:
Lista 5.9 Fişierul AusterBean.java

package jsp;
public class AusterBean {
// variabilele clasei sunt totdeauna intangibile din exterior
private String meckerel;

public String getMolusca() {


return meckerel;
}

public void setMolusca(String fiinta) {


meckerel = fiinta;
}

// Constructorul clasei
public AusterBean() {
meckerel = "";
}
}

Explicaţii şi parafraze
Să ne concentrăm mai întâi asupra ultimei liste. Primul lucru pe care îl remarcaţi este că
aici apar instrucţiuni tipice ale limbajului Java.
Orice clasă de tip Bean are constructor. Al doilea lucru este declaraţia:
package jsp;

Cu ea anunţăm container servletul că clasa AusterBean va aparţine unui pachet denumit


jsp, deci va fi găsită în directorul redat mai sus.
Alt lucru care sare în ochi este faptul că clasa este publică, deci accesibilă din exterior,
deci şi din pagina stridie.jsp.
În schimb meckerel, unica variabilă a clasei este inaccesibilă din exterior. De ce?
Remarcaţi cuvântul cheie „private” din faţa denumirii. Meckerel înseamnă stridie în
engleză, iar în germană i se spune Auster. Aceasta nu este o convenţie de notaţie ci, un
... bâzdîc al programatorului în a denumi în fel şi chip variabilele, proprietăţile şi clasa.
Repetăm, nici chiar denumirea clasei nu trebuie să se termine neapărat cu Bean.
Clasa conţine două proprietăţi, getMolusca() şi setMolusca(). Cu ajutorul primeia
obţinem conţinutul variabilei meckerel. Cu setMolusca() în schimb, înscriem un şir de
caractere preluat de către argumentul fictiv fiinta. Valoarea se preia din lista stridie.jsp.
Observaţi atributul value din:
<jsp:setProperty name="stridia" property="molusca" value="Nu stiu, n-am mancat" />
Remarcaţi şi constructorul clasei AusterBean. El nu întoarce nimic şi nu primeşte ceva
prin listă. În momentul în care motorul servlet execută eticheta jsp:useBean, are loc
automat o instanţiere a clasei respective. Despre instanţiere am tot vorbit. E ca şi când s-
ar întâlni o instrucţiune de genul
AuserBean variabila = new AusterBean();
Să aşezăm două linii aproape unda de alta.
<jsp:setProperty name="stridia" property="molusca" value="Nu stiu, n-am mancat" />
din fişierul stridie.jsp şi,
public void setMolusca(String fiinta) {
din fişierul AusterBean.java. Remarcaţi ceva care poate scăpa neobservat şi anume
cuvântul este transcris cu literă mică în fişierul stridie.jsp (molusca) şi cu literă mare în
fişierul AusterBean.java (Molusca), deşi este precedat de get sau set. Acesta este tipicul
de programare … Bean! Fără acest tipic nu merge acest mecanism de tip Bean!
Ca să executăm acest exerciţiu cu motorul resin1.1.4, trebuie dată adresa:
http://localhost:8080/stridie/stridie.jsp
Mai trebuie realizat ceva. Un container servlet este în fond tot un program. Menirea lui
este de a executa servleturi. Acest motor este ghidat la momentul pornirii de un fişier
scenariu denumit httpd.conf (în cazul resin), sau de altul în cazul altui motor servlet
(JRun, Tomcat).
Nu ne apucăm acum să redăm lista acestui fişier, deoarece am divaga. Vom arăta doar
liniile adăugate acestuia:
<!-- adaugat 6 mai 2003 -->
<web-app id='stridia'>
<servlet-mapping url-pattern='/servlet/*' servlet-name='AusterBean'/>
<servlet servlet-name='AusterBean' servlet-class='jsp.AusterBean'/>
</web-app>

Explicaţii şi parafraze
Prima linie este un comentariu JSP. Următoarele linii sunt scrise după tipicul unui fişier
XML. Marcajul <web-app> flanchează un grup de două linii. Marcajul are întotdeauna
două balize, cea de început <web-app> şi de final, </web-app>.
Vă recomandăm să parcurgeţi paginile dedicate limbajului XML din referinţa /1/.
Acest grup de două linii din interior nu îl explicăm în totalitate. Rostul său este să
anunţăm motorul servlet resin că trebuie să compileze tot ce găseşte în directorul
<HOME_Resin>/stridie/WEB-INF/classes/jsp.
deci un fişier sursă Java. Pe acest motor nu îl interesează că fişierul conţine o clasă tip
Bean sau nu. De fiecare dată când vom lansa aplicaţia stridie.jsp, deci dăm adresa URL
de mai sus, dacă nu exista deja fişierul AusterBean.class, motorul va compila fişierul
AusterBean.java. Reamintim că orice fişier Java compilat are aceiaşi denumire cu accea
a fişierului sursă, dar extensia va fi .class. Este acel cod de octeţi, bytecode de care
vorbeam în introducere.
Să privim acum lista fişierului stridie.jsp. Trimitem de fapt şirul de litere:
„Nu stiu, n-am mancat”.
Priviţi aspectul ferestrei documentului acestei aplicaţii adhoc.

FIGURA 5.6 Aspectul ferestrei în contextul browserului MSIE

La final de capitol
Am prezentat:
1. Câteva elemente despre metodele de acces la platforma ODBC venind dinspre
maşina virtuală Java. Am explicat rostul fiecăruia din cele două drivere . Vezi şi
figura 5.1.
2. Am analizat în detaliu aplicaţia mydb.jsp, evitând partea propriu-zisă a clasei de
tip Bean, DBBean.java.
3. A venit rândul prezentării în sine a tipicului unei clase de tipul Bean, şi, aici am
insistat pe un exemplu adhoc asupra legăturii dintre container servlet şi pagina
JSP şi clasa în sine.
6
Capitolul

Sesiuni şi jaloane
Să traducem termenul cookie prin prăjiturică este prea de tot! Pragmatism tipic
american în alegerea denumirilor facilităţilor! Le vom spune jaloane. Jalonul nu
este o ascunzătoare de viruşi informatici!

S
puneam în introducere că protocolul HTTP este unul care nu are posibilitatea să
înregistreze dacă un vizitator a efectuat mai multe intrări tip cerere/răspuns la
acelaşi sit.
HTTP-ul a rămas acelaşi protocol simplu, eficient şi rapid! Pentru că pe Tim Berners
Lee, primul realizator al HTTP, nu l-a preocupat problema comerţului electronic, deci
problema coşului electronic
Chiar şi azi, fiecare cerere a unui client Web efectuată prin http, este tratată ca un
eveniment izolat.
Nu merge aşa ceva într-un sit comercial. O operaţiune comercială nu este ceva static.
Cumpărătorul încarcă şi descarcă coşul cu produse. Serverul trebuie să ţină minte cine şi
ce marfă a pus în coş.
JSP are două componente cu care poate urmări sesiunile unui cumpărător.
Fie foloseşte un identificator unic de sesiune, ce este alocat vizitatorului la prima cerere
a unei pagini JSP. Informaţia va fi stocată la PC-ul clientului Web.
Fie recurge la un obiect sesiune, ce este stocat la server.
Deşi serverele Web clasice nu memorează o cerere a unui client Web, după ce acesteia i
s-a răspuns, motorul servlet poate păstra obiecte sesiune unice pentru fiecare cerere.
JSP implementează obiectul session, dar auzim afirmaţiile: „domeniul session” şi
„obiectul session”. A nu se face o confuzie ! Obiectul este o structură de date şi de
punctatori spre metodele clasei care l-a generat. Domeniul este zona din program unde
este recunoscut acest obiect!
Blocului stocat pe disc i se spune jalon, cookie. Aici nu pot intra decât cel mult elemente
simple, date personale, deci variabile simple în sensul limbajului Java. Într-un obiect
sesiune stocat la server se admit şi structuri complexe de date.
Tehnologia JSP a permis ataşarea unor facilităţi avansate referitoare la gestionarea stării
sesiunilor.
Să ne ocupăm acum de cele mai relevante metodele ale obiectului sesiune.

Metodele obiectului sesiune


În acest exemplu scurt recurgem la câteva dintre metodele sale de bază.
LISTA 6.1 Pagina sesiune1.jsp

<!--
Fisier: sesiune1.jsp
<html>
<%@ page import="java.util.*,java.text.DateFormat" %>
<body>
<%
out.println("Sesiunea este noua? " + session.isNew() );
// Care este id-ul acestei sesiuni?
out.println( "<br>Identificatorul sesiunii este: " + session.getId() );
// Si la ce data si ora am creat-o?
out.println( "<br>Data si ora crearii sesiunii este: " +
DateFormat.getInstance().format(new Date(session.getCreationTime())) );
// Obtin data si ora ultimei accesari a obiectului Session:
out.println( "<br><br>Ultima accesare a fost la (format ilizibil): " +
session.getLastAccessedTime() );
// Transform sesiunea curenta intr-una nevalabila si eliberez toate obiectele
(variabilele simple sau chiar obiectele stocate in ea
// session.invalidate();
%>
</body>
</html>

Explicaţii şi parafraze
Să remarcăm existenţa metodelor:
1. isNew(): întoarce o valoare logică (adevărat sau fals), după cum a fost sau nu o
sesiune nouă. Priviţi figura 6.1, unde din a doua sesiune obţinută prin lansarea
din nou a browserului MSIE, s-a creat contextul sesiunii noi. De unde şi acel
true anunţat în fereastra celei de a doua lansări.
2. getId(): se obţine un identificator al sesiunii. Este treaba JVM de a livra un şir
unic de caractere pe post de identificator de sesiune.
3. getCreationTime(): întoarce data şi ora creării sesiunii.
4. getLastAccesedTime(): anunţă momentul ultimului acces la acea pagină din
sesiunea curentă. În exerciţiul de faţă acest moment a coincis cu data şi ora
creării, fiindcă cele două metode de creare şi acces erau în aceiaşi pagină JSP.
5. invalidate(): anulează accesul la conţinutul blocului sesiunii. Revenim mai jos
cu explicaţii mai clare pentru această metodă.
În figură distingeţi două ferestre de tip document, fiecare corespunde unei sesiuni
distincte. Fiecare sesiune are un identificator unic, momente sunt diferite la aceiaşi dată,
deoarece am aşteptat circa un minut înaintea celei de a doua folosiri a browserului
MSIE.

FIGURA 6.1 Cele două sesiuni, fiecare id-ul său (context Resin)

Să mai observăm ceva: metoda getLastAccesedTime() întoarce data şi ora sub forma
unei valori întregi stocate pe opt octeţi (tipul de dată long). Valoarea nu este inteligibilă.
Acelaşi tip de dată întoarce şi metoda getCreationTime(). Prelucrată însă cu metode
adecvate (Date, DateFormat) valoarea datei se transformă într-una inteligibilă.
Mergem mai departe! Să înscriem o valoare simplă în cadrul obiectului sesiune. O vom
face cu metoda setAttribute(). Şi am ales ca să trimitem chiar „id-ul” sesiunii pe postul
de variabilă simplă în sens Java. Ea este denumită idSesiune. Priviţi listele exemplului.
Am profitat de prezenţa unui formular, deci de existenţa obiectului request şi, prin
intermediul etichetei jsp:forward, am trimis din motive didactice şi acest idSesiune.
În acest exerciţiu, sesiunea se extinde logic pe cele trei pagini sesiunePreiaId.jsp,
sesiuneSetezId.jsp şi sesiuneAfisezId.jsp. Pagina chemătoare în care se află formularul
se numeşte sesiunePreiaId.jsp. Deci lansăm aplicaţia prin adresa:
http://localhost:8080/test/sesiunePreiaId.jsp în contextul motorului Resin 1.1.4. Aspectul
îl vedeţi în figura 6.2a. Dacă am fi folosit JRun 3.0, atunci comanda ar fi fost:
http://localhost:8100/sesiunePreiaId.jsp. Iată cele trei pagini JSP.
LISTA 6.2a Fişierul sesiunePreiaId.jsp(context Resin)

<html>
<body>
<form name="setezId" method="post" action="sesiuneSetezId.jsp">
<% String idSesiune = session.getId(); %>
<center><table>
<tr><input type="submit" name="Buton" value="<%=idSesiune %>"</td></tr>
</table></center></body></html>
LISTa 6.2b Fişierul sesiuneSetezId.jsp(context Resin)

<%
// Setez variabila tip session cu numele de "idSesiune"
session.setAttribute( "idSesiune", request.getParameter("Buton") );
%>
<jsp:forward page="sesiuneAfisezId.jsp"/>
<%@ page import = "java.util.*" %>
LISTA 6.2c Fişierul sesiuneAfisezId.jsp(context Resin)

<html>
<body>
Id-ul sesiunii este <%=session.getAttribute("idSesiune")%>!
<%
out.println("<br>Id de sesiune a fost transmis printr-un cookie " +
request.isRequestedSessionIdFromCookie() );
out.println("<br>Id de sesiune a fost transmis printr-o adresa URL " +
request.isRequestedSessionIdFromUrl() );
%>
</body>
</html>

şi aspectul pe ecran al exemplului:

FIGURA 6.2 Afişarea id-ului sesiunii (context Resin)

Explicaţii şi parafraze
Nu am redat aspectul iniţial de pe ecran al ferestrei pentru acest exerciţiu însă, prima
dată veţi observa un buton de formular, care are inscripţionat pe el chiar valoarea
identificatorului sesiunii. Servletul care prelucrează acest formular este
sesiuneSetezId.jsp (form are atributul action). La momentul efectuării clicului pe acest
buton, cererea ajunge la pagina sesiuneSetezId.jsp. Acest servlet înscrie cu ajutorul
metodei setAttribute(), id-ul sesiunii în idSession. Valoarea o preia cu ajutorul obiectului
request şi al metodei getParameter() din câmpul denumit Buton din formular,.
Cu ajutorul etichetei jsp:forward se expediază această valoare la pagina
sesiuneAfisezId.jsp. Priviţi lista 6.2c. În această pagină deosebiţi trei metode. Prima
dintre ele, getAttribute(), accede obiectul sesiune. De fapt interesează conţinutul lui
idSesiune pe care-l afişăm. Următoarele două metode ne spun pe care traseu s-a trimis
id-ul sesiunii. Id-ul unei sesiuni poate veni fie prin adresă URL, fie prin jalon (cookie).
Când lucrăm cu session, lucrăm de fapt în fundal cu jalonul (cookie). Aici el a fost
trimis prin cookie, de unde şi valoarea true. Metodele de explorare au denumiri lungi şi
clare:
isRequestedSessionIdFromCookie, respectiv isRequestedSessionIdFromURL
A mai rămas să arătăm cum se memorează un obiect cu structură de date mai complexă
în cuprinsul obiectului session. Iată cum se procedeează în cazul memorării unui vector
cu elemente. Priviţi lista exemplului următor unde apar şi alte metode ale obiectului
session.
LISTA 6.3 Un fişier cu multe metode ale obiectului session, SesiuneVector.jsp

01. <!--
02. Fisier: SesiuneVector.jsp
03. Inspirat dupa exemplul lui David Aden, cap. 10 "JSP Development", ed. Sams
2001
04. dar modificat mai ... multicel -->
05. <html>
06. <head>
07. <title>Vector cu obiecte Session</title>
08. </head>
09. <body>
10. <%@ page import="java.util.*" %>
11. <%
12. // Creez o variabila de lucru
13. String s = "";
14. // Creez un vector denumit vec
15. Vector vec = new Vector();
16. // Si il umplu cu valori
17. vec.addElement("pantoful marca x");
18. vec.addElement("gluga marca y");
19. vec.addElement("camasa z ");
20. // Creez un obiect complex denumit Vectorul propriu, caruia ii atasez valoarea
obiectului vec.
21. session.setAttribute("VectorulPropriu", vec);
22. // Citesc valoarea parametrului "VectorulPropriu" din obiectul Session
23. Vector vec1 = (Vector) session.getAttribute("VectorulPropriu");
24. // Buclez prin acest vector citit si ii afisez elementele
25. out.println( "<br>Imprim vectorul stocat in obiectul Session:" );
26. for ( int x=0; x < vec1.size(); x++ )
27. out.println( "<br>vec1 " + x + ": " + vec1.elementAt(x) );
28. // Obtin o valoare specifica din vector
29. s = (String) ((Vector) session.getAttribute("VectorulPropriu")).elementAt(2);
30. out.println( "<br>Afisez valoarea elementului 3 direct din vector:" );
31. out.println( s );
32. out.println( "<br>Iata o lista a tuturor variabilelor din " +
33. "Obiectul Session:");
34. // Obtin o lista a tuturor parametrilor obiectului Session
35. Enumeration enum = session.getAttributeNames();
36. // Prin intermediul lui Enumeration extrag valorile parametrilor din obiect
37. while ( enum.hasMoreElements() ) {
38. s = (String) enum.nextElement();
39. out.println( "<br>Numele variabilei Session: " + s );
40. }
41. // Afisez intervalul de asteptare ca la clientul web sa se intample ceva
42. out.println( "<br>Time-outul este de: " + session.getMaxInactiveInterval() + "
secunde. Schimb timeoutul la 10 minute");
43. // Setez time-out-ul la 10 minute
44. session.setMaxInactiveInterval(60*10);
45. // Si afisez acest time-out, interval de asteptare
46. out.println( "<br>Noul time-out este de: " + session.getMaxInactiveInterval() + "
secunde");
47. // Incerc sa afisez o valoare de atribut inexistenta
48. out.println( "<br>Exista parametrul u1234? Evident ca nu si va raspunde prin sir
vid, adica: " + session.getAttribute("u1234"));
49. // Inscriu parametrul u1234 in obiectul sesiune:
50. session.setAttribute("u1234", "HIP HIP URA!");
51. // Incerc sa afisez o valoare de atribut care exista acum
52. out.println( "<br>Exista parametrul u1234? Acum da si va raspunde prin sirul HIP
HIP URA!: " + session.getAttribute("u1234"));
53. out.println( "<br>Sterg parametrul u1234? Va raspunde prin null" );
54. // Indepartez acest parametrul u1234 din obiectul sesiune:
55. session.removeAttribute("u1234");
56. // Incerc sa afisez o valoare de atribut care nu mai exista
57. out.println( " Dar acum mai exista parametrul u1234? " +
session.getAttribute("u1234"));
58. %>
59. </body>
60. <html>

Explicaţii şi parafraze
Liniile 01-04 alcătuiesc un comentariu. Directiva page (linia 10) anunţă maşina JVM că
este nevoie de clasele nodului java.util.*. De ce acest nod generic din ierarhie? Deoarece
în cuprinsul exemplului de faţă operăm atât cu clasa Enumeration cât şi cu clasa Vector.
Am fi putut specifica explicit java.util.Vector şi java.util.Enumeration, dar mai bine am
inclus totul, adică java.util.*. Să nu credeţi că servletul va deveni mai voluminos. La
momentul importării se vor selecţiona doar clasele efectiv apelate în această pagină.
Creăm variabila de tip şir denumită s (în linia 13) şi vectorul vec (linia 15). Iniţializăm
elementele sale cu ajutorul metodei addElement() – vezi liniile 17-19. Înscriem în
fiecare element, literalii pe care de altfel îi şi remarcaţi. În primul element vec[0], se va
înscrie textul „pantoful marca x”, ş.a.m.d. Numerotarea unui vector începe în
programare de la zero nu de la unu!
Graţie metodei setAttribute(), stocăm întregul vector (linia 21).
Apoi, creeăm o altă instanţă denumită vec1. Cu ajutorul metodei getAttribute(), se preia
întregul vec şi se atribuie lui vec1 (linia 23).
Parcurgem element după element, conţinutul vectorului vec1 pe care îl şi afişăm de
altfel (liniile 26-27). Metoda de selecţie este elementAt(x). Observaţi că indexul x ia
valori de la 0 la 2; x este indexul buclei for.
Se permit şi referiri directe la elemente unui vector (vezi linia 29). Aici se preia în
variabila s conţinutul elementului al treilea (index 2) al vectorului vec1.
Acum să ne amintim din nou de clasa Enumeration, întâlnită în această carte. Cu ea
« palpăm » întregul obiect sesiune şi aflăm ce se află în cadrul său. Există doar obiectul
denumit „VectorulPropriu”. Observaţi în linia 21 felul cum am memorat acest obiect în
dreptul lui „VectorulPropriu”. La fel i-am zis şi când am dorit să regăsim vectorul (linia
23), şi când am adresat chiar un element din el (linia 29). În fiecare caz am recurs la
getAttribute().
Să mergem mai departe! În porţiunea liniilor 34-40, unde am comentat din plin această
listă în detrimentul lungirii ei, aflăm lista tuturor parametrilor obiectului sesiune.
Orice sesiune va fi dezactivată de către serverul Web în mod automat, după scurgerea
unui interval de timp de inactivitate la clientul Web. Cu linia 42 aflăm mărimea time-
out-ului.
Putem schimba mărimea acestui interval de aşteptare cu ajutorul metodei denumite
setMaxInactiveInterval(), vezi linia 44. Am dorit ca obiectul « să vieţuiască » 10 minute
x 60 secunde. Metoda aparţine de obiectul session, ca de altfel şi metoda de aflare a
acestui interval, getMaxInactiveInterval(). Observaţi că se lucrează cu secundele ca
unitate de măsură!
Am ajuns aproape de sfârşitul acestei liste. Fixaţi-vă acum atenţia asupra liniei 48. Când
încercăm să aflăm dacă ar exista o variabilă cu o astfel de denumire în obiectul sesiune,
ni se răspunde printr-un şir vid că nu există!
Dacă însă înscriem în acest bloc (linia 50) parametrul u1234 şi îi ataşăm valoarea HIP
HIP URA! cu ajutorul metodei setAttribute(), la citirea conţinutului parametrului u1234,
se va anunţa acest text (linia 52).
Prin metoda invalidate() se elimină toţi parametrii din obiectul session. Cu metoda
removeAttribute() din linia 55 îndepărtăm doar un parametru. Deci invalidate şterge
totul din obiectul session, în timp ce removeAttribute, doar ce dorim din el.
Să privim aspectul acestui exerciţiu rulat cu MSIE în figura de mai jos.
FIGURA 6.3 Aspectul documentului MSIE după rularea servletului sesiune3.jsp

Foarte puţin despre clasa cookie


Această clasă este una de tipul explicit. Deci vom apela la operatorul new ca să creăm
un obiect cookie. Repetăm! Când recurgem la obiectul session, se spune că „lucrăm în
fundal cu cookie”. Se recomandă folosirea obiectului session, dar şi cu cookie putem
face ceva.
În ce ne priveşte, avem rezerve asupra acestor cookies. Orice browser poate dezactivata
această facilitate şi atunci toată strădania se duce … de râpă! Există şase metode în clasa
cookie şi anume: getName(), setValue(), getValue(), setMaxAge(), getMaxAge() şi
clone().
Când vrem să creăm un jalon procedăm astfel:
Cookie prăjituraMea = new Cookie(“cuki”,”bigi-bigi”);

Denumirea blocului cookie este cuki, iar valoarea bigi-bigi, acel gel dulce pe care îl
savuram în copilărie! E ceva turcesc. Acum totul se înscrie pe discul PC-ului gazdă a
browserului cu care s-a intrat la sit.
Ca să trimitem la clientul Web odată cu răspunsul acest ... bigi-bigi, vom recurge la
metoda addCookie() a obiectului response, deci vom zice:
Response.addCokie(prajituricaMea);

Observaţi caracterul terminal punct şi virgula cu care se sfârşeşte orice instrucţiune


scrisă în limbaj Java. Aţi remarcat poate la JSP că liniile care se referă la expresii JSP
sau la directive JSP nu recurg la punct şi virgulă.
Ca să memorăm în ... prăjituraMea un şir s cum este cel creat în lista de mai sus, vom
proceda aşa:
setValue(s);
Spre a se afla valoarea acestui şir recurgem la metoda:
getValue();

Cu metodele setMaxAge(int număr_secunde) şi getMaxAge() stabilim, respectiv aflăm


durata de viaţă a unui obiect de tip cookie, în secunde.
În sfârşit, prin metoda clone(), ... reproducem un jalon ca obiect.

La final de capitol
Am ajuns la finalul tehnologiei JSP. În acest capitol am abordat câteva exerciţii
referitoare la suportul Java pentru îmbogăţirea protocolului http, adică protocolul fără
stări. Am enumerat metodele obiectului sesiune şi am amintit în final cele şase metode
ale obiectului cookie.
Nu am mai tratat în această carte problema securizării tranzacţiilor, descurajaţi de acces
oprit la folosirea cadrului de lucru J2EE, cu care am fi putut construi un sit în toată
regula! Suportul API Mail pentru mesaje electronice, lipseşte de asemeni din J2SE, aşa
că ne oprim aici cu regret!
Nu am mai explicat nici partea referitoare la etichetele taglib, adică la biblioteca de
etichete personalizate din acelaşi motiv!
Nu ne rămâne decât să privim spre tehnologia concurentă Active Server Pages, ASP,
fiindcă să recunoaştem a fost mai accesibilă mediului universitar!
Întrebări şi răspunsuri
Întrebări fără răspunsuri
1. Ce tipuri de piese software reprezintă denumirile ca: Symantec Visual Café,
Allaire JRun Studio, Apache Tomcat Servlet and JSP Development with
VisualAge for Java?
2. Ştiţi denumiri de motoare servlet extrem de cunoscute?
3. Ce ştiţi dspre serverle Microsoft?
4. Cam ce piese software mai modeste ne vor duce la realizarea unui sit comercial
construit după tehnologia JSP?
5. Cine este promotorul tehnologiei JSP şi ce înseamnă JSP?
6. Ce sunt J2SE, J2EE?
7. Ce este un container?
8. Dinspre tehnologia ASP spre ce pachete să ne îndreptăm?
9. Ce limbaj nu ştiu serverele IIS şi PWS (Windows)? Care este însă limbajul
statuat la Microsoft pentru tehnologia ASP?
10. Ce este un client Web, dar un server Web?
11. Daţi exemple de clienţi Web şi servere Web din platforma Windows.
12. Ce este XML, dar XSL, dar XSLT?
13. Explicaţi modelul 3-tier master slave.
14. Servletul rezidă la serverul Web sau în cadrul containerului pentru servleturi şi
pagini JSP?
15. Containerul pentru servleturi şi pagini JSP este tot una cu motorul servlet?
16. Ce condiţii trebuie să se îndeplinească pentru ca de la staţii să avem acces la o
aplicaţie gen sit comercial?
17. Care este raportul dintre un component, un pachet şi o clasă?
18. JDK foloseşte sau nu suprafeţe grafice?
19. Care este diferenţa dintre servlet, scriptlet şi pagina JSP?
20. Ce extensie are un applet şi unde se află el?
21. În ce constă maşina virtuală Java?
22. După compilarea unui fişier sursă .java se obţine un fişier cu extensia .class.
Cum se numeşte el?
23. Ce este clasa, constructorul şi la ce este folosit?
24. La nivelul generaţiei a treia de limbaje se vorbeşte de subprogram, funcţie,
subrutină. Dar la nivelul generaţiei a patra care este termenul folosit?
25. Ce înseamnă Java Bean (vezi şi capitolul 6)?
26. Priviţi figura 1.3. Care ar fi relaţia dintre un server Web clasic şi un motor
servlet?
27. Ce ştiţi despre JAR şi WAR?
28. Ce conţin fişierele cu sufixul .html (.htm)?
29. De ce pagină statică, de ce pagină dinamică?
30. Explicaţi termenii development şi deployment.
31. Ce este un proces, multitasking şi multithreading?
32. La ce valori de port schimbă replici motorul JRun dar motorul Resin? Ce
înseamnă port şi soclu?
33. Ce înseamnă cookie?
34. Cum se obţine un servlet cu un motor specializat?
35. Care sunt cei trei protagonişti implicaţi în schimbul de informaţie dintr-o sesiune
la un sit comercial?
36. Ce este aşa-zisul fake-root?
37. Este corectă adresa URL următoare: http://localhost:8088/test/pagina.jsp?
38. În instrucţiunea out.println(“ …“ ); ce reprezintă out, dar println?
39. Daţi un exemplu de similitudine a clasei, pachetului, obiectului şi metodei
(indicaţie vezi finalul capitolului 3).
40. Se face sau nu distincţie între literele mici şi mari în denumirile unei clase? Este
tot una cu a scrie javax.servlet.jsp.JspWriter cu javax.servlet.jsp.jspwriter?
41. Ce este o metodă în sensul Java?
42. Explicaţi rostul etichetelor jsp:include şi jsp:forward.
43. Ce rost au etichetele jsp:useBean, jsp:setProperty şi jsp:getProperty?
44. Care sunt delimitatorii unei directive?
45. Explicaţi rostul moştenirii.
46. Metodele care încep cu cuvântul set şi get dintr-o clasă Bean ce conţin în
continuare în denumire?
47. Ce restricţii se cer variabilelor unei clase tip Bean?
48. Contemplaţi listele mai jos. Mai întâi pagina example3a.jsp:
<html>
<head><title>Session Example</title></head>
<body>
<p>
<h1> Where will your balance take you?</h1>
<br>
<%-- Get paramaters from the request object --%>
<% String firstName = request.getParameter("fname"); %>
<% String balance = request.getParameter("bal"); %>
<%-- Convert the bal paramater from String to double --%>
<% double accountBalance = Double.valueOf(balance).doubleValue(); %>
<%--
Write input paramaters to the session object
The session object cannot store a double.
You must first convert it to a Double.
--%>
<%
session.setAttribute("userName", firstName);
Double tempAccountBalance = new Double(accountBalance);
session.setAttribute("userBalance", tempAccountBalance);
%>
<%-- Output results --%>
Balance for <%=firstName %>: <%=accountBalance %> <br>
<br><br>
Would you like to <A href="example3b.jsp">invest your money</a>?.
<br><br>
Do you need a <a href="example3c.jsp">job</a>.
</body>
</html>

apoi example 3b.jsp:


<html>
<body>
<%-- Get name from the session object --%>
<% String fname = (String) session.getAttribute("userName"); %>
<h2>Hi <%=fname %> </h2>
<%-- Get balance and convert to double --%>
<%
Double tempBal = (Double) session.getAttribute("userBalance");
double accountBalance = tempBal.doubleValue();
%>
<%-- Got enough money too invest? --%>
<% if(accountBalance > 100.00) { %>
Your balance of $<%= accountBalance %> is sufficient for investing.
We offer a number of investment opportunities, including: <br>
<li>Bonds<br>
<li>CDs<br>
<li>Mutual funds<br>
<% } %>
<%-- Is balance too low? --%>
<% if(accountBalance <= 100.00) { %>
Your balance is too low for investing. It looks like you need a <a
href="example3c.jsp">job</a>.
<% } %>
</body>
</html>

şi în final, example3c.jsp:
<html>
<body>
<%-- Get paramaters from the session object --%>
<% String fname = (String) session.getAttribute("userName"); %>
<h2>Hi <%=fname %></h2>
<h2>Available positions include:</h2>
Software Engineer<br>
QA<br>
Technical Writer<br>
</body>
</html>

După pornirea motorului JRun şi a browserului MSIE se dă comanda:


http://localhost:8100/example3a.jsp?bal=345.56&fname=Oprea
Descifraţi dumneavoastră ce rost au aceste fişiere şi conţinutul lor.
52. Explicaţi listele de mai jos: mai întâi fişierul includedir.jsp:
<html>
<body>
<%@ include file="inc\antet.inc" %>
<%@ include file="inc/corp.inc" %>
</body>
</html>

apoi fişierul antet.inc din directorul inc fiu al directorului test:


<head>
<title>Exemplu de includere a unui fisier cu directiva include</title>
<style type="text/css">
<!--
body { background-color:blue; color:white; }
-->
</style>
</head>

şi în final, corp.inc:
<body>
<h1 align="center">Exemplu de folosire a directivei Include</h1>
<hr/>
<font face="Verdana"><p>Aici e un prim paragraf.</font>
<font face="Times Roman"><p>Aici e al doilea paragraf.</font>
<font face="Arial"><p>Merg ambele feluri de slash-uri si asa ("\") si asa ("\"), cand
incluzi cu directiva file fisiere.</font>
</body>
53. Ce se întâmplă aici?
<%@ page language='java' %>
2 + 3.14 / 5 - int(4.44) = <%= 2 + 3.14 / 5 - (int)4.44 %>

Întrebări cu răspunsuri
1. În adresa următoare http://localhost:8080/test/welcomets0.jsp cum vă daţi seama
că s-a folosit motorul servlet Resin şi nu JRun
2. Care este ordinea de evaluare a unei expresii JSP: a. De la stânga la dreapta sau
b. De la dreapta la stânga. Iată expresia:
<%= new File(application.getRealPath(request.getServletPath())) %>

3. Priviţi lista următoare. Ce se realizează cu ea?


<html>
<! >
<! Servlet comentar1.jsp >
<! Autor Dan Somnea editia 0 >
<! Revizia 2. Azi 6 feb. 2003 >
<! >
<%@include file="inc/antet.inc" %>
<body>
<p> Urmeaza ca prin acest truc sa by-passez un fragment de cod JSP.
<p> Veti remarca ca (deschizand cu View - Source pagina sursei html), de aici va lipsi
<p> tocmai fragmentul de cod JSP baipasat!
<P>
<!--
<%-- Aceasta pagina a fost generata la data
si ora = <%= (new java.util.Date()).toLocaleString() %>
--%>
-->
<!--Aceasta pagina a fost generata la data de <%= (new
java.util.Date()).toLocaleString() %> -->
</body>
</html>

4. Cum facem să vedem rezultatul ultimei expresii din lista de mai sus?
5. Ce condiţii trebuie să fie îndeplinite ca o pagină jsp să funcţioneze ca pagină
interceptoare de erori?
6. Ce este greşit în liniile de mai jos?
<LI><a href="fruct2.jsp!fruct=mar">mar</a>
<LI><a href="fruct2.jsp?fruct=mar?fruct=par">mar si par</a>

7. Unde se transmite şirul de interogare următor:


<LI><a href="fruct2.jsp?fruct=mar">mar</a>

8. Care este şirul de interogare de mai sus? Comentaţi şi detaliaţi (contextul


browserelor Netscape, MSIE)
9. Un obiect implicit, out de exemplu, trebuie instanţiat de noi sau nu, adică vom
scrie ceva de genul JspWriter out = new.javax.servlet.jsp.JspWriter(); În ce
limbaj se scrie aici?
10. Orientându-vă după lista 4.2 încercaţi să descrieţi cu cuvintele dumneavoastră ce
face programul de mai jos:
<%@ page import="java.util.Enumeration" %>
<%
for (Enumeration e = request.getParameterNames();
e.hasMoreElements(); )
{
String nume_par = (String) e.nextElement();
String[] valori = request.getParameterValues(nume_par);
String lista_de_valori = valori[0];
int i;
while (i < valori.length)
lista_de_valori += ", " + valori[i];
out.println("<br>" + nume_par + " = " + lista_de_valori);
}
%>

11. Cine este servletul care preia datele formularului din lista 4.4b? Ce se transmite
la serverul Web? Când se transmite?
12. De ce i se spune radio button unei resurse de formular HTML?
13. Ce înseamnă boolean?
14. Priviţi lista 4.5a. Când întâlnim ceva de genul acesta:
String vizitator = getValues( request, "vizitator" );

înseamnă că metoda getValues() a obiectului request are acces la întregul şir de


perechi atribut=valoare corespunzător tuturor rubricilor formularului sau doar la
ceva anume?
15. Contemplaţi lista 4.5b. Fixaţi-vă atenţia asupra liniei:
if( cnp.equals("") ) {

Ce sunt: if, cnp şi equals? Ce se realizează aici?


16. Fie următoarea instrucţiune:
String tabelHTML = “<table border=\”0\”><tr><td>celula 1</td></tr></table>”;

Ce rost au caracterele \ care preced ghilimelele? Cine este tabelHTML?


17. Fie instrucţiunea de atribuire următoare:
String tableC = tabC+”</tr></table>”;

Ce este tabC, dar grupul de caractere încadrat de ghilimele?


18. Priviţi lista 4.5d. Cum ştie containerul servlet că aici este un program scris în
limbaj Java?
19. Când scriem:
"<%= DateFormat.getTimeInstance().format(new Date()) %>"

de ce nu folosim operatorul de instanţiere new ân expresia de mai sus?


20. Priviţi lista de mai sus. De ce se scrie new Date()?

Răspunsuri
1. Resin, deoarece este portul 8080. Serverul JRun Default foloseşte portul 8100.
2. b.
3. Este o pagină jsp. În prima parte este un comentariu clasic al HTML. Urmează o
directivă pentru includerea fişierului antet.inc. El rezidă în subdirectorul inc.
Urmează liniile banale ale unui document de tip HTML. Observăm un scriptlet;
dovadă prezenţa separatorilor <% şi %>. Acesta este însă încadrat de separatorii
comentariului de tip „ascunde cod”, <%-- şi -->. Când veţi vizualiza conţinutul
sursei cu MSIE pe traseul View, Source Code, veţi observa că acest scriptlet
lipseşte cu desăvârşire din fereastra denumită cod sursă, Source Code. Sunt
redaţi doar delimitatorii comentariului. Mai departe, vedem alt comentariu tot de
tipul „ascunde cod”. Aici însă apare o expresie JSP. Rezultatul evaluării sale se
poate vedea doar în fereastra Source Code şi redă data şi ora conform tipicului
de scriere al fusului local.
4. Dăm la o parte separatorii <!—şi -->
5. Două condiţii: în directiva page să fie atributul isErrrorPage plasat pe true, să
existe o expresie <%=exception %>.
6. Două lucruri. În prima linie se foloseşte semnul mirării în locul semnului de
interogare, iar în a doua, semnul interogării în loc de caracterul &.
7. La serverul Web unde este prelucrat de un servlet.
8. ”fruct2.jsp?fruct=mar”. Dacă am avea două sau mai multe cuvinte separate prin
caractere care dau probleme la unele browsere (Netscape) trebuie să recurgem la
metoda de substituire, encode a clasei URLEncoder. Ea substituie blancurile cu
caracterele %20 etc. MSIE nu are probleme!
9. Nu! Noi nu vom scrie niciodată linia din limbajul Java. Cel care o generează este
motorul servlet.
10. Se face exact acelaşi lucru care se realizează cu lista 4.2 doar că se recurge la
blocul while. Variabila de indecsare a blocului while ne ajută să alcătuim pas cu
pas un literal ce constă din valorile sosite în şirul de interogare URL, pe care
metoda getParameterNames() le preia din şir. Obiectul request este specializat în
analizarea perechilor atribut=valoare.
11. Fişierul mypisi_raspunsuri.jsp. Un şir de interogare este alcătuit din perechi de
atribute=valoare şi este delimitat prin caractere &. Semnul interogării (?) separă
partea de bază a adresei în sens URL de restul şirului. Dacă valoarea este
alcătuită din mai multe cuvinte, pot apare semne plus (secvenţe escape) la
serverul Web în locul spaţiilor sau semne %20 aşa cum sunt redate în tabelul
4.1. La momentul când am acţionat butonul de tip submit, faptul este echivalent
cu apăsarea pe tasta Enter, când ar fi fost focalizată ultima rubrică a
formularului. Focalizată, adică cea care era redată mai distinct!
12. Citiţi anexa A.
13. Este un cuvânt cheie al limbajului Java, prin care variabila este una logică.
Boolean poate avea doar două valori: adevărat (true) sau fals (false).
14. Da are acces la tot şirul de perechi, dar extrage doar valoarea rubricii vizitator!
15. Cuvântul if este o instrucţiune din limbajul Java. Serveşte la testarea unei
condiţii. Se verifică dacă variabila cnp „conţine” un şir vid. Când rubrica cnp,
cod numeric personal, ar rămâne necompletată, în variabila cnp nu va fi nimic.
Cuvântul equals se referă la denumirea metodei clasei String. În sfârşit, cnp este
o variabilă de tip String.
16. Prezenţa barei inverse înaintea ghilimelelor este necesară deoarece ghilimelele
sunt considerate delimitator de literal (Java). Şi, HTML foloseşte ghilimelele cu
alt sens. Ca să ajungă a fi tratate de HTML, orbim compilatorul prin plasarea în
faţa ghilimelelor a acestui caracter (\). Denumirea tabelHTML este o variabilă
de tip şir de caractere.
17. Denumirea tabC trebuie să fie definită tot ca variabilă de tip şir, aşa cum este
definită şi variabila tableC. Expresia dintre ghilimele este un literal în sensul
limbajului Java.
18. Datorită delimitatorilor <%! şi %>.
19. DateFormat este o clasă abstractă ca şi clasele obiectelor implicite. Numai că
obiectul DateFormat are o utilizare mai sporadică de aceea nu mai este instanţiat
automat de către JVM.
20. Date este o clasă explicită nu abstractă. De aceea este nevoie de operatorul new.
7
Capitolul

Primii paşi în tehnologia ASP


Microsoft a avut oportuna idee de a dezvolta colecţia obiectelor ActiveX şi
limbajul Visual Basic, un liant al tuturor programelor din suita Office. Nu ne
apucăm să explicăm ce este ActiveX şi Visual Basic (VB). Presupunem că aveţi
cunoştinţe extrem de puţine despre un limbaj de programre procedural. VB este
reprezentat de câteva subfamilii: Visual Basic nativ, Visual Basic for
Applications (cel al Excel-ului), Visual Basic for Scripting (prescurtat VBScript).
VB nativ este familiar tehnologiei ASP.NET. Varianta VBScript este folosită în
tehnologia ASP.
Când vorbim de tehnologia ASP, siturile Web, deci şi siturile comerciale, sunt
administrate de unul dintre serverele Web ale platformei Microsoft Windows.
Este vorba fie de Personal Web Server (Windows 98) fie de Information Internet
Server (Windows NT), vezi şi introducerea.
Cu începere din acest capitol ne vom ocupa mai în detaliu de tehnologia Active
Server Pages, decât am făcut-o în referinţa /1/.
Există păreri potrivit cărora tehnologia ASP ar fi mai oportună pentru
construirea siturilor mai ... firave! Este o abnormitate! Nouă ni se pare destul de
prietenoasă şi destul de flexibilă această tehnologie. Oricum, politica răspândirii
tehnologiilor este una de care nu este cazul să ne ocupăm.

S
ă vedem mai întâi de ce avem nevoie în materie de suport software cu pretenţii
mai modeste. Am spus-o şi în introducere, fără un pachet care face legătura cu
bazele de date (MS Access, în cel mai bun caz, MS SQL Server) nu putem face
un pas! Vizitatorii unui sit comercial trebuie înregistraţi, la fel şi coşurile lor de
cumpărături, comenzile pe care le fac. Unde altundeva decât în baze de date.
Când vrem ca să aibă acces simultan la magazinul virtual mai mult de 30 vizitatori,
cumpărători este nevoie de Microsoft SQL Server.
În sfârşit, doar pentru scop didactic, ne este extrem de suficient MS Access.
Limbajul de bază al tehnologiei ASP este Visual Basic for Scripting, VBScript.
Ar mai trebui să recurgem la serviciile unui container pentru servleturi?
Nu, fiindcă acest VBScript este un limbaj interpretat pe loc de către serverul Web al
platformei Windows! Deci nu mai are loc o traducere prealabilă a codului sursă
VBScript într-un cod de octeţi, cum era în cazul tehnologiei Java Server Pages.
Scade într-adevăr puţin performanţa, dacă avem parte de un sit foarte vizitat şi, mai
avem şi proasta inspiraţie de a recurge la MS Access în loc de MS SQL Server!
Este cert că viteza de execuţie a unui cod de octeţi este mai mare decât interpretarea
unui program sursă! Bibliotecile EJB din platforma Java se spune că sunt extrem de
perfomrante. De aceea sunt vândute pe bani grei! Au de ce să se îngâmfe cei de la Sun,
dar politica lor eremetică de acceptare a unei versiuni „tiny” în mediul didactic nu prea a
fost agreată de către Sun!
Apropo de portabilitatea cu care se laudă platforma Java. Microsoft nu este o firmă de
neluat în seamă. Vezi şi informaţiile despre acele servere 2000 ale platformei anunţate în
introducerea la carte în limba română. Alte dovezi : cei de firma ChiliSoft (vezi /6/) au
conceput prin anul 1999 pachetul Chili!ASP, prin care s-a permis folosirea tehnologiei
ASP de sub controlul serverelor Apache, Netscape Entreprise, O’Reilly Website Pro,
Lotus Domino Go Webserver. Se spune că ar exista PWS sau IIS chiar pentru platforma
Macintosh.
Chit chat! Să trecem mai bine la fapte!

Ce este o pagină ASP?


Este un fişier de tip text ca şi pagina .jsp. Aici însă extensia este .asp. Acest fişier conţine
în afara nelipsitelor porţiuni scrise în HTML şi scenariile realizate în VBScript, JScript.
Nu ne ocupăm decât de VBScript. Priviţi două ipostaze simple în lista de mai jos.
LISTA 7.1 Pagina salut1.asp

<HTML><BODY>
<%
' Folosirea obiectului implicit Response
response.Write("Bine ati venit in magazinul nostru virtual!")
%>
<%
' O pagina in care afisez data si ora
%>
<p>Acum suntem in data de <%=DATE()%>.
<p>Si la ora <%=TIME()%>
</BODY></HTML>
Explicaţii şi parafraze
Remarcaţi că am recurs la litere mari pentru a marca părţile mai evidente ale HTML ca
şi denumirile funcţiilor DATE( ), pentru dată, sau TIME( ), pentru oră. Mai remarcaţi că
separatorii pentru scriptleţi sunt identici ca la tehnologia JSP.
Sunt admise comentarii în interiorul scenariului aşa cum se vede mai sus. Comentariul
începe cu un apostrof în prima coloană. Dacă plasaţi cometariile în afara scriptleţilor ei
apar în fereastra browserului!
În sfârşit, remarcaţi caracterul identic al expresiilor. Tehnologia ASP are alt termen
pentru expresii. Îi spune „dată de ieşire”. Cât priveşte delimitatorii pentru datele de ieşire
ei sunt identici ca la Java Server Pages, şi anume: <%= şi %>. Iată cum arată aspectul
documentului din ferestra clientului Web (MSIE):

FIGURA 7.1 Aspectul ferestrei documentului MSIE, pentru pagina salut1.asp

Într-o pagină ASP se admit scenarii scrise într-un dialect al limbajului JScript (un fel de
JavaScript al Microsoft). Există chiar şi PerlScript. Nu ne ocupăm şi de aşa ceva!
Sunt câteva probleme de lămurit.
Mai întâi ce flux de caractere se trimite spre clientul Web? La browserul MSIE nu ajung
şi scenariile ci numai rezultatul interpretării acestora. Interpretarea are loc la serverul
Web. VBScript am spus-o şi o repetăm, nu este un limbaj care să necesite compilare ci
interpretare.
A interpreta înseamnă a executa pe loc acea instrucţiune VBScript! Când modificăm o
pagină cu extensia .asp cu orice editor de texte (după ce accedem situl prin adresa sa în
sensul URL, vezi partea de sus a figurii 7.1, http://localhost/alias/nume_pagina.asp),
serverul Web încarcă fişierul nume_pagina.asp, care se află în directorul echivalent
aliasului. Apoi, interpretează pe loc instrucţiunile din scenariile aflate în această pagină.
Deci la clientul Web vine exact fluxul de caractere din poza de mai sus!
Cine este response, dar Write? Suntem doctori în tehnologia JSP! Dacă nu, atunci
response este denumirea obiectului răspuns (întocmai ca la JSP). Metoda nu mai este
println( ) ci, Write.
Să ne relaxăm faţă de JSP! Nu se mai cere acea exactitudine în privinţa transcrierii
denumirilor metodelor şi obiectelor. În ASP nu se face distincţie între literele mici şi
mari ca în tehnologia JSP. Slavă Domnului!
Am afirmat mai sus denumirea alias. După instalarea serverului Web, sistemul de
operare Windows porneşte automat acest server (IIS sau PWS, depinde de sistemul de
operare instalat). În acest manual am recurs la serviciile serverului Microsoft IIS 5,
fiindcă sistemul de operare instalat era Windows 2000 Professional Workstation.
Cum a apărut acel cuvânt olga în adresa de mai sus? Iată procedeul:

1. Am efectuat clic pe pictograma aflată pe suprafaţa de lucru.


Am ales fila Advanced, avansat (figura 7.3). A apărut o fereastră
asemănătoare cu aceea din figura de mai jos. Prin intermediul butonului
Browse, răsfoire, am ajuns în directorul c:\Inetpub\wwwroot\olga. De fapt
directorul c:\Inetpub\wwwroot este aşa-zisul fake-root al serverului IIS (PWS),
iar olga este un subdirector al său.

FIGURA 7.2 Fereastra Add Directory

2. În alias am scris „exemple didactice”, apoi am efectuat clic pe OK. În acest


moment am revenit în fereastra din figura următoare şi de aici am ieşit în modul
uzual.
FIGURA 7.3 Fila Advanced a serverului Web (PWS, IIS)

FIGURA 7.4 Fila olga Properties a directorului cu acelaşi nume

3. Procedura nu s-a terminat. Ajungem în directorul olga (prin MyComputer, sau


Windows Explorer), efectuăm clic pe dreapta, cu mausul plasat chiar pe
denumirea olga.
4. Alegem opţiunea properties, proprietăţi (figura 7.4) apoi fila sharing, adică
accesibil şi altora. Selectăm opţiunea Share this folder, acces la acest director
pentru toţi. Accesul va fi doar în citire nu şi în scriere! Vă recomandăm să nu
permiteţi accesul la scenariu şi în scriere! Denumirea alias în cazul de mai sus
este chiar a unui subdirector la directorul wwwroot. Putea foarte bine ca situl
nostru să fie în cu totul alt loc pe disc. Atunci, am fi urmat procedura de mai
sus. Trebuia înscris rubrica alias (figura 7.2) o denumire pentru specificaţia de
cale, care ar fi rezultat din răsfoirea ierarhiei de directoare, ca să ajungem în
directorul gazdă a paginii ASP. În acest caz, denumirea de alias se justifică
întrucât ea substituie complicata specificaţie de cale la acest director!
Gata! De aici încolo, calea este liberă! Remarcaţi tipicul adresei URL din figura 7.1 de
mai sus.
Fake-root-ul, adică rădăcina „mutantă” a serverului Microsoft IIS (PWS) este de regulă
c:\Inetpub\wwwroot. Şi acest server are un director AdminScript, care este plin cu tot
felul de fişiere scrise în limbajul VBScript. Toate au extensia .vbs. Rostul lor este de a
pregăti, iniţializa aplicaţia PWS, alias IIS, când se lansează aceasta.
Ne oprim aici cu chestiunile prea tehnice şi revenim la iniţierea în ASP. Să ne ocupăm
acum de scrierea unui mesaj lung care să aibă şi caractere speciale. Priviţi lista 7.2.
LISTA 7.2 Pagina salut_cam_lung.asp

<HTML><BODY>
<%
Response.write "Bine ati venit in magazinul nostru virtual " &_
"construit dupa regulile tehnologiei Active Server " &_
"Pages. Aici sunt preturile cele mai scazute. Daca " &_
"gasiti altundeva in oras ceva mai ieftin de vineri " &_
"pana luni, veniti luni dimineata inapoiati marfa " &_
"si va restituim banii pe loc!"
%>
<P><FONT FAMILY="Verdana" SIZE="5" COLOR="BLUE">
<%
' Ocolirea diacriticelor
response.write server.htmlencode("Ne zice: <<La ...ache!>>")
%>
</FONT></BODY></HTML>

FIGURA 7.5 Aspectul documentului salut_cam_lung.asp


Explicaţii şi parafraze
Remarcaţi sintaxa şirului de caractere din instrucţiunea response.write. Mai remarcaţi
lejeritatea scrierii cuvântului response. Nu se face distincţie între literele mari şi cele
mici.
Pentru trimiterea caracterelor „cu probleme” cum sunt caracterele < şi >, dar şi altele,
care au un rost în limbajul VBScript, trebuie recurs la metoda htmlencode(). Putea fi
transcrisă şi ca HTMLEncode() sau HtmlEncode() etc.
Această metodă este a obiectului implicit server.
Cu ce obiecte implicite lucrăm în ASP?
Numai cu şase obiecte, nu cu nouă, ca în JSP. Acestea sunt denumite: aplicaţii
(applications), server, cerere (request), răspuns (response), sesiune (session) şi contextul
obiectului (objectcontext). Nu vi se pare mai lizibilă notaţia Applications, Response,
Request, . . . , ObjectContext? Sigur că da! Dar nu este o obligaţie a transcrie exact aşa!
Nu vă speriaţi că nu o să ne apucăm să vă povestim ce rost are fiecare obiect implicit. În
exerciţiul nostru despre un sit comercial ne vom întâlni numai cu request, foarte rar cu
response, server şi session.

Câteva noţiuni despre VBScript


Am aflat deja sintaxa comentariului şi faptul că nu se face distincţie între literele mici şi
mari.
VBScript operează cu variabile. De pildă scriem:
pretProdus = 0

Variabila „scalară” pretProdus capătă valoarea zero. Este o variabilă numerică. Evident
că putem memora valori cu zecimale. Există desigur operatorii pentru: adunare, scădere
etc. Nu intrăm în detalii. Există şi variabile de tip text, ca mai jos:
sqlString = "SELECT DISTINCT categorie_produs FROM Produse "

Faptul că scriem cu litere mari este doar din motivul lizibităţii. Variabila sqlString este
tot una cu sqlstring sau SQLstring. Ea capătă o valoare. I se spune literal. Literalul este
încadrat de ghilimele. De fapt exemplul de faţă se referă la începutul unei comenzi SQL.
Dar despre SQL vom vorbi în paragraful următor.
Variabilele de tip text se pot alipi (de la englezescul concatenate). Iată un caz:
sqlString = sqlString & "WHERE stare_produs=1 "

Conţinutul variabilei sqlString se prelungeşte cu literalul WHERE ... Deci acum


sqlString va conţine textul SELECT DISTINCT categorie_produs FROM Produse
WHERE stare_produs=1. Operatorul de alipire este &.
Există şi variabile care preiau obiecte:
numeProdus = RS("nume_produs")
Aici obiectul este RecordSet, un tabel rezultat în care se livrează un răspuns după
analiza unei baze de date. Mai multe tabele alcătuiesc o bază de date.
Există şi constante de tip citeşte numai. Iată un caz:
CONST numVitrina = 3

În numeVitrina nu mai putem înscrie altă valoare şi nu îi putem schimba tipul.


Să ne referim puţin la unele instrucţiuni pe care le întâlnim în exemplul nostru complex
de sit comercial.
Mai întâi instrucţiunea if. Dăm câteva ipostaze. Primul este unul mai simplu:
IF caracteristiciProdus = "" THEN
caracteristiciProdus = "nil"
END IF

Dacă variabila caracteristiciProdus nu conţine nici un literal (în jargon se spune: conţine
un şir vid, şi notaţia din program este “”), atunci ea va primi textul literal nil. Cei care
lucrau în urmă cu vreo 25 ani în urmă în limbajul Pascal îşi amintesc că şirul vid se
numea nil şi îl notau ””. Observaţi delimitatorii literalului. Orice IF se încheie cu un
ENDIF.
Putem scrie aşa:
IF cat = "" THEN cat = "Acasa"

sau aşa:
IF cat = "" THEN
cat = "Acasa"

efectul este acelaşi: dacă variabila cat este vidă (deci nil în sensul Pascal), atunci lui cat i
se va atribui literalul Acasa.
Evident instrucţiunea IF poate avea şi alternativa ELSE, ca mai jos:
IF RS.EOF THEN
dejaInBD = FALSE
ELSE
dejaInBD = TRUE
END IF

Dacă obiectul notat prin RS, de tipul RecordSet, a fost parcurs şi s-a ajuns la finalul său,
adică la EOF, end of file, atunci variabila dejaInBD capătă valoarea logică FALSE, în
caz contrar, valoarea TRUE. Deci în VBScript se operează şi cu variabile logice şi nu
numai cu cele întregi sau cu zecimale.
Să mai complicăm puţin lucrurile! Există şi tot felul de funcţii. Iată un prim caz:
IF isNumeric(newQ) THEN
RS("cantitate_cos") = newQ
END IF
Dacă în variabila newQ se află o valoare numerică întreagă sau cu zecimale
(isNumeric), atunci câmpul denumit cantitate_cos din rezultatul RS, va prelua conţinutul
variabilei newQ. Deci funcţia a fost isNumeric(). Alt caz:
FUNCTION SELECTED(valoare1, valoare2)
IF cSTR(valoare1) = cSTR(valoare2) THEN
SELECTED = "SELECTED"
END IF
END FUNCTION

Aici apare o funcţie de bibliotecă cSTR() şi o funcţie creată adhoc, denumită


SELECTED. Acesta nu este decât un tipic de scriere. Am dorit să fie mai vizibilă
denumirea funcţiei SELECTED. Funcţia cSTR() converteşte un întreg în şir de caractere
(literal). Variabilele păstrătoare de numere întregi sunt denumite valoare1 şi valoare2. În
cazul contextului de faţă, valoare1 şi valoare2 sunt parametrii fictivi, argumentele
fictive. Acestea primesc drept conţinut valori din partea argumentelor reale la momentul
apelului. Dacă conţinutul este identic (operatorul de comparaţie este aici semnul egal),
se va atribui variabilei SELECTED valoarea „SELECTED”. E admis aşa ceva? Da ! Nu
am greşit! Funcţia noastră va întoarce un rezultat, iar acesta am hotărît să fie şirul de
caractere SELECTED. Putea foarte bine să întoarcă un întreg sau un număr zecimal sau
o valoare logică adevărat (TRUE) sau fals (FALSE).
Iată o expresie mai complicată în IF:
IF newQ = "" OR newQ = "0" THEN
RS.Delete

Când conţinutul variabilei newQ este cifra 0 sau nimic (nil adică şir vid în sens Pascal),
numai atunci se execută ştergerea rândului curent din obiectul RS. Aici am întâlnit la
lucru atât SQL cât şi VBScript!
Priviţi alt fel de operator de comparaţie:
IF RS("caracteristici_produs") <> "nil" THEN

Semnele <>, numai când sunt alăturate, au semnificaţia de „diferit”. Deci dacă rubrica
caracteristici_produs din RecordSet este diferit de textul „nil“, se execută ce urmează
după THEN.
IF topVitrina <= numVitrina THEN skip = 1

Când conţinutul variabilei topVitrina este mai mic sau egal (<=) decât conţinutul
variabilei numVitrina, atunci variabila skip va căpăta valoarea 1.
IF NOT RS.EOF AND camp_cautare <> "" THEN

Dacă nu s-a ajuns la finalul tabelului rezultat alias obiectul RS şi dacă în acelaşi timp
valoarea din camp_cautare este diferită de un şir vid, atunci se execută toate
instrucţiunile ce urmează după THEN.
Acum iată o comparaţie pe dos:
IF NOT RS.EOF THEN
numeProdus = RS("nume_produs")
pretProdus = RS("pret_produs")
caracteristiciProdus = RS("caracteristici_produs")
categorieProdus = RS("categorie_produs")
produsDeVitrina = RS("produs_de_vitrina")
ENDIF

Explicaţii
Dacă nu s-a ajuns la finalul obiectului RecordSet, reamintim este un tabel cu diverse
coloane cu anumite denumiri, se vor transmite valorile lor unor variabile locale precum:
numeProdus etc.
Să mai trecem la alte funcţii de bibliotecă. De pildă aici:
parolanoua = TRIM( Request( "parolanoua" ) )

variabila parolanoua îşi va modifica conţinutul. Dacă ea conţinea ”abc de f”, după ce se
execută funcţia TRIM (trimitere blancuri la spate) ea va deveni ” abcdef ”. Cu alte
cuvinte spaţiile (programatorii le spun şi blancurile) se adună la coada literalului.
Sau iată ceva cu o notaşie şi mai … fistichie:
eliminProdus = TRIM(Request("pq" & RS("id_cos")))

Variabila eliminProdus va fi alcătuită din două şiruri alipite. Primul şir conţine literele p
şi q, scrise alăturat. În continuare al doilea şir provine de la ceea ce întoarce obiectul
RecordSet din coloana id_cos. Să ne închipuim că acest id_cos ar avea 34. Şirul
rezultant va fi pq34.
Când vedeţi obiectul request, să faceţi automat în cap asociaţia următoare: „aici este
vorba de o cerere care vine de la clientul Web la serverul Web. Această cerere provine
fie în urma unui clic efectuat pe butonul submit al formularului, fie de la un şir de
interogare aflat pe o legătură de tip hypertext.
Să adâncim ultima afirmaţie. Atunci suntem obligaţi ca să întrerupem seria explicaţiilor
asupra limbajului VBScript, şi să trecem la limbajul ASP.

Şirul de interogare în ASP


Iată un exemplu format din două pagini care tratează şiruri de interogare:
LISTA 7.3 Pagina lafructar.asp

01. <html>
02. <head><title>La fructar</title> </head>
03. <body>
04. Alege doar un fruct:
05. <%
06. ceFructAleg = "Mandarine de Grecia"
07. ceFructAleg = Server.URLEncode( ceFructAleg )
08. ceSortAleg = "Mandarine mai mici, dar suculente"
09. ceSortAleg = Server.URLEncode( ceSortAleg )
10. %>
11. <p><a
href="aleg.asp?fructe=<%=ceFructAleg%>&tip=<%=ceSortAleg%>">Mandarine
de Grecia</a>
12. <%
13. ceFructAleg = "Mandarine de Cipru"
14. ceFructAleg = Server.URLEncode( ceFructAleg )
15. ceSortAleg = "Mandarine mai mari, cu coaja mai groasa dar extrem de dulci"
16. ceSortAleg = Server.URLEncode( ceSortAleg )
17. %>
18. <p><a
href="aleg.asp?fructe=<%=ceFructAleg%>&tip=<%=ceSortAleg%>">Mandarine
de Cipru</a>
19. <%
20. ceFructAleg = "Ionatane de Turcia"
21. ceFructAleg = Server.URLEncode( ceFructAleg )
22. ceSortAleg = "Mere mari Ionatane"
23. ceSortAleg = Server.URLEncode( ceSortAleg )
24. %>
25. <p><a
href="aleg.asp?fructe=<%=ceFructAleg%>&tip=<%=ceSortAleg%>">Ionatane
Turcesti</a>
26. <%
27. ceFructAleg = "Mere de Voinesti"
28. ceFructAleg = Server.URLEncode( ceFructAleg )
29. ceSortAleg = "Mere mai mici dar grozav de aromate"
30. ceSortAleg = Server.URLEncode( ceSortAleg )
31. %>
32. <p><a
href="aleg.asp?fructe=<%=ceFructAleg%>&tip=<%=ceSortAleg%>">Mere de
Voinesti</a>
33. </body>
34. </html>

şi pagina aleg.asp
LISTA 7.4 Pagina aleg.asp

<html>
<head><title>La fructar</title> </head>
<body>
Ai ales urmatoarea marfa:
<p>Fructul <%=Request.QueryString( "fructe" )%>
<p>Sortul <%=Request.QueryString( "tip" )%>
</body>
</html>

Explicaţii şi parafraze
Să ne fixăm atenţia pe pagina intitulată lafructar.asp. Ea conţine mai multe scenarii.
Priviţi delimitatorii de scriptleturi din dreptul liniilor cu numerele 05, 10, 12, 17, 19, 24,
26 şi 31.
Denumirea Server din faţa funcţiei URLEncode se referă la obiectul server. De
exemplu, instrucţiunea din linia 21 va încărca în variabila denumită ceFructAleg o
valoarea, rezultată din transformarea funcţiei URLEncode(). URLEncode face cam
acelaşi lucru ca şi funcţia HTMLEncode(), întâlnită mai sus. Ea înlocuieşte caracterele
speciale (spaţii etc.) cu aşa-zisele „secvenţe escape” întâlnite în capitolul 5, tabelul 4.1
(tehnologia JSP).

Din nou … VBScript


După această divagaţie să revenim la VBScript.
Am afirmat că obiectul implicit request se ocupă şi de şiruri de interogare. Când faceţi
un clic pe una dintre legăturile de tip hypertext din figura 7.6, se trimite spre serverul
Web un şir de interogare. Priviţi liniile numeroatate cu 11, 18, 25 sau 32. Tot ce vine
după semnul întrebării se numeşte şir de interogare. Observaţi acum lista paginii
aleg.asp. În liniile 05 sau 06 apare obiectul request. Deci obiectul request se ocupă şi de
şirurile de interogare. Aceasta am dorit a vă spune.
Avem tot timpul să explicăm mult mai uzitatul caz al formularului, unde obiectul
request îşi face simţită prezenţa din nou.

FIGURA 7.6 Aspectul documentului paginii lafructar.asp

Să abordăm buclele for şi while în ASP.


Bucla for este delimitată de instrucţiunile for şi next:
FOR i = 1 To LEN( digits) STEP 1
checkSum = checkSum + CINT( MID( digits, i, 1 ) )
NEXT

Explicaţii şi parafraze
Blocul for este alcătuit aici doar dintr-o singură instrucţiune. Pot fi oricâte la număr. Se
admite şi for în for! Variabila de indexare este i. LEN este o funcţie de bibliotecă ce
întoarce numărul de caractere din variabila digits. Admiteţi că variabila digits ar conţine
drept literal, un şir de cifre „23456”. Atunci len(digits) va da valoarea 5. Variabila de
indexare i va creşte cu câte o unitate (Step 1). Evident după STEP putea urma o expresie
complicată.
Să vedem ce se întâmplă în variabila checkSum. Aici se totalizează nişte valori
numerice. Valoarea numerică este obţinută graţie funcţiei de conversie din tip caracter în
tip întreg. Se numeşte CINT(). Evident ce trebuie convertit trebuie să fie un şir de cifre.
Provoţi acum funcţia MID(). Ea acţionează precum un vizor care se mută de la un
caracter la altul al şirului. Mai exact se preia din şirul digits doar câte o singură cifră. De
ce numai una? Fiindcă este scrisă forma MID(digits, i,1), acel 1 din ultima poziţie spune
că este vorba de un singur caracter. De fiecare dată conţinutul variabilei i creşte cu câte
o unitate. Prima dată i este egal cu 1, apoi cu 2, ş.a.m.d. Deci se iau la rând cifrele şi se
extrag din … digits. Atunci checkSum va conţine în final 2+3+4+5+6, deci valoarea 20.
Să privim un caz mai complicat de bloc for:
01. FOR EACH resursa IN Request.Form
02. %>
03. <input name="<%=resursa%>" type="hidden"
value="<%=Server.HTMLEncode(Request(resursa))%>">
04. <%
05. NEXT

Explicaţii şi parafraze
Aici am numerotat liniile. Scenariul este alcătuit doar din liniile 01 şi 05. De ce? Priviţi
ordinea delimitatorilor. Mai întâi în linia 02 se află delimitatorul de sfârşit de scenariu.
Se intră „pe teritoriul” HTML în linia 03. În linia 04 se revine înapoi. Ce se realizează în
linia 03? Aici se preia în variabila resursa, valoarea întoarsă de metoda HTMLEncode a
obiectului Server. Această metodă a preluat la rându-i, de la obiectul request (denumit
tot resursa) un şir de caractere. Acest şir de caractere este denumirea unei rubrici de
formular. Din lista de mai sus nu apare explicit acest lucru. Veţi vedea aceiaşi secvenţă
când va fi vorba de lista respectivă a exemplului de sit comercial, tratat mai jos pe
îndelete. Deci una peste alta în variabila resursa vor figura pe rând denumirile rubricilor
unui formular.
Remarcaţi şi enunţul din linia 01. Obiectul request se ocupă de rubricile formularului şi
preia denumirile logice ale acestora. Că aceste rubrici sunt de tipul ascuns, hidden, este
mai puţin important. O rubrică (echivalentul lui input name = ...) de tip ascuns
(type=”hidden”) nu se afişează pe ecranul browserului!
Să privim spre o construcţie de bloc while. Iată secvenţa:
01. WHILE NOT RS.EOF
02. %>
03. <tr>
04. <td><%=RS( "id_comanda" )%></td>
05. <td><%=RS( "data_intrare_comanda" )%></td>
06. <td><%=RS( "nume_produs" )%></td>
07. <td><%=arataStareComanda( RS( "stare_Comanda" ), RS(
"data_livrare_comanda" ) )%></td>
08. </tr>
09. <%
10. RS.MoveNext
11. WEND
Explicaţii şi parafraze
Scenariul este alcătuit din liniile 01, 10 şi 11. Atât! Restul liniilor sunt din HTML.
Denumirile tr şi td sunt balizele unui tabel HTML. În celulele tabelului afişat pe ecran,
se preia rubrică după rubrică datele obiectului RS în acest exemplu. Conţinutul său se
afişează pe ecran cu expresii de genul:
RS(”nume-de-rubrică”)

În linia 07 se afişează rezultatul funcţiei arataStareComanda(), o funcţie compusă de


programator şi nu din biblioteca VBScript. Ea foloseşte două argumente de intrare.
Blocul WHILE este delimitat de separatorul WEND. Instrucţiunea din linia 10 mută
„cursorul” obiectului RecordSet la rândul următor. Consideraţi acest rezultat RecordSet
un table cu rânduri. Acest avans la următorul rând are loc până se ajunge la sfârşitul
tabelului (condiţia RS.EOF din WHILE). Deci după WHILE urmează „expresia
condiţională”. Aceasta este evaluată de fiecare dată mai înainte ca să se execute întregul
grup de instrucţiuni dintre separatorii WHILE şi WEND. Grupul acestor instrucţiuni,
corpul while, se execută atâta timp cât condiţia se îndeplineşte.
Aici operatorul NOT inversează exprimarea. Spunem aşa: „cât timp nu s-a ajuns la
sfârşitul tabelului, execută instrucţiunile corpului while”.
Să aruncăm acum o privire spre funcţia arataStareComanda(). Iată conţinutul:
LISTA 7.5 Funcţia arataStareComanda

01. FUNCTION arataStareComanda( starea, dataLivrare )


02. ' Care este starea comenzii
03. SELECT CASE starea
04. CASE 0
05. arataStareComanda = "In curs"
06. CASE 1
07. arataStareComanda = "Produs nu este in stoc"
08. CASE 2
09. arataStareComanda = "Livrat la data de " & dataLivrare
10. CASE ELSE
11. arataStareComanda = "Stare necunoscuta"
12. END SELECT
13. END FUNCTION

Explicaţii şi parafraze
Linia 02 conţine un comentariu. Evident, acesta începe cu apostrof. Linia 03 se referă la
altă instrucţiune şi anume la SELECT CASE. În funcţie de valoarea variabilei
(argumentul fictiv) denumit aici starea, se execută una dintre ramurile CASE.
Argumentul stare a primit la apelare o anumită valoare şi anume, ce s-a transmis prin
RS(”stare_Comanda”).
Mai departe, se sare imediat după cuvântul END SELECT. Deci se ajunge la ieşirea din
funcţie. Funcţia mai face un lucru şi anume, atribuie celui de al doilea argument fictiv
dataLivrare, un text. El va fi unul dintre literalii cazurilor de mai sus. Acest argument
fictiv va transmite mai departe celui de al doilea argument real al apelului funcţiei
arataStareComanda(arg1, arg2) valoarea respectivă. Ea va fi aceea afişată pe ecran. În
construcţia SELECT de mai sus, sunt trei cazuri distincte CASE 1, 2 şi 3 şi un caz
general, CASE ELSE.
Acum să vedem ce se realizează în instrucţiunile de mai jos:
FUNCTION apostrof12(Sirul)
apostrof12 = REPLACE(Sirul, "'", "''")
END FUNCTION

Explicaţii şi parafraze
Funcţia are un singur argument fictiv intitulat Sirul. În cadrul său, se înlocuieşte fiecare
apostrof cu doi apostrofi. Funcţia REPLACE este o funcţie de bibliotecă VBScript. De
ce trebuie această substituţie? Uneori în cadrul câmpurilor unui formular putem avea
valori precum aceasta: Scotts’Company, compania lui Scotts. Dacă ar rămâne acest
apostrof şi, am vrea să înscriem această valoare într-o bază de date MS Access,
comanda INSERT INTO (SQL) nu ar funcţiona normal. MS Access (şi MS SQL
Server) consideră apostroful un delimitator de literal. Ca atare, nu s-ar înregistra decât
cuvântul Scott şi nu întregul text Scott’s Company. Comanda INSERT INTO ... s-ar
opri la primul apostrof din valoare.
Pentru a preveni această terminare prematură, dublăm apostroful, exact cum făceam cu
ghilimelele de mai sus. Este oportun să ne referim puţin şi la limbajul SQL. O vom face
imediat după ce tratăm un ultim aspect legat de funcţiile VBScript.
În exemplul de mai sus am trimis valori argumentelor fictive starea şi dataLivrare. Iată
un caz mai complicat ce este folosit în cadrul sitului comercial:
LISTA 7.6 Funcţia verificParola

01. FUNCTION verificparola(byVal numeclient, byVal parola, byRef Con)


02. sqlString = "SELECT id_client FROM Clienti " &_
03. "WHERE nume_client='" & numeclient & "' " &_
04. "AND parola_client='" & parola & "'"
05. SET RS = Con.Execute(sqlString)
06. IF RS.EOF THEN
07. verificparola = - 1
08. ELSE
09. …
10. END FUNCTION

Explicaţii şi parafraze
Este vorba de funcţia verificParola. Ea are trei argumente fictive. Primele două primesc
direct valoarea. Acest mod de transmitere prin valoare este cel uzual. Asta înseamnă că
în cadrul funcţiei se vor aloca două zone de memorie. Se copiază aici valorile
argumentelor reale. Ultimul argument fictiv comunică cu argumentul real prin …
adresă (byRef). El comunică cu obiectul denumit Con, care are legătură cu conexiunea
logică la baza de date. Amânăm explicaţiile despre Con. Ce înseamnă prin adresă. Se
alocă un grup de octeţi, dar aici se memorează adresa care punctează spre acel obiect
complicat Con. În liniile 02 – 04 observaţi o comandă SQL. De asemeni, o vom explica
în paragraful următor. La fel şi comanda SQL din linia 05. Restul liniilor sunt de acum
cunoscute dumneavoastră din prezentările făcute.
Am ales acest exemplu pentru a puncta aceste două moduri de transmitere a conţinutului
argumentelor reale în cele fictive.
Ce vrea să însemne transmiterea prin valoare am explicat.
Insistăm la transmiterea prin referinţă. În loc să se dedubleze întreaga structură de date,
care se întinde pe destui octeţi, cum este cazul obiectului Con, se trimite doar un număr.
Acesta este adresa de memorie unde se află stocaţi toţi aceşti octeţi referitori la obiectul
Con. Dacă s-ar trimite şi acest parametru prin valoare, ar fi şi o risipă inutilă de spaţiu de
memorie dar şi de timp. Nu are sens! Funcţia verificParola() va întoarce valoarea
întreagă -1, când nu este ceva în regulă cu parola vizitatorului sitului.

O privire fugară asupra limbajului structurat de


interogare SQL
SQL înseamnă Structured Query Language. Este prea de demult apărut ca să fie nevoie
să justificăm în faţa unui nespecialist de ce i se spune structurat şi de interogare. Cu
comenzile SQL într-adevăr în primul rând interogăm bazele de date. Să nu rămâneţi cu
impresia că cu SQL doar „interogăm”. Ca să interogăm trebuie mai întâi să creăm baza,
apoi tabelele sale, să încărcăm aceste tabele cu informaţie. De abia acum putem extrage
informaţiile pe care le dorim sau să le modificăm. Nu mai spunem nimic despre trecutul
limbajului de interogare structurat şi mai ales despre viitorul său!
SQL este un limbaj vast. De aceea preferăm să „decupăm” doar chestiunile care ne
interesează şi pe care le vom întâlni în aplicaţia noastră de comerţ electronic din
capitolele următoare.
Limbajul are multe instrucţiuni, funcţii şi proceduri. În exemplul nostru va fi vorba de o
bază de date, mypisi.mdb (.mdb este extensia unei baze create cu aplicaţia MSAccess).
Baza mypisi.mdb are vreo patru tabele: Produse, Clienti, Comenzi şi Cos. Fiecare tabel
poate fi creat, ca de altfel şi baza în sine, cu anumite instrucţiuni SQL.
Am creat baza mypisi.mdb şi tabelele sale cu ajutorul interfeţei grafice a aplicaţiei
MSAccess.
Un tabel are cum ştim un antet cu mai multe rubrici. Consideraţi antetul drept structura
de descriere a tabelului, iar rândurile sale drept înregistrări cu date.
Când trebuie să accedem unul sau mai multe tabele ale unei baze de date, dintr-un
program scris în VBScript? Va trebui ca mai întâi să se stabilească o conexiune logică
cu acea baza. Despre ea nu vom vorbi aici.
Orice bază de date este la urma urmei o resursă fizică. Programul o vede însă ca pe o
resursă logică. Du-te-vino-ul informaţiilor dintre program şi tabelele bazei nu s-ar putea
realiza decât după conectarea prealabilă la ea.
În capitolul următor vom descrie procedurile pentru atribuirea unei denumiri logice
pentru această conexiune, deşi am abordat acest subiect şi în capitolele dedicate
tehnologiei JSP.
Suntem mai interesaţi acum să tratăm SQL-ul ca atare, deci câteva dintre instrucţiunile
sale. Iată de pildă când scriem comanda aceasta:
SELECT id_produs, nume_produs FROM Produse

înţelegem că selectăm doar rubricile, câmpurile id_produs şi nume_produs din tabela


Produse, una din tabelele bazei mypisi.mdb.
Dacă am fi dorit să accedem toate rubricile tabelului am fi scris aşa:
SELECT * FROM Produse

Dacă vrem să selectăm cele două câmpuri şi să ordonăm după nume produs în ordinea
alfabetică (programatorii spun în ordinea lexicografică ascendentă!) vom recurge la o
comandă de genul acesta:
SELECT id_produs, nume_produs FROM Produse ORDER BY nume_produs

O selecţie după anumite criterii comportă o comandă SELECT de forma:


SELECT * FROM Produse WHERE id_produs = 3

Aici ne interesează doar produsul al cărui identificator este egal cu 3. Câmpul id_produs
are tipul număr nu text, de unde şi valoarea sa numerică.
Când scriem în VBScript comenzile SQL, trebuie să respectăm sintaxa limbajului
VBScript. Atunci iată un exemplu concret:
sqlString = "SELECT id_produs, nume_produs FROM Produse " &_
"ORDER BY nume_produs"

Comanda este un literal înregistrat în variabila sqlString. Fiindcă acesta am vrut să îl


transcriem pe două rânduri, am recurs la acest delimitator compus din două caractere:
&_. Recunoaştem că este destul de ciudat!
O altă ipostază tipică:
RS.Open "SELECT * FROM Produse WHERE id_produs=" & idProdus

Aici folosim metoda Open a obiectului RecordSet denumit aici RS. Ca argument real
pasat acestei metode, este literalul. Ne reamintim că un literal este încadrat de ghilimele
în VBScript. De ce şi notaţia & idProdus? Dacă aţi citit cele câteva pagini consacrate
limbajului VBScript, atunci ar trebui să ştiţi că operatorul de alipire este &. Faptul că în
loc de 3 am scris idProdus, a fost pentru că aici ne referim la o variabilă şi nu la o
valoare. Fireşte, ne-am luat măsurile de prevedere de a încărca în prealabil variabila
idProdus cu valoarea numerică, mai înainte de a executa această metodă.
Cum ar fi arătat din punct de vedere sintactic comanda de mai sus? Aşa:
SELECT * FROM Produse WHERE id_produs = idProdus
Să trecem la altă tabelă cu alte câmpuri. Putem să selectăm din tabela Clienti, toţi clienţii
cu numele Ionescu în coloana nume_client. În acest caz comanda ar fi arătat aşa:
SELECT nume_client FROM Clienti WHERE nume_client = ‘Ionescu’

Mergem mai departe! O comandă SQL SELECT, scrisă în limbajul VBScript arată cam
aşa:
sqlString = "SELECT DISTINCT categorie_produs FROM Produse "
sqlString = sqlString & "WHERE stare_produs=1 "
sqlString = sqlString & "ORDER BY categorie_produs"

Mai sus sunt de fapt trei instrucţiuni VBScript. În finalul parcurgerii acestora, variabila
sqlString va conţine întreaga comandă SQL:
SELECT DISTINCT categorie_produs FROM Produse WHERE stare_produs=1
ORDER BY categorie_produs

A apărut un lucru nou şi anume cuvintele ORDER BY. Separatorul ORDER BY


ordonează înregistrările tabelului după valorile din câmpul categorie_produs. Dacă
lipseşte separatorul ASC sau DES, se presupune ASC, adică ordinea de la A la Z.
Destul cu SELECT! Să trecem la altă comandă SQL şi anume la INSERT.
Când scriem aşa:
INSERT INTO Produse ( nume_produs, pret_produs, caracteristici_produs,
categorie_produs, stare_produs ) VALUES ( ‘LCD Relisys TL561’, 11999000,
‘17”/ 0.29 pixel/ rezolutie maxima1024x768/luminozitate 300:1/TCO99 TUV FCC_B
UL ISO 13406-2‘,‘monitor‘,‘activ‘ )

de fapt anunţăm din VBScript că vom recurge la o inserţie a unui rând în tabelul
Produse. Valorile pe care le înscriem în noua înregistrare se află în lista de după
separatorul VALUES.
Deci INSERT ca formă, este urmat de separatorul INTO, apoi de denumirea tabelului,
de o listă de denumiri de rubrici. Lista este încadrată de paranteze ronde. Mai departe
vine separatorul VALUES şi în final, din nou o listă de valori sau de variabile VBScript.
Dacă sunt valori, atunci cele de tip literal sunt încadrate între apostrofi. În schimb
valorile întregi (pret_produs, 11999000) se transcriu direct fără apostrofi.
Dacă aceste valori ar fi provenit din variabile de tip VBScript şi dacă, aceste variabile se
numeau numeProdus, pretProdus, caracteristiciProdus, categorieProdus şi stareProdus,
am fi rescris comanda în modul următor. De data aceasta am respectat regulile sintactice
ale limbajului VBScript. Este ceva mai complicat, dar urmăriţi cu atenţie:
sqlString = "INSERT INTO Produse " &_
"( nume_produs, pret_produs, caracteristici_produs, categorie_produs, stare_produs )
VALUES ( " &_
" '" & numeProdus & "', " &_
pretProdus & ", " &_
" '" & caracteristiciProdus & "', " &_
" '" & categorieProdus & "', " &_
stareProdus & " )"
Explicaţii şi parafraze
Observaţi separatorul pentru prelungirea unui literal pe mai multe linii în VBScript. Mai
observaţi (poate mai greu) prezenţa unor apostrofi încadraţi de ghilimele. Aceasta
deoarece elementele listei VALUES sunt încadrate de apostrofi. Vă amintiţi de funcţia
apostrof12. Spuneam cu acea ocazie că trebuie să dublăm apostrofii. În transcrierea
VBScript se începe cu un apostrof şi, dacă valoarea ar conţine un apostrof, interpretorul
de comenzi SQL s-ar „împotmoli” la primul apostrof terminal de valoare. De exemplu
valoarea Scott’s Company nu s-ar înregistra corect în tabel.
Mă rog, noi în româneşte nu folosim apostrofii în denumiri!
Încă ceva. Doar un singur câmp, pretProdus este numeric în acest exemplu. Celelalte trei
câmpuri sunt de tip text.
Observaţie: Pe cei care cunosc SQL îi rog să nu se supere că nu ne abatem de la subiect,
ca să povestim multiplele tipuri de date din SQL. Ar fi o prea mare paranteză care nu ar
fi necesară unui nespecialist în programare.
Priviţi cu atenţie că denumirea pretProdus nu mai este încadrată de apostrofi, cum se
întâmplă cu celelealte trei câmpuri.
O altă comandă SQL este şi cea de actualizare a rândurilor unui tabel. Se numeşte,
UPDATE. Iată una din formele sale:
UPDATE Produse SET nume_produs = ' DVD-ROM', pret_produs = 4999000,
caracteristici_produs = 'diverse caracteristici’, categorie_produs = 'DVD'",
produs_de_vitrina = 1, stare_produs= 'ACTIVA'
WHERE id_produs = 4

Explicaţii şi parafraze
Aici câmpurile pret_produs şi produs_de_vitrina sunt numerice, în timp ce restul
câmpurilor sunt de tip text, caracter este acelaşi lucru. Deci se menţine consistentă
regula apostrofilor.
Transcrierea VBScript mai generală este mai greoaie. Apar şi o serie de variabile în loc
de valori exacte. Iat-o:
sqlString = "UPDATE Produse SET " &_
"nume_produs='" & apostrof12( numeProdus ) & "'," &_
"pret_produs=" & cCUR( pretProdus ) & "," &_
"caracteristici_produs='" & apostrof12( caracteristiciProdus ) & "'," &_
"categorie_produs='" & apostrof12( categorieProdus ) & "'," &_
"produs_de_vitrina=" & produsDeVitrina & "," &_
"stare_produs=" & stareProdus & " WHERE " &_
"id_produs=" & idProdus

Explicaţii şi parafraze
Important este că UPDATE schimbă conţinutul acelei înregistrări din tabela Produse,
care are un identificator de produs egal cu cel conţinut în variabila idProdus. Se vor
schimba doar câmpurile aflate după separatorul SET.
O a patra comandă SQL este cea de eliminare a unor rânduri (înregistrări) din tabelă. Se
numeşte DELETE. Prezentăm chiar un exemplu de comandă scrisă à la VBScript!
sqlString = "DELETE FROM cos " &_
"WHERE id_client_cos=" & idclient

Aici tabela este denumită cos. Se referă la coşul de cumpărături. Evident, denumirile
variabilelor unui limbaj nu sunt acceptate decât în transcrierea anglo-saxonă. Nici vorbă
de caracterele noastre diacritice.
Se elimină din această tabelă doar rândurile care au în câmpul id_client_cos o valoare
identică cu conţinutul variabilei idclient.
Observaţie generală:
Pentru a nu ne bulversa în exemplul magazinului virtual de mai jos, am convenit ca
toate denumirile de variabile VBScript să le transcriem fără trăsură de unire, în timp ce
denumirile de câmpuri de tabele să aibă acest caracter ”_”.
Ce se realizează în secvenţa de mai jos?
sqlString = "SELECT DISTINCT categorie_produs FROM Produse "
sqlString = sqlString & "WHERE stare_produs=1 "
sqlString = sqlString & "ORDER BY categorie_produs"

Explicaţii şi parafraze
Este vorba de o selectare din tabela Produse a denumirilor distincte din câmpul
categorie_produs. Selectăm doar produsele alese pentru a fi vândute (stare_produs = 1).
Ele sunt ordonate crescător după conţinutul rubricii categorie_produs. Atenţie! Într-un
tabel de produse pot exista multe produse ce aparţin aceleiaşi categorii. Dacă nu am
recurge la separatorul DISTICT, s-ar prelua mult mai multe înregistrări. Cu DISTINCT
se va selecţiona doar câte o înregistrare care are o valoare distinctă.
Dar în secvenţa de mai jos ce facem?
sqlString = "SELECT id_cos FROM cos " &_
"WHERE id_client_cos=" & idClient & " " &_
"AND id_produs_cos=" & idProdus

Singurul element nou este operatorul logic AND. Traducem: “selectează din tabela cos
după câmpul id_cos doar unde id_client_cos are valoarea din idCleint ŞI id_produs_cos
are valoarea din idProdus.
Cam atât despre SQL, acest vast subiect despre s-au scris zeci de tratate!

La final de capitol
Aici am aflat:
1. Care sunt cerinţele software pentru a aborda tehnologia ASP din punct de vedere
al variantelor de sisteme de operare Windows în circulaţie.
2. Ce este o pagină ASP cu câteva exemple concrete.
3. Procedeele de operare pentru a pune pe rol serverul Web şi driverul ODBC.
4. Cum se scriu liniile lungi, cum se lucrează cu obiectele implicite.
5. Care sunt obiectele implicite ale tehnologiei ASP.
6. Câteva reguli sintactice ale limbajului Visual Basic for Scripting.
7. Şi la sfârşit, ne-am uşurat sarcina explicării lungilor liste de programe ale
exemplului de sit electronic din capitolele următoare, printr-un compendiu la
obiect despre limbajul de interogare structurat, SQL.
8
Capitolul

Să construim un catalog de
produse pentru un sit comercial
Pregătiţi-vă să aveţi răbdare cu carul! Vom folosi tehnologia ASP. Presupunem
că aveţi ceva cunoştinţe minimale de Visual Basic de la primul curs de iniţiere în
informatică sau măcar aţi citit capitolul anterior!
Primul lucru care ne interesează este să definitivăm

Caietul de sarcini al aplicaţiei

S
untem proprietarii unor depozite de produse din domeniile IT&C. Vrem să
alcătuim un magazin virtual. Această aplicaţie intră în categoria B2C.
Pentru explicarea acestui termen recomandăm una dintre referinţele /1, 6/ sau
partea a doua în limba franceză.
Ne-am inspirat oarecum din exemplul mai vast tratat în /6/. Vai însă, ţinem cont că sunt
destui hoţi şi crackeri. Pentru termenul cracker vezi referinţa /1/. E cam acelaşi lucru. A
se citi hoţi electronici. Aşa că vom diferi mult de exemplul de sit comercial dat în
această referinţă.
Revenind la sarcinile pe care trebuie să le realizeze programul sitului nostru, vizitatorii
noi vor trebui înregistraţi pe bază de formular. Cei vechi vor recurge doar la informaţia
de login, adică numele şi parola.
La înregistrare, clientul va anunţa adresa de email de destinaţie. Nu am ales soluţia
instrumentelor electronice de plată ci banii lichizi achitaţi la momentul livrării obiectelor
transportate la domiciul clientului. Ce trai ar fi fost pe crackeri!
Pe pagina principală a magazinului virtual se vor perinda cele mai noi produse la
vânzare, după strategia proprie de reclamă a administratorului sitului. El poate trimite e-
mail-uri spre clienţii tradiţionali.
Evident, vizitatorul va şti ce conţine coşul său de cumpărături, ori de câte ori va revizita
situl. I se va cere să se legitimeze prin formular de login. Dacă este impostor, va fi
anunţat că nu mai are ce căuta în acest sit, şi că a fost anunţat la poliţie. Oricum, ca să
ajungă aici un impostor îşi va freca mâinile şi se va arunca precis să „cumpere” cât mai
mult pe banii altui cumpărător cinstit. Nu! Nu-i va merge! Va fi oprit la plata! E
adevărat: la orice armă se găseşte o « contra armă ».
Coşul se va goli în tabelul livrare a comenzilor, când vizitatorul va accepta întocmirea
facturii de plată. Vizitatorul va putea modifica conţinutul coşului său până la momentul
acceptării întocmirii comenzii ferme, de fapt a ordinului de plată. Nu îl elaborăm aici!
În principiu, fiecare produs ar trebui să aibă câte o poză cu aspectul său şi neapărat o
serie de caracteristici specifice. Nu am avut timp ca să desenăm aspectul produselor
vândute. De aceea multe din pozele produselor nu apar în fereastra browserului.
Evident, trebuie să permitem potenţialului cumpărător de componente electronice să
caute orice produs în rafturile depozitului. El trebuie să nu dovedească cine ştie ce
cunoştinţe tehnice. Şi le va forma pe parcurs după vizite repetate. Reamintim că este un
magazin de articole şi accesorii din IT, deci este vorba de PC-uri, servere, memorii,
discuri, accesorii, pagere, PDA-uri etc.
Nu am securizat paginile ca numai administratorul să poată umbla la unele pagini, din
motive didactice.
Nu vom arăta cum am folosit FrontPage, întrucât scopul acestui manual nu este de a vă
învăţa proiectarea Web. Nici nu vom prezenta ciclul de dezvoltare, fiindcă nu trebuie să
deveniţi programatori şi ceea ce e mai rău, nu am posedat Microsoft Visual InterDev.
Am mers pe ideea bazei software de la laboratoare, adică editorul WordPad, serverul IIS
şi nelipsitul client Web MSIE. Totuşi pe fiecare staţie am instalat, aşa cum spuneam în
introducere, două servere, resin pentru tehnologia JSP şi IIS pentru ASP. Acum folosim
tehnologia ASP, deci serverul MS IIS. Nu am avut acces la aplicaţia MS SQL Server.
Am fost mulţumiţi şi cu MS Access.
Aşadar să începem!

Baza de date şi tabelele sale (MSAccess)


În primul rând creăm cu MS Access o bază de date denumită mypisi. Procedeul este
acesta:
1. Activăm aplicaţia MS Access (Start Æ Programs Æ MS Access).
2. Din caseta iniţială de dialog alegem opţiunea pentru crearea unei
noi baze de date, Blank Database.
3. Apare caseta de dialog denumită fişier nou de tipul bază de date, File New
DataBase. Aici precizăm în nume fişier, File name, denumirea bazei, mypisi.
Denumirea are automat extensia .mdb. Alegem directorul unde dorim să o
salvăm. Acţionăm butonul Create.
4. Apare o altă casetă de dialog. Aici alegem prima opţiune, aceea de creare a unui
tabel în modul de proiectare denumit vedere a structurii de date, Create Table in
Design View. De fapt, vom crea cele patru tabele: Produse, Clienti, Cos şi
Comenzi.
5. Precizăm în ordine cele câmpurile pentru Produse etc. Indiferent că folosim doar
driverul ODBC fiind în platforma Microsoft, trebuie să anunţăm acest driver că
va avea acces la o „sursă de date”. Denumirea sursei va fi „sd”. Pentru aceasta
iată procedeul:
6. Dacă folosim sistemul de operare Windows 2000 Professional, activăm Data
Sources (ODBC); traseu este: Start Æ Settings Æ Control Panel Æ
Administrativ Tools Æ Data Sources (ODBC). Dacă folosim varianta Windows
98, traseul va fi altul: Start Æ Programs Æ Control Panel Æ ODBC Data
Sources. Apare o casetă complexă, similară cu aceea din figura 5.4, capitolul 6.
În acea figură apare denumirea logică a sursei de date mydb.mdb, deoarece
acolo ne ocupam de o altă bază de date. Principiul se păstrează! Acum însă sursa
de date va fi de tip sistem şi nu de tip utilizator (user). Aceasta înseamnă ceva şi
nu mai divagăm! Revenind la procedura în sine.
7. Ni se cere denumirea sursei de date. Precizăm sd. O scriem exact aşa.
8. Apoi selectăm un driver de tipul Microsoft Access (*.mdb).
7. Mai departe, prin clic pe butonul Finish, apare o ultimă casetă de dialog
Database. Aici selectăm fişierul mypisi.mdb. El se află într-un alt director decât
cel afişat iniţial în casetă. Pentru aceasta călătorim în directorul unde este baza
şi, prin clic pe denumirea ei, ajungem la final. Am anunţat driverul ODBC că
sursa de date sd corespunde fişierului mypisi.mdb.
Câmpurile celor patru tabele sunt următoarele:
I. Tabelul Produse este alcătuit din:
• id_produs, are tipul autonumber, deci are regim de cheie primară
pentru indexare,
• nume_produs de tipul text, maximum 50 caractere,
• caracteristici_produs, text, maximum 255 caractere,
• pret_produs, currency,
• stare_produs, de tip număr şi
• produs_in_vitrina tot de tip număr.
Starea produsului poate activ sau nu. Activ înseamnă la vânzare. Produs_in_vitrină
dacă diferă de zero, înseamnă că produsul este selectat pentru a fi afişat pe pagina
primară a sitului, deci în vitrina magazinului virtual. Selecţia în programul nostru se
face aleator cu ajutorul funcţiei RND (VBScript).
II. Tabelul Clienti este alcătuit din:
• id_client, autonumber, pe post de cheie primară,
• nume_client, text, maximum 50 caractere,
• parola_client, idem,
• email_client, ibidem,
• cod_postal_client, număr.
III. Tabelul cos destinat coşului pentru cumpărături, are rubricile:
• id_cos, autonumber, pe post de cheie primară,
• id_client_cos, număr,
• id_produs_cos, idem,
• cantitate_cos, ibidem.
IV. La final, tabelul Comenzi este compus din:
• id_comanda, număr, pe post de cheie primară,
• id_produs_comanda, număr,
• cantitate_comanda, idem,
• id_client_comanda, ibidem,
• data_intrare_comanda, date/time,
• data_livrare_comanda, idem.
Observaţie: Un câmp care are regimul de cheie primară impune de la sine ca
valoarea sa să fie unică în acel tabel.

Cum adăugăm produsele şi cum administrăm


tabelul respectiv
Începem cu prezentarea unei pagini la care are de regulă acces doar administratorul.
Mai înainte două observaţii importante:
1. Nu am inclus în sistem vreo interdicţie pentru vizitatorul obişnuit, din motive de
conciziune a codului. Nu aşa se procedează însă în realitate. Trebuie îngrădit
accesul vizitatorilor la paginile la care are acces doar administratorul.
2. Redăm integral listele programelor sitului.
Prima pagină este denumită adaugProdus.asp. Iată conţinutul acesteia:
LISTA 8.1 Pagina adaugProdus.asp

<html>
<head><title>Adaug Produs</title></head>

<body bgcolor="gray">
<form method="post" action="adminproduse.asp">
<center>
<table width="600" border=1 bgcolor="lightyellow" cellpadding="4" cellspacing="0">
<tr>
<td colspan="2" bgcolor="yellow"><font face="Arial" size="3"><b>Adaug
Produsul</b></font>
</td>
</tr>
<tr>
<td><b>Nume produs:</b></td>
<td><input name="numeProdus" size="50" maxlength="50"></td>
</tr>
<tr>
<td><b>Pret produs:</b></td>
<td><input name="pretProdus" size="10"></td>
</tr>
<tr>
<td><b>Caracteristici produs:</b></td>
<td><input name="caracteristiciProdus" maxlength="255" size="50"></td>
</tr>
<tr>
<td><b>Categorie produs:</b></td>
<td><input name="categorieProdus" size="50" maxlength="50"></td>
</tr>
<tr>
<td><b>Stare produs:</b></td>
<td><select name="stareProdus"><option value = "0">INACTIV<option value =
"1">ACTIV</select></td>
</tr>
<tr>
<td colspan=2 align="right"><input type="submit" value="Adaug Produs"></td>
</tr>
</table>
</center>
<input name="adaugProdus" type="hidden" value="1">
</form>
</body>
</html>

Explicaţii şi parafraze
Pagina care va prelua valorile completate de operatorul datelor, atunci când acesta va
introduce produsele se cheamă adminproduse.asp (linia 05). Pagina de mai sus este un
banal formular HTML care nu are nici un scenariu ASP. Ar fi putut avea sufixul .htm
sau .html. Totuşi am stabilit ca să aibă sufixul .asp, deoarece ea nu mai este statică ci
una dinamică. Nu uitaţi că pagina trebuie să vină de la serverul Web.
Reamintim să citiţi anexa A pentru a vă pune oarecum la punct cu HTML. Priviţi mai
jos aspectul documentului, dacă se dă comanda:
http://localhost/abc/adaugProdus.asp

FIGURA 8.1 Aspectul ferestrei document MSIE (contextul: adaugProdus.asp)

Să ne referim acum la pagina adminproduse.asp:


LISTA 8.2 Pagina adminProduse.asp

01. <!-- #INCLUDE FILE="functii.asp" -->


02. <%
03. ' Atribuim unor variabile locale
04. ' valorile din rubricile formularului

05. adaugProdus = TRIM( Request( "adaugProdus" ) )


06. actualizezProdus = TRIM( Request( "actualizezProdus" ) )
07. idProdus = TRIM( Request( "idProdus" ) )
08. numeProdus = TRIM( Request( "numeProdus" ) )
09. pretProdus = TRIM( Request( "pretProdus" ) )
10. caracteristiciProdus = TRIM( Request( "caracteristiciProdus" ) )
11. categorieProdus = TRIM( Request( "categorieProdus" ) )
12. produsDeVitrina = TRIM( Request( "produsDeVitrina" ) )
13. stareProdus = TRIM( Request( "stareProdus" ) )

14. ' Atribuirea valorilor asumate pentru rubrici necompletate

15. IF numeProdus = "" THEN


16. numeProdus = "nil"
17. END IF

18. IF pretProdus = "" or NOT isNUMERIC( pretProdus ) THEN


19. pretProdus = 0
20. END IF

21. IF caracteristiciProdus = "" THEN


22. caracteristiciProdus = "nil"
23. END IF
24. IF categorieProdus = "" THEN
25. categorieProdus = "nil"
26. END IF

27. ' Deschid conexiunea logica la BD


28. Set Con = Server.CreateObject( "ADODB.Connection" )
29. Con.Open "sd"
30. %>

31. <html>
32. <head><title>Administrare Produse</title></head>
33. <body bgcolor="gray">

34. <%

35. ' Adaug un produs nou

36. IF adaugProdus <> "" THEN


37. sqlString = "INSERT INTO Produse " &_
38. "( nume_produs, pret_produs, caracteristici_produs, categorie_produs,
stare_produs ) VALUES ( " &_
39. " '" & numeProdus & "', " &_
40. pretProdus & ", " &_
41. " '" & caracteristiciProdus & "', " &_
42. " '" & categorieProdus & "', " &_
43. stareProdus & " )"

44. Con.Execute sqlString


45. %>

46. <center>
47. <table width="600" cellpadding="4" cellspacing="0" bgcolor="lightyellow">
48. <tr>
49. <td><%=numeProdus%> a fost adaugat in BD, tabelul produse</td>
50. </tr>
51. </table>
52. </center>
53. <p>

54. <%
55. END IF

56. ' Actualizarea unui produs, deja prezent in BD, tabelul produse

57. IF actualizezProdus <> "" THEN


58. sqlString = "UPDATE Produse SET " &_
59. "nume_produs='" & apostrof12( numeProdus ) & "'," &_
60. "pret_produs=" & cCUR( pretProdus ) & "," &_
61. "caracteristici_produs='" & apostrof12( caracteristiciProdus ) & "'," &_
62. "categorie_produs='" & apostrof12( categorieProdus ) & "'," &_
63. "produs_de_vitrina=" & produsDeVitrina & "," &_
64. "stare_produs=" & stareProdus & " WHERE " &_
65. "id_produs=" & idProdus
66. Con.Execute sqlString
67. %>

68. <center>
69. <table width="600" cellpadding="4" cellspacing="0" bgcolor="lightyellow">
70. <tr>
71. <td><%=numeProdus%> was updated in the database</td>
72. </tr>
73. </table>
74. </center>
75. <p>

76. <%
77. END IF
78. %>

79. <center>
80. <table width="600" border=1 bgcolor="lightyellow" cellpadding="4"
cellspacing="0">
81. <tr>
82. <td colspan="2" bgcolor="yellow"><font face="Arial" size="3"><b>Admin.
produse</b></font></td>
83. </tr>
84. <tr>
85. <td align="center"><table border="1" size="400" cellpadding="3" cellspacing=0
bgcolor="white">

86. <%
87. sqlString = "SELECT id_produs, nume_produs FROM Produse " &_
88. "ORDER BY nume_produs"
89. SET RS = Con.Execute( sqlString )

90. WHILE NOT RS.EOF


91. %>

92. <tr>
93. <td><a href="actualizezprodus.asp?pid=<%=RS( "id_produs")%>"><%=RS(
"nume_produs" )%></a></td>
94. </tr>

95. <%
96. RS.MoveNext
97. WEND
98. %>

99. </table>
100. </td>
101. </tr>
102. <tr>
103. <td><a href="adaugProdus.asp">Adaug produs</a>
104. </td>
105. </tr>
106. </table>
107. </center>
108. </body>
109. </html>

Explicaţii şi parafraze
În prima linie anunţăm că se va include în prealabil fişierul functii.asp. Aici sunt grupate
toate funcţiiile aplicaţiei. Această directivă se citeşte automat la începutul fazei de
interpretare a paginii în sine. Deci nu are importanţă locul acesteia. Putea să fie la final,
şi s-ar fi citit tot înaintea începerii interpretării instrucţiunilor VBScript. Primul scriptlet
este anunţat în linia 02.
După comentariul aferent, în liniile 05-13 preluăm valorile completate pentru produsul
respectiv.
Priviţi denumirile logice ale rubricilor din lista adaugProdus.asp. Acolo este un
formular. Obiectul request poate recurge şi la alte colecţii. Aici este vorba de colecţia
formular.
Puteam scrie canonic aşa: request.Form(“adaugProdus”). Ar fi fost redondant, deoarece
din context s-a dedus că este vorba despre o colecţie Form. Cum adică colecţie?
Formularul este o resursă HTML. El conţine o colecţie de rubrici de tip text, sau de tip
casetă de verificare etc.
Mai departe se urmăreşte ca în rubricile rămase necompletate să se înscrie fie textul
„nil”, dacă acel câmp este de tip text, fie cifra 0, dacă acea rubrică este de tip numeric.
Aceasta se realizează cu triadele IF ... ENDIF.
Urmăriţi preţul produsului. Se poate întâmpla ca operatorul din grabă să introducă o
literă. Atunci în pretProdus se înregistrează valoarea 0.
Desigur, am putea complica funcţie de analizare şi să trimitem un mesaj de avertizare.
Dacă vă pasionează programarea, puteţi modifica dumneavoastră această rutină. Nu
uitaţi să o includeţi în pagina de funcţii, denumită functii.asp.
Am ajuns la liniile 28 şi 29. Aici se realizează conexiunea logică cu baza de date
mypisi.mdb Afirmam mai sus că obiectul Con are o structură complicată. Nici nu avem
de gând să o prezentăm. În ASP anunţăm obiectul server ca să creeze un obiect din
categoria Activex Data Object (ADO) şi anume unul de tip baza de date (DB). Apoi să
recurgă la metoda conectare (Connection). Mai departe, cu metoda Open afiliată
obiectului Con, se cere ca denumirii sd (numele logic al sursei de date) să i se atribuie
un număr logic (programatorii îi spun handle). Dacă treaba nu reuşeşte (poate aţi uitat să
anunţaţi componenta ODBC Data Sources că pentru denumirea sd, s-a asociat o resursă
fizică, mypisi.mdb, aflată undeva pe ierarhia directoarelor), desigur programul se
termină anormal cu un mesaj bulversant!
Să presupunem că aţi urmat procedeul de asociere arătat mai sus. În acest caz vine
rândul instrucţiunii din linia 36. Aici există o variabilă pe post de semafor, denumită
adaugProdus. Ea - fiţi siguri - va avea o valoare diferită de ””, motiv pentru care se va
pregăti în variabila sqlString o comandă de inserţie. Priviţi linia cu numărul 36 din lista
adaugProdus.asp. Acolo s-a introdus în semaforul adaugProdus valoarea 1. Înseamnă că
într-adevăr s-a parcurs formularul care solicită date despre produsul, ce urmează a fi
adăugat în tabelul Produse. În linia 44 se execută (Execute) comanda INSERT prin
intermediul obiectului Con. Mai simplu se realizează inserţia. În linia 49 se anunţă că
produsul cutare s-a introdus în bază.
Priviţi cum arată aspectul paginii în fereastra document a browserului MSIE, dacă se dă
comanda:
http://localhost/abc/adminproduse.asp

FIGURA 8.2a. Aspectul imediat după lansarea paginii adminProduse.asp

Distingem un tabel cu diferite produse. Fiecare produs este un „hypertext”. Deci când
am efectua clic pe el, va apare un ecran de genul celui din figura următoare:

FIGURA 8.2b. Ce vedem dacă alegem un produs spre a-l actualiza (adminProduse.asp)
Cum a fost posibil ca să transformăm datele unui tabel în legături de tip hypertext? Iată
cum: priviţi cu atenţie liniile 90 – 97.
Observaţi o buclă WHILE. În cadrul ei se afişează rând după rând într-un tabel HTML
conţinutul câmpului nume_produs din tabelul Produse. În cadrul rândului există o
celulă. Conţinutul acesteia este de fapt o referinţă de tip hypertext (HTML) la
înregistrarea din tabelul Produse. Dacă este aleasă, va genera un şir de interogare, în care
apare şi parametrul pid, adică numărul înregistrării din tabelul Produse. Pe baza lui se
citeşte din această tabelă conţinutul acelei înregistrări. Va apare pe ecran o fişă similară
cu aceea din figura 8.1, doar că apare butonul Actualizare produs.
Această pagină de administare a produselor a fost scrisă şi pentru cazul când
administratorul vrea să modifice datele unui produs. Dacă este aşa, atunci s-a parcurs o
altă serie de instrucţiuni datorate efectuării clicului pe butonul actualizare produs. Altfel
spus s-a declanşat executarea paginii actualizezProdus.asp. Din această cauză şi
semaforul actualizezProdus va fi schimbat la valoarea 1. Atunci IF-ul din linia 57 va
găsi acest semafor poziţionat pe 1. În consecinţă, se execută grupul de linii 58-65. De
fapt, aici se pregăteşte în variabila sqlString, comanda de actualizare UPDATE, aşa cum
am văzut mai sus la breviarul pentru SQL.
În continuare, în linia 66 se face această actualizare, după care se anunţă în linia 71 că
treaba s-a încheiat cu bine. Observaţi expresia <%=numeProdus%>.
Să privim acum instrucţiunile paginii actualizezProdus.asp:
LISTA 8.3 Pagina actualizezProdus.asp

01. <%
02. ' Obtin ID-ul produsului
03. idProdus = Request("pid")

04. ' Deschid conexiunea logica la BD


05. Set Con = Server.CreateObject("ADODB.Connection")
06. Con.Open "sd"

07. ' Deschid obiectul RecordSet


08. Set RS = Server.CreateObject("ADODB.Recordset")
09. RS.ActiveConnection = Con
10. RS.CursorType = 3
11. RS.Open "SELECT * FROM Produse WHERE id_produs=" & idProdus

12. IF NOT RS.EOF THEN


13. numeProdus = RS("nume_produs")
14. pretProdus = RS("pret_produs")
15. caracteristiciProdus = RS("caracteristici_produs")
16. categorieProdus = RS("categorie_produs")
17. produsDeVitrina = RS("produs_de_vitrina")
18. IF isNULL(produsDeVitrina) THEN produsDeVitrina = 0
19. stareProdus = RS("stare_produs")
20. END IF
21. ' Inchid obiectul Recordset
22. RS.Close
23. FUNCTION SELECTED(valoare1, valoare2)
24. IF cSTR(valoare1) = cSTR(valoare2) THEN
25. SELECTED = "SELECTED"
26. END IF
27. END FUNCTION
28. %>

29. <html>
30. <head><title>Actualizare produs</title></head>
31. <body bgcolor="gray">
32. <form method="post" action="adminproduse.asp"><center>
33. <table width="600" border="1" bgcolor="lightyellow" cellpadding="4"
cellspacing="0">
34. <tr>
35. <td colspan="2" bgcolor="yellow"><font face="Arial" size="3"><b>Actualizare
Produse</b></font></td>
36. </tr>
37. <tr>
38. <td><b> Nume produs:</b></td>
39. <td><input name="numeProdus" size="50" maxlength="50"
value="<%=Server.HTMLEncode(numeProdus)%>"></td>
40. </tr>
41. <tr>
42. <td><b>Pret produs:</b></td>
43. <td><input name="pretProdus" size="10" value="<%=pretProdus%>"></td>
44. </tr>
45. <tr>
46. <td><b>Caracteristici produs:</b></td>
47. <td><input name="caracteristiciProdus" size="50" maxlength="255"
value="<%=Server.HTMLEncode(caracteristiciProdus)%>"></td>
48. </tr>
49. <tr>
50. <td><b>Categorie produs:</b></td>
51. <td><input name="categorieProdus" size="50" maxlength="50"
value="<%=Server.HTMLEncode(categorieProdus)%>"></td>
52. </tr>
53. <tr>
54. <td><b>Produs nou de vitrina:</b></td>
55. <td><select name="produsDeVitrina"><option value="0" <%=SELECTED("0",
produsDeVitrina)%>>Normal<option value="1" <%=SELECTED("1",
produsDeVitrina)%>>Lavitrina</select></td>
56. </tr>
57. <tr>
58. <td><b>Stare produs:</b></td>
59. <td><select name="stareProdus"><option value="0" <%=SELECTED("0",
stareProdus)%>>INACTIV<option value="1" <%=SELECTED("1",
stareProdus)%>>ACTIV</select></td>
60. </tr>
61. <tr>
62. <td colspan=2 align="right"><input type="submit" value="Actualizare
produs"></td>
63. </tr>
64. </table>
65. </center>
66. <input name="idProdus" type="hidden" value="<%=idProdus%>">
67. <input name="actualizezProdus" type="hidden" value="1">
68. </form>
69. </body>
70. </html>

Explicaţii şi parafraze
Prima grijă pe care am avut-o este să preluăm valoarea lui pid, deci indexul rândului din
tabelul Produse. Pe baza lui, după deschiderea logică din liniile 05 şi 06, creăm un tabel
rezultat RecordSet. L-am denumit RS. Din el accedem chiar produsul a cărei actualizare
intenţionăm a o face. Atâta timp cât nu am ajuns la sfârşitul tabelului RS (linia 12)
preluăm informaţiile despre acest produs (liniile 13-19) în variabile locale. La final, în
linia 22 închidem din punct de vedere logic tabelul rezultat RS.
Funcţia SELECTED apare aici ... ca nuca în perete! Totuşi am făcut-o din motive pur
didactice. În caz contrar, ar fi fost nevoie să vă rugăm să citiţi paginile care tratează
pagina functii.asp, lucru destul de neplăcut dumneavoastră. Paginii acesteia îi va veni
rândul mult mai jos!
Oricum, pentru eleganţa exerciţiului de programare, nu ar fi fost nevoie să mai scriem
instrucţiunile ei aici. Deci tot ce trebuia să facem era să adăugăm acea declaraţie de
includere a paginii functii.asp şi totul era rezolvat. Cum? Vom vedea mai jos!
Sărim descifrarea acestei funcţii de care avem nevoie puţin mai jos şi intrăm în partea
„html” a paginii (linia 29). Aici este anunţată o resursă de tip formular HTML (priviţi
linia 32), care este deservită de pagina adminproduse.asp.
Formularul este redat sub forma unui tabel (linia 33). El are aspectul identic cu cel din
pagina adaugProdus.asp, doar că acum apare şi conţinutul rubricii produs_de_vitrină. În
linia 55 observaţi că ne interesează conţinutul acestui câmp. În HTML îl denumim
produsDeVitrina. Cu funcţia SELECTED facem un lucru foarte simplu! Explorăm
conţinutul câmpului stareProdus. Dacă acel produs era la vânzare, atunci acest câmp ar
fi avut valoarea 1 în tabelul Produse. În consecinţă, parametrul fictiv valoare1 ar fi
preluat conţinutul 1, caz în care s-ar fi afişat în dreptul rubricii din formular textul „în
vitrină”. În caz contrar, s-ar fi afişat textul „normal”. Vă propunem o primă întrebare:
1. Este un exerciţiu de programare: ce denumire ar fi fost mai nimerită pentru
această funcţie în loc de SELECTED, dacă am fi voit să exprime faptul că este
în vitrina. După aceea unde trebuia să modificaţi codul de instrucţiuni în sine ca
să beneficiaţi de această nouă denumire mai nimerită.

Afişarea produselor
Pe administrator îl interesează un catalog cu categoriile de produse şi un catalog „in
extenso”.
Pagina listaCatalog.asp răspunde la prima problemă, iar pagina listaProduse.asp la a
doua.
Mai întâi să ne ocupăm de pagina listaCatalog.asp:
LISTA 8.4 Pagina ListaCatalog.asp

01. <%
02. ' Creez obiectul catRS, unde se va forma tabelul categoriilor de produse
03. Set catRS = Server.CreateObject("ADODB.Recordset")
04. catRS.ActiveConnection = Con
05. sqlString = "SELECT DISTINCT categorie_produs FROM Produse "
06. sqlString = sqlString & "WHERE stare_produs=1 "
07. sqlString = sqlString & "ORDER BY categorie_produs"
08. catRS.Open sqlString
09. %>

10. <% IF cat = "Acasa" THEN %>


11. <font color="red"><b>Acasa</b></font><UL>
12. <% ELSE %>
13. <a href="index.asp?cat=Acasa">Acasa</a><UL>
14. <% END IF %>

15. <% WHILE NOT catRS.EOF %>


16. <% IF catRS("categorie_produs") = cat THEN %>
17. <li><font color="red"><b>
18. <%=catRS("categorie_produs")%></b></font>
19. <% ELSE %>
20. <li><a
href="index.asp?cat=<%=Server.URLEncode(catRS("categorie_produs"))%>">
21. <%=catRS("categorie_produs")%></a>
22. <% END IF %>
23. <%
24. catRS.MoveNext
25. WEND
26. %>
27. </UL>
28. <% catRS.Close %>

Explicaţii şi parafraze
Prima chestiune pe care o realizăm mai sus este să pregătim o instanţă a obiectului
RecordSet, pe care aici îl vom numi catRS. În el vom păstra un tabel prescurtat cu
categoriile de produse. Vă reamintim că unul din câmpurile tabelului Produse este
categorie_produs. Deci trebuie să parcurgem toate înregistrările tabelului şi să
vizualizăm doar categoriile distincte de produse din depozit.
Cum facem acest lucru? Cu ajutorul unei comenzi SQL în care neapărat trebuie să apară
opţiunea DISTINCT. Priviţi liniile 05-07. Aici se prepară în variabila locală sqlString
comanda respectivă. Să ştiţi că denumirea sqlString nu este rezervată. Am lăsat-o la fel
denumită ca şi în exemplul din referinţa /6/.
În liniile 10-14 prin construcţia IF ... END IF urmărim conţinutul variabilei cat. Dacă ea
conţine literalul Acasă, deci. încă nu am vizitat vreo categorie şi, suntem în pagina
primară a sitului, acest text va fi redat cu culoarea roşie. Altfel, când am alege o
categorie de produs, textul Acasa va fi redat cu o nuanţă mai palidă. Priviţi figurile 8.3a
şi 8.3b. Cuvântul Acasă se observă clar în prima figură.
Mai departe să examinăm blocul WHILE . . . WEND din liniile 17-27. Prin IF-ul din
linia 16, examinăm dacă tabelul rezultat catRS a fost încărcat cu o categorie, adică am
ieşit din pagina primară pentru a căuta informaţii despre produsele care aparţin unei
anumite categorii.
FIGURA 8.3a. Pagina primară a sitului mypisi.shop,
înainte de selectarea categoriei monitoare

FIGURA 8.3b. Pagina primară a sitului mypisi.shop, după selectarea categoriei monitoare
Orice categorie vizitată va fi redată cu culoarea roşie pe cuvintele legăturii de tip
hypertext. Iniţial toate categoriile apar cu altă culoare, cea pentru legături încă nevizitate.
Acest schimbare de culori este doar pentru a demonstra elasticitatea tehnologiei ASP.
Observaţi în linia 20 cum se atribuie variabilei cat rezultatul metodei URLEncode.
Acestă metodă aparţine obiectului Server. Informaţia legăturii de hypertext se află între
paranteza unghiulară închisă a balizei <a href ... > şi paranteza unghiulară deschisă a
balizei </a>. Conţintul ei este rezultatul evaluării expresiei:
<%=catRS(“categorie_produs”)%>

Din această evaluare se obţine denumirea categoriei. Rostul metodei MoveNext asociată
obiectului catRS este acela de a trece la următoarea înregistrare a tabelului catRS. La
final, închidem logic obiectul catRS (linia 28).

Să privim acum lista paginii listaProduse.asp. Ea se ocupă de afişarea produselor după


categorii.
LISTA 8.5 Pagina ListaProduse.asp

01. <%
02. ' In variabila prodRS formez tabelul cu produse pentru acea categorie, cat
03. Set prodRS = Server.CreateObject("ADODB.Recordset")
04. prodRS.ActiveConnection = Con

05. sqlString = "SELECT id_produs, nume_produs, caracteristici_produs " &_


06. "FROM Produse WHERE categorie_produs='" & cat & "' " &_
07. "AND stare_produs=1 " &_
08. "ORDER BY nume_produs "
09. prodRS.Open sqlString
10. %>

11. <table width="350" border="0" cellpadding="4" cellspacing="0">

12. <%
13. WHILE NOT prodRS.EOF
14. %>

15. <tr>
16. <td>
17. <% IF prodRS("caracteristici_produs") <> "nil" THEN %>
18. <IMG SRC="<%=prodRS("nume_produs")%>.jpg" hspace="4" vspace="4"
border="0" align="center">
19. <% END IF %>
20. </td>
21. <td>
22. <a href="produs.asp?pid=<%=prodRS("id_produs")%>">
23. <b><%=prodRS("nume_produs")%></b></a>
24. <br><%=prodRS("caracteristici_produs")%>
25. <br><a href="produs.asp?pid=<%=prodRS("id_produs")%>"></a>
26. </td>
27. </tr>
28. <tr>
29. <td colspan="2" align="center">&nbsp;</td>
30. </tr>

31. <%
32. prodRS.MoveNext
33. WEND
34. %>

35. </table>

Explicaţii şi parafraze
Aici pregătim o instanţă a unui tabel rezultat denumit prodRS. Obiectul Con are un
număr logic (acel „handel” de care vorbeam mai devreme). Ceea ce facem aici este să
obţinem acest număr logic, deci ne conectăm logic la baza mypisi.mdb.
În continuare, dacă aţi citit cu atentie explicaţiile de până aici, atunci vă va veni mai uşor
să recunoaşteţi ce se întâmplă în liniile următoare ale acestui program.
De pildă, în liniile 05-08 pregătim comanda de selectare a trei coloane id_produs,
nume_produs şi caracteristici_produs din tabelul Produse. Selectarea se face doar pentru
o anumită categorie (variabila cat ne spune care anume).
Mai este o condiţie şi anume: se selectează doar acele produse puse la vânzare
(stare_produs = 1). Ordonarea se face alfabetic după numele produsului.
Blocul WHILE . . . WEND, delimitat de liniile 13-33, este similar celui de la programul
ListaCatalog.asp. Să explicăm totuşi ce se petrece în linia a 18-a. Dacă produsul are
specificate caracteristici, atunci există şi poza cu aspectul său. Aţi observat poze de
produse în figurile 8.3a şi 8.3b. Este prea migălos să compui artistic poze cu un maus!
De aceea pozele nu arată prea bine.
În linia 18 se evaluează expresia şi se obţine conţinutul câmpului nume_produs. Acesta
este alipit la sufixul „.jpg” şi se obţine denumirea fişierului pozei. În referinţa /6/ se
consacra încă o coloană în tabelul Produse pentru denumirea fişierului cu poza
produsului.
Poza este plantată în prima celulă a tabelului HTML. În celula alăturată afişăm
denumirea produsului (expresia <%=RS(“nume_produs”)%>) şi caracteristicile sale
(expresia <%=RS(”caracteristici_produs”)%>). Există chiar şi o legătură de tip
hypertext care generează un şir de interogare. În acest şir este implicat şi parametrul pid,
deci numărul produsului selectat cu ajutorul mausului.
A venit în sfârşit rândul paginii principale a sitului, index.asp.
LISTA 8.6 Pagina de casă a sitului, index.asp

01. <!-- #INCLUDE FILE="adovbs.inc" -->


02. <%
03. ' Atribui categoria curenta variabilei locale cat
04. cat = TRIM( Request( "cat" ) )
05. inreg = TRIM(Request("inreg"))
06. ' response.write "index.asp: inreg = " & inreg & "<BR>"
07. ' Semafor stare inregistrare client vechi sau nou
08. ' inreg = 0 valoare de blocaj
09. ' inreg = 1 client nou
10. ' inreg = 2 client vechi

11. IF cat = "" THEN cat = "Acasa"


12. ' Deschid conexiunea logica la BD
13. Set Con = Server.CreateObject( "ADODB.Connection" )
14. Con.Open "sd"
15. %>

16. <html>
17. <head>
18. <title>Mypisi.shop</title>
19. </head>
20. <body link="#ffaa55" vtext="red" bgcolor="antiquewhite">
21. <center>
22. <table width="640" border="0" bgcolor="#eeddcc" cellspacing="0"
cellpadding="0">
23. <tr>
24. <td align="center" colspan="2"><img border="0" src="logo.jpg"></td>
25. </tr>
26. <tr>
27. <td width="160"><a href="cosuri.asp">Stare cos</a></td>
28. <td width="160"><a href="inreg.asp">La prima vizita a sitului</a></td>
29. <td width="160"><a href="login.asp">Vizitator vechi</a></td>
30. <td width="160"><a href="plata.asp">Stare comanda</a></td>
31. </tr>
32. </table>
33. <table width="640" border="0" bgcolor="#ffffff" cellpadding="0" cellspacing="0">
34. <tr>
35. <td valign="top">
36. <table cellpadding="0" cellspacing="0" border="0">
37. <tr>
38. <td valign="bottom"><img src="cauta.jpg" vspace=0 border="0"></td>
39. </tr>
40. <tr>
41. <td><table width="198" cellpadding="4" cellspacing="0" bgcolor="lightyellow"
border="1">
42. <tr>
43. <td width="186">
44. <form method="post" action="cauta.asp">
45. <input name="camp_cautare" size="15">
46. <input type="submit" value="Cauta">
47. </form>
48. </td>
49. </tr>
50. </table>
51. </td>
52. </tr>
53. <tr>
54. <td></td>
55. </tr>
56. <tr>
57. <td valign="bottom"><img src="categorii.jpg" vspace="0" border="0"></td>
58. </tr>
59. <tr>
60. <td><table width="200" cellpadding="4" cellspacing="0" bgcolor="lightyellow"
border="1">
61. <tr>
62. <td><font size="3"><b><!-- #INCLUDE FILE="ListaCatalog.asp" --
></b></font></td>
63. </tr>
64. </table>
65. </td>
66. </tr>
67. </table>
68. </td>
69. <td valign="top">
70. <% IF cat = "Acasa" THEN %>
71. <!-- #INCLUDE FILE="Vitrina.asp" -->
72. <% ELSE %>
73. <!-- #INCLUDE FILE="ListaProduse.asp" -->
74. <% END IF %>
75. </td>
76. </tr>
77. </table>
78. <hr width=640>
79. Inspirat dupa exemplul sitului din cartea "Teach Yourself E-Commerce
Programming with ASP in 21 Days", Stephen Walter si Jonathan Levine, seria
SAMS Teach Yourself, SAMS, 2000, dar modificat mult ca filozofie in privinta
vizitatorilor vechi si noi.
80. <br>Fara suport pentru card electronic, doar pentru scop didactic, elab. prof. dr.
Somnea Dan, 2003.
81. </center>
82. </body>
83. </html>

Explicaţii şi parafraze
În linia 01 includem în modul static un fişier denumit adovbs.inc. El conţine mulţi
parametri ai aşa-zisei biblioteci ActiveX Data Object. Limbajul este evident Visual
Basic for Scripting; de unde şi prescurtarea adovbs. Nu ne apucăm a-l diseca. Putem
înţelege ASP şi fără a-l prezenta!
Remarcaţi variabilele cat şi inreg. Prima se referă la categoria selectată cu mausul, a
doua la tipul vizitatorului. Ştim că TRIM este o funcţie de bibliotecă a limbajului
VBScript şi ştim şi ce face.
Evident, variabilele cat şi inreg nu conţin la început decât acest şir (””) adică nimic. În
linia 06 vedeţi o scriere de testare acum invalidată. A servit în faza de punere la punct a
sitului. Să ignorăm comentariile din liniile 07-10, care se referă la un semafor privitor la
tipurile de vizitatori, noi sau vechi. Motivul? Ar trebui să întrerupem explicaţiile acestui
program pentru a trece prin alt liste. Nu este oportun! Urmează deschiderea conexiunii
logice la baza de date (12-13). Am explicat-o cu lux de amănunte mai sus la lista
adminproduse.asp.
Această pagină primară împarte fereastra în parcele după tehnica tabelării fără chenare
din HTML. Pagina nu a fost totuşi proiectată cu un editor specializat pentru publicarea
pe Web ci cu editorul WordPad, lucrând direct în HTML. A fost mai primitiv, dar am
avute unele avantaje de care nu voi vorbi deloc! Evident, este bine să folosiţi un editor
Web gen FrontPage! Atenţie însă, FrontPage 98 pierde pe drum porţiuni de cod ASP,
muncite de dumneavoastră!
Revenim. Mai întâi apare sigla magazinului virtual (linia 24). Imediat vin patru legături
de tip hypertext (liniile 27-30). Mergem mai departe! Mai jos în fereastră, în partea
stângă a acesteia apare rubrica dedicată căutării. De ea se ocupă porţiunea cuprinsă între
liniile 44-47. Imediat urmează o altă zonă pentru afişarea categoriilor de produse (linia
62, priviţi şi figura 8.3a).
În dreapta ferestrei pe o lăţime mai mare este vitrina magazinului virtual. Aici se perindă
pozele acelor mărfuri livrate ce constituie noutăţi de ultimă oră. Felul cum se face
selecţia lor va fi arătat mai jos, când va fi vorba de pagina vitrina.asp.
Observaţi că apar şi primele chestiuni legate de partea finaciară: acele cuvinte subliniate
„Stare comanda” şi evident, starea coşului de cumpărături al vizitatorului.
Când efectuăm clic pe „Stare cos (linia 27) sărim de fapt la pagina cosuri.asp etc.
La fel, după ce completăm mica fereastră rezervată căutării şi efectuăm un clic pe
butonul Cauta, se sare la programul caută asp. Acest buton aparţine formularului
gestionat de programul cauta.asp (linia 44).
Chiar dacă este situată abia în linia 62, includerea statică a fişierului ListaCatalog.asp are
loc mai înainte de a se porni interpretarea paginii index.asp. Se alipeşte la index.asp
acest fişier.
Vom întâlni imediat mai jos şi cazul includerii dinamice de pagini.
Priviţi liniile 70-74. În funcţie de conţinutul variabilei cat se alipeşte fie pagina
vitrina.asp, fie pagina ListaProduse.asp, fie pagina vitrina.asp. Prima dată cat are
conţinutul „Acasa”, deci se va alipi pagina vitrina.asp.
Când însă începem să colindăm prin situl virtual după categorii de produse, cat nu mai
conţine acest text ci, categoria care a fost selectată. Drept consecinţă, se va încărca
celălalt program, ListaProduse.asp.
Wow! It’s really great!

Ultimele noutăţi expuse în vitrină


Dacă este aşa, să vedem cum stăm cu vitrina magazinului virtual!
Deci să examinăm pagina vitrina.asp.
LISTA 8.7 Pagina vitrina.asp

01. <%
02. ' Resetez generatorul aleator
03. Randomize
04. ' Declar o constanta
05. CONST numVitrina= 3

06. ' Regaseste produsele alese pentru a fi in Vitrina e-shop-ului


07. sqlString = "SELECT id_produs, caracteristici_produs, nume_produs " &_
08. "FROM Produse WHERE produs_de_vitrina= 1 " &_
09. "AND stare_produs=1 " &_
10. "ORDER BY nume_produs "

11. ' In variabila locala formez tabelul produselor vedeta,


12. ' cele care au valoarea 1 in campul produs_de_vitrina (tabelul produse)

13. SET Vitrina = Con.Execute( sqlString )


14. IF NOT Vitrina.EOF THEN
15. Vitrina_Masiv = Vitrina.GetRows()
16. Vitrina.Close

17. ' Afisez produsele noi in vitrina


18. topVitrina = UBOUND( Vitrina_Masiv, 2 ) + 1
19. skip = topVitrina / numVitrina
20. IF topVitrina <= numVitrina THEN skip = 1
21. %>
22. <table width="350" border="0" cellpadding="4" cellspacing="0">
23. <%
24. FOR i = 0 TO topVitrina - 1 STEP skip
25. offset = RND * ( skip - 1 )
26. idProdus = Vitrina_Masiv( 0, i + offset )
27. caracteristiciProdus = Vitrina_Masiv( 1, i + offset )
28. numeProdus = Vitrina_Masiv( 2, i + offset )
29. %>
30. <tr>
31. <td>
32. <% IF caracteristiciProdus <> "nil" THEN %>
33. <IMG SRC="<%=numeProdus%>.jpg" hspace="4" vspace="4" border="0"
align="center">
34. <% END IF %>
35. </td>
36. <td><a href="produs.asp?pid=<%=idProdus%>">
37. <b><%=numeProdus%></b></a>
38. <br><a href="produs.asp?pid=<%=idProdus%>">Obtine mai multa
informatie</a>
39. </td>
40. </tr>
41. <tr>
42. <td colspan="2"></td>
43. </tr>
44. <%
45. NEXT
46. %>
47. </table>
48. <%

49. END IF
50. %>

Explicaţii şi parafraze
Sare în ochi acel cuvânt Randomize din linia 03. Comentariul de deasupra spune ce
face. VBScript are un generator normalizat de numere aleatoare uniform distribuite.
Funcţia RND întoarce un număr aleator uniform distribuit între 0,000...01 şi 0,999... De
aceea se spune normalizat!
Constanta numVitrina stabileşte numărul produselor expuse în vitrină. Ştim că în liniile
07-10 preluăm trei coloane din tabelul Produse după un criteriu: produsul este la vânzare
(stare_produs conţine 1) şi, coloana produs_de_vitrina este tot 1 (produsul este o
noutate). Administratorul bazei stabileşte care produse merită să fie considerate noutăţile
acelei perioade. Tot el schimbă manual în 0 valorile din coloana produs_de_vitrina,
când aceste produse ... „şi-au făcut veacul”! Desigur selecţia se face alfabetic după
numele produsului.
În linia 13 obţinem o instanţă a unui tabel rezultat, deci un obiect de tipul RecordSet.
Merge orice denumire nu numai RS ! Am ales denumirea Vitrina. Aici exista şi mai
mult de trei produse noi la un moment dat . Dar în vitrină încap numai trei (numVitrina
= 3). Cu metoda GetRows() a obiectului Vitrina, încărcăm totul într-o matrice VBScript
denumită Vitrina_Masiv. Ştiţi ce este o matrice? Este un tablou care are mai multe linii
şi coloane. Liniile sunt alocate produselor iar coloanele matricei corespund în ordine
coloanelor tabelului Produse: id_produs, caracteristic_produs şi nume_produs. Priviţi
din nou comanda SELECT de mai sus!
În linia 18 apelăm la funcţia de bibliotecă UBOUND specială pentru matrici. Observaţi
că se comunică acestei funcţii cine este matricea şi câte dimensiuni are. UBOUND
întoarce numărul liniilor acestui masiv. Îl mărim cu o unitate. De ce? Nu intrăm în
detalii de teoria numerelor!
Mai departe, în variabila skip, stabilim din câte în câte linii sărim prin această matrice.
Pot fi mai mult de trei produse cu caracter de noutate în tabelul Produse! Dacă să zicem
există 8 produse noi, 8 împărţit la 3 (topVitrina) dă 2,66...! Priviţi la linia a 24-a. Aici
începe un bloc FOR. Spunem acum că după STEP urmează o expresie VBScript a cărei
valoare va servi blocului FOR. Valoarea nu va fi de tipul cu zecimale, ci una întreagă,
trunchiată la întregul imediat inferior. Deci skip va avea 2! Deci vom sări din două în
două linii. Ce ne facem că avem 8 noutăţi şi toate trebuie să fie expuse în vitrină!
Politica de advertising o rezolvă RND adcă alegerea la întâmplare! El ne oferă o valoare
cuprinsă între 0,000...01 şi 0,999... . În fond şi la urma urmei prin acest offset alegem
când rândurile pare când pe cele impare din matrice. În coloana a întâia se află
id_produs. Programatorii numără de la 0 nu de la 1! De aceea vedeţi
Vitrina_Masiv(0,i+offset). Deci în idProdus va intra chiar numărul identificator al
produsului „fericit”, că a fost selectat pentru afişare în fereastra document a acelui
vizitator x. RND întotdeauna oferă alt număr la următoarea apelare a sa. Deci alt
vizitator va primi în fereastra sa poate alte linii din Vitrina_Masiv. Chiar acest vizitator
dacă mai reintră puţin mai târziu va primi pe ecran pozele altor produse. It’s fantastic!
Really fantastic!
Mai departe, considerăm că sunteţi cunoscători ai HTML! Este vorba de un tabel în
sensul acestui limbaj (linia a 22-a). Tabelul este fără chenare, are spaţii de patru pixeli
între celule, nu are margini între conţinutul celulei şi chenarul acesteia. Tabelul are un
rând (tr din linia 30). În coloana din stânga (31-35) afişăm poza produsului nou iar în
celula alăturată, (36-39) datele referitoare la acesta, ş.a.m.d.!

Căutarea produsului după anumite


caracteristici
Am spus mai sus că în pagina principală a sitului se recurge frecvent la căutări. Pagina
care va trata aceste investigări ale vizitatorului se numeşte cauta.asp. Să o descifrăm!
LISTA 8.8 Pagina cauta.asp

01. <!-- #INCLUDE FILE="adovbs.inc" -->


02. <%

03. ' Atribui categoria curenta variabilei locale cat


04. cat = TRIM(Request("cat"))
05. ' Obtin comanda de cautare
06. IF cat = "" THEN cat = "Acasa"
07. camp_cautare = TRIM(Request("camp_cautare"))

08. ' Conectare la BD


09. Set Con = Server.CreateObject("ADODB.Connection")
10. Con.Open "sd"
11. %>

12. <html>
13. <head>
14. <title>Mypisi.shop</title>
15. </head>
16. <body link="#ff4040" vtext="lightred" bgcolor="fucsia">
17. <center>
18. <table width="640" border="0" bgcolor="#eeddcc" cellspacing="0"
cellpadding="0">
19. <tr>
20. <td colspan="2" align="center"><img src="logo.jpg"></td>
21. </tr>
22. <tr>
23. <td align="right" valign="bottom"><a href="cosuri.asp">Stare cos</a><td>
24. <td><a href="plata.asp">La plata!</a></td>
25. </tr>
26. </table>
27. <table width="640" border="0" bgcolor="#ffffff" cellpadding="0" cellspacing="0">
28. <tr>
29. <td valign="top">
30. <table cellpadding=0 cellspacing="0" border="0">
31. <tr>
32. <td valign="bottom" bgcolor="pink"><img src="cauta.jpg" vspace="0"
border="0"></td>
33. </tr>
34. <tr>
35. <td>
36. <table width="200" cellpadding="4" cellspacing="0" bgcolor="lightyellow"
border="1">
37. <tr>
38. <td><form method="post" action="cauta.asp">
39. <input name="camp_cautare" size="15">
40. <input type="submit" value="Cauta">
41. </form>
42. </td>
43. </tr>
44. </table>
45. </td>
46. </tr>
47. <tr>
48. <td></td>
49. </tr>
50. <tr>
51. <td valign="bottom"><img src="categorii.jpg" vspace=0 border="0"></td>
52. </tr>
53. <tr>
54. <td><table width="200" cellpadding="4" cellspacing="0" bgcolor="lightyellow"
border="1">
55. <tr>
56. <td><font size="3"><b><!-- #INCLUDE FILE="ListaCatalog.asp" --
></b></font></td>
57. </tr>
58. </table>
59. </td>
60. </tr>
61. </table>
62. </td>
63. <td valign="top">
64. <%
65. sqlString = "SELECT id_produs, caracteristici_produs, nume_produs " &_
66. "FROM Produse " &_
67. "WHERE stare_produs = 1 " &_
68. "AND (nume_produs LIKE '%" & camp_cautare & "%' " &_
69. "OR caracteristici_produs LIKE '%" & camp_cautare & "%') " &_
70. "ORDER BY nume_produs "
71. SET RS = Con.Execute(sqlString)

72. IF NOT RS.EOF AND camp_cautare <> "" THEN


73. %>
74. <table width="350" border="0" cellpadding="4" cellspacing="0">
75. <tr>
76. <td colspan="2"><font color="darkblue" size="3"><b>Rezultatul
cautarii:</b></font></td>
77. </tr>
78. <%
79. WHILE NOT RS.EOF
80. %>

81. <tr>
82. <td>
83. <%
84. IF RS("caracteristici_produs") <> "nil" THEN
85. %>
86. <IMG SRC="<%=RS("nume_produs")%>.jpg" hspace="4" vspace="4"
border="0" align="center">
87. <%
88. END IF
89. %>
90. </td>
91. <td><a
href="produs.asp?pid=<%=RS("id_produs")%>"><b><%=RS("nume_produs")%
></b></a></td>
92. </tr>
93. <%
94. RS.MoveNext
95. WEND
96. %>
97. </table>
98. <%
99. ELSE
100. %>
101. <table width="350" border="0" cellpadding="4" cellspacing="0">
102. <tr>
103. <td><font face="Arial" color="darkblue"><b>Nici un produs nu are caracteristicile
cerute de dvs. <br>Puteti cauta si dupa numele produsului. Deoarece nu il stiti,
puteti cauta dupa un cuvant de pilda: 15", TCO, pixel, boxe, mouse, DVD, CD,
disc etc. <br>Se intra in tabelul in campul caracteristicilor produsului! <br.Se
afiseaza tot ce are acel cuvant, grup de cuvinte separate prin blanc.</td>
104. </tr>
105. </table>
106. <%
107. END IF
108. %>
109. </td>
110. </tr>
111. </table>
112. </center>
113. </body>
114. </html>

Explicaţii şi parafraze
Mai întâi de toate anexăm la ea fişierul parametrilor ActiveX Data Object. Apoi
preluăm parametrul cat. Dacă această variabilă va avea chiar textul Acasa, atunci nu am
recurs încă la o selectare a unei categorii.
Nu suntem obligaţi să punctăm o anume categorie la vizitarea sitului, mai înainte de a
specifica un criteriu de căutare. Dacă totuşi există o informaţie de căutare în variabila
camp_cautare (vezi liniile 07 şi mai ales linia 39), acest conţinut va servi drept criteriu
de căutare. Nu am folosit încă rubrica de căutare. Deci camp_cutare nu va conţine
nimic. În acest caz programul caută un şir vid şi nu va găsi ceva în coloana
caracteristici_produs din tabelul Produse şi nici în coloana denumirilor de produs.
Atunci se va afişa un mesaj (linia 103): „Nici un produs nu are caracteristicile …”.
Dar să revenim. Ne conectăm logic la baza de date (09-10). Alocăm un tabel de 640
pixeli pe lăţime (linia 18). În rândul întâi al său afişăm imaginea logo.gif, care este sigla
magazinului. Priviţi figura 8.3a acel text Mypisi. Vedeţi că nu apare centrată. Acum o a
doua întrebare:
2. Unde am greşit de nu apare această poză centrată că doar am specificat
align=center. Răspuns: am scris colspan=2 în loc de 4.
Mai devreme erau doar două coloane. Pe rândul doi apar în fiecare coloană legăturile de
tip hypertext de care vorbeam mai sus. Programele care se ocupă de aceste legături sunt
cosuri.asp (linia 23), plata.asp (linia 24).
Sub acest tabel urmează altul fără chenare (linia 27). Este mai greu de observat. În fond,
fiecare rând are doar o celulă. În prima sa linie (28), în celula respectivă (linia 29)
afişăm o poză denumită cauta.jpg. Este acel cuvânt încadrat de o tentă de culoare (vezi
figura 8.3a). În rândul al doilea, pe doar 200 pixeli (linia 36) alocăm un alt tabel cu
chenar de un pixel (36).
Tabelul are doar o singură linie şi o celulă! În ea (linia 38) anunţăm că este un formular
cu două câmpuri logice, nume_cautare (linia 38) şi butonul de căutare (linia 40). În linia
39 este o fereastră de 15 caractere, unde înscriem cuvintele pe care le căutăm.
Formularul care se ocupă de căutare punctează spre programul cauta.asp, adică
programul pe care îl explicăm aici.
Urmează partea legată de categorii. Mai întâi este afişată o poză (linia 51), denumită
categorii.jpg. Poza este acel cuvânt „Categorii” încadrat de o tentă de culoare.
Mai departe, în linia 54 începe un alt tabel. Nu mai numărăm al câtelea este! Şi acesta
are tot 200 pixeli lăţime şi un chenar de un pixel ca şi tabelul rezervat căutării. Restul de
440 pixeli sunt rezervaţi vitrinei sitului.
În unica celulă a sa (linia 56) anunţăm că alipim static lista ListaCatalog.asp la pagina
index.asp.
În liniile 65-70 pregătim comanda de selectare după rubricile: id_produs,
caracteristici_produs şi nume_produs. Se caută doar în înregistrările cu produse la
vânzare (stare_produs=1).
Acum urmează ceva interesant! Observaţi în liniile 68 şi 69 acel cuvânt LIKE. Este un
operator de căutare generic al SQL. În fereastra criteriului de căutare am înscris unul,
poate două cuvinte. Fie acest criteriu „H120, V30” sau „TCO”. Se caută în ambele
coloane, nume_produs şi caracteristic_produs, ceva asemănător (LIKE) ca denumire cu
acest criteriu.
Morala! Putem căuta după denumirea completă sau incompletă a produsului. Exemple:
Reli sau Relisys sau sys sau LCD sau, şi mai exact, Relisys TL 561, în fine doar 561.
Putem căuta şi după o caracteristică a sa (exemple TCO sau FCC sau pixel etc.) Nu este
necesar a înscrie decât un cuvânt cel mult. Restul face LIKE. De fapt se înţelege că este
o căutare generică, cu ceva asemănător cu acea rădăcină. La momentul executării
comenzii de căutare vom avea ceva de genul: %561% sau %pixel% .
Remarcaţi rădăcina încadrată de două caractere procent.
Se execută apoi comanda în linia 71. Deci se lansează o căutare prin cele două câmpuri
ale tabelelei Produse. Tot ce se găseşte conform acestor criterii generice de căutare
ajunge într-un tabel rezultat tip RecordSet, denumit RS, aşa cum am făcut-o de multe
ori. Rândurile acestui tabel sunt apoi anunţate pe ecran cu blocul instrucţiunilor din
liniile 79-95. Se afişează chiar şi poza produsului căutat (linia 86) nu numai denumirea
sa (linia 91).
Dacă nu există nici un criteriu asemănător cu cel cerut de vizitator, se anunţă mesajul
din linia 103, aşa cum spuneam poate prea devreme mai sus.

La final de capitol
În acest capitol am parcurs:
1. Caietul de sarcini al sitului mypisi.
2. Tabelele şi rubricile (câmpurile) sitului.
3. Procedeul de operare al asocierii sursei de date la directorul care găzduieşte baza
de date mypi.mdb.
4. Programul de înscriere a produselor în tabelul Produse, adaugProdus.asp
5. Programul de administrare al parcului de produse, adminProduse.asp.
6. Programul de schimbare al conţinutului unui produs, actualizezProdus.asp.
7. Afişarea unui catalog de categorii de produse, listaCatalog.asp.
8. Afişarea tuturor produselor unei anumite categorii, listaProduse.asp
9. Pagina principală a sitului index.asp
10. Alegerea şi expunerea în vitrină a produselor noi, vitrina.asp.
11. Căutarea generică, programul cauta.asp.
9
Capitolul

Înregistrarea vizitatorilor unui sit


comercial în ASP
Mai aveţi răbdare? Abia am început! Vizitatorii trebuie înregistraţi. Ce mai
aşteptăm!

S
ă vedem cum înregistrăm vizitatorii noştri. De aceasta se ocupă mai multe pagini
şi anume: login.asp şi inreg.asp al căror liste sunt redate în continuare.

Circuitul noilor vizitatori


Mai înainte să redăm aspectul formularului de înscriere.

FIGURA 9.1 Formularul de înscriere pentru vizitatori noi, tabelul Clienti

Aici diferim mai mult de exerciţiul din referinţa /6/. Sunt două feluri de vizitatori, noi şi
vechi. Ne ocupăm de formularul celor noi. La acest formular se ajunge când efectuaţi
clic pe Vizitatori noi (vezi figura 8.3b), dacă am intrat prin „La prima vizita a sitului”.
Iată lista programului:
LISTA 9.1 Pagina inreg.asp

01. <%
02. ' Preiau valorile provenite din formular (obiect request)
03. ' si le inscriu in variabile locale VBS
04. numeclientnou = TRIM( Request( "numeclientnou" ) )
05. parolanoua = TRIM( Request( "parolanoua" ) )
06. emailclient = TRIM( Request( "emailclient" ) )
07. adresaclient = TRIM( Request( "adresaclient" ) )
08. codpostalclient = TRIM( Request( "codpostalclient" ) )
09. inreg = TRIM( Request( "inreg") )

10. ' response.write "inreg = " & inreg & "<BR>"


11. %>

12. <html>
13. <head><title>Inregistrare</title></head>

14. <body bgcolor="white">


15. <center>
16. <table width="500" border="0" cellpadding="4" cellspacing="0">
17. <tr>
18. <td bgcolor="blue"><font color="white"
face="Arial"><b>Inregistrare</b></font></td>
19. </tr>
20. <tr>
21. <td>
22. <form method="post" action="adaugVizitator.asp"
23. <input name="inreg" type="hidden" value="1">
24. <input name="pid" type="hidden" value="<%=idProdus%>">
25. <font face="Arial" size="2"><p><b>Informatii cerute pentru clientii noi:</b></font>
26. <font face="Courier" size="2"><br><b>Nume client:</b>
27. <input name="numeclientnou" size="20" maxlength="20"
value="<%=Server.HTMLEncode( numeclientnou )%>">
28. <br><b>Parola:</b><input name="parolanoua" size="20" maxlength="20"
value="<%=server.HTMLEncode( parolanoua )%>">
29. <br><b>Adresa de email:</b><input name="emailclient" size="30"
maxlength="75" value="<%=Server.HTMLEncode( emailclient )%>"></font>
30. <font face="Arial" size="2" color="darkgreen">
31. <p><b>Informatia de adresa:</b></font>
32. <font face="Courier" size="2">
33. <br><b>Adresa:</b><input name="adresaclient" size="50" maxlength="50"
value="<%=Server.HTMLEncode( adresaclient )%>">
34. <br><b>Codul postal cel nou:</b><input name="codpostalclient" size="20"
maxlength="20" value="<%=Server.HTMLEncode( codpostalclient )%>"></font>
35. <input type="submit" value="Inregistrare">
36. </font>
37. </form>
38. </td>
39. </tr>
40. </table>
41. </body>
42. </html>
Explicaţii şi parafraze
Preluăm datele completate în rubricile formularului în variabilele locale din liniile 04-
09. Linie a 10-a este o una de testare, din faza de punere la punct a sitului. Fiind acum
transformată într-un comentariu, nu îşi exercită acţiunea. În clipa în care efectuăm clic
pe butonul Inregistrare (linia 35) al formularului (linia 22), s-au preluat deja în două
câmpuri ascunse (hidden) valorile inreg (linia 23, o valoare egală cu 1) şi pid,
identificatorul produsului, vezi linia 24; valoarea este dată după ce are loc evaluarea
expresiei <%=idProdus%>. Această pagină poate fi referită şi din alt program.
Contextul îl dă identificatorul produsului. Reţineţi denumirile logice ale câmpurilor
„vizibile” ale formularului.
Ele sunt: numeclientnou, parolanoua, emailclient, adresaclient şi codpostalclient.
Când acţionaţi butonul Înregistrare, se trece la pagina adaugVizitator.asp. Să o redăm
acum pe aceasta.
LISTA 9.2 Pagina adaugVizitator.asp

01. <!-- #INCLUDE FILE="functii.asp" -->


02. <%

03. ' client nou


04. numeClientnou = TRIM( Request( "numeClientnou" ) )
05. parolanoua = TRIM( Request( "parolanoua" ) )
06. inreg = TRIM( Request( "inreg" ) )

07. ' response.write "inreg = " & inreg & "<BR>"


08. ' response.write "client nou = " & numeclientnou & "<BR>"
09. ' response.write "parola noua = " & parolanoua & "<BR>"
10. ' response.end

11. ' Deschid conexiunea logica cu BD


12. Set Con = Server.CreateObject( "ADODB.Connection" )
13. Con.Open "sd"

14. ' Este vorba de o noua inregistrare


15. IF error = "" THEN
16. adaugClient
17. END IF
18. %>
19. <html>
20. <body bgcolor="yellow">
21. <center>
22. <table width="400" border="3" cellpadding="10" cellspacing="7">
23. <tr>
24. <td>Multumim ca ne vizitati. Va rugam sa tineti minte parola dvs.</td>
25. </tr>
26. <tr>
27. <td>Ne scuzati, dar ca sa ne ferim de hoti va vom solicita la un moment dat
datele de identificare pentru fiecare marfa pe care intentionati sa o adaugati in
cosul de cumparaturi!</td>
28. </tr>
29. </table>
30. <form action="index.asp" method="post">
31. <input name="inreg" type="hidden" value="2">
32. <input type="submit" value="Succes la cumparaturi!">
33. </form>
34. </body>
35. </html>

Explicaţii şi parafraze
Această listă este scurtă! Observaţi instrucţiunile de testare a sitului (liniile 07-09) şi
acea instrucţiune de stopare brutală a execuţiei (10). Ea acţionează ca un punct de
întrerupere a execuţiei unui program, fără posibilitatea de a relua executarea sa, într-un
mediul de depanare precum Microsoft Visual InterDev. După ce deschidem conexiunea
logică la baza de date mypisi.mdb (liniile 12-13), dacă semaforul error nu a avut nimic,
deci formularul a fost corect completat la toate rubricile, vom adăuga clientul în tabelul
Clienţi (lansăm subrutina adaugClient din linia 16). Această subrutină se află în lista
functii.asp de care ne ocupăm mai jos.
Avertizăm pe vizitator că pregătim situl contra hoţilor! Deci să îşi ţină minte parola.
Evident , ca să mai descreţim fruntea oneştilor noştri vizitatori, în linia 32, le urmăm
totuşi succes la cumpărături!

Circuitul cumpărătorilor tradiţionali


Vizitatorul tradiţional intră prin legătura hypertext „Vizitator vechi”. În acest moment se
va intra în pagina login.asp. Iată lista ei în continuare:
LISTA 9.3 Pagina login.asp

01. <%
02. numeclient = TRIM( Request( "numeclient" ) )
03. parola = TRIM( Request( "parola" ) )
04. inreg = TRIM(Request( "inreg" ) )

05. ' response.write "login.asp: nume client " & numeclient & "<BR>"
06. ' response.write "login.asp: parola client " & parola & "<BR>"
07. ' response.write "login.asp: inreg " & inreg & "<BR>"

08. %>
09. <html>
10. <head><title>Client vechi</title></head>
11. <body bgcolor="white">
12. <center>
13. <table width="500" border="0" cellpadding="4" cellspacing="0">
14. <tr>
15. <td bgcolor="red"><font color="white" face="Arial"><b>Login</b></font>
16. </td>
17. </tr>
18. <tr>
19. <td>
20. <form method="post" action="verificclient.asp">
21. <input name="idclient" type="hidden" value="<%=idclient%>">
22. <font face="Arial" size="2">Va rog numele si parola dvs.:</font>
23. <font face="Courier" size="2"><p><b>Nume client vechi:</b><input
name="numeclient" size="20"></b>
24. <br><b>Parola:</b><input name="parola" size="20"></b>
25. <input type="submit" value="Login">
26. </font>
27. </form>
28. </td>
29. </tr>
30. </table>
31. </body>
32. </html>

Explicaţii şi parafraze
Distingem în cuprinsul acesteia un tabel HTML şi un formular tot HTML, cu două
rubrici vizibile (numeclient, parola, vezi liniile 22 şi 23) şi unul invizibil, deci hidden
(idclient, linia 21). Vă rugăm să remarcaţi că inreg este ţinut sub control în mod
permanent prin instrucţiunea din linia 04.
La acţionarea butonului pe care scrie Login (25) se predau programului verificclient.asp
conţinuturile acestor rubrici ca şi câmpul invizibil inreg!
Iată-ne ajunşi şi la programul verificclient.asp:
LISTA 9.4 Pagina verificclient.asp

01. <!-- #INCLUDE FILE="adovbs.inc" -->


02. <!-- #INCLUDE FILE="functii.asp" -->

03. <%
04. numeclient = TRIM( Request( "numeclient" ) )
05. parola = TRIM( Request( "parola" ) )
06. inreg = TRIM( Request( "inreg" ) )

07. ' response.write "verficclient.asp: inreg = " & inreg & "<BR>"

08. ' Conectare la BD


09. Set Con = Server.CreateObject("ADODB.Connection")
10. Con.Open "sd"

11. sqlString = "SELECT id_client, nume_client, parola_client FROM Clienti " &_
12. "WHERE nume_client='" & numeclient & "' " &_
13. "AND parola_client='" & parola & "'"
14. SET RS = Con.Execute(sqlString)

15. IF RS.EOF THEN


16. %>
17. <html>
18. <body bgcolor="red">
19. <P><FONT FACE="Verdana" COLOR="WHITE">A-ati uitat parola stimate
vizitator. Va trebui sa va inregistrati ca client nou.
20. <P>Pacat nu mai aveti acces la fostul dvs. cos de cumparaturi!
21. </FACE>
22. <form method="post" action="index.asp">
23. <input name="inreg" type="hidden" value="0">
24. <input type="submit" value="Inapoi">
25. </form>
26. </body>
27. </html>
28. <%
29. ELSE
30. cid = RS("id_client")
31. %>
32. <html>
33. <body bgcolor="#55eeaa">
34. <center>
35. <table width = "300" border="1" cellpadding="15" cellspacing="5">
36. <tr>
37. </tr>
38. <tr>
39. <td colspan="2" align="center"><img src = "logo.jpg"></td>
40. </tr>
41. <tr>
42. </tr>
43. </table>
44. <form method="post" action="index.asp">
45. <input type="submit" value="Inapoi">
46. <input type="hidden" name = "cid" value="<%=RS("id_client")%>"></td>
47. <input type="hidden" name ="inreg" value="2"></td>
48. </form>
49. </body>
50. </html>
51. <%
52. ' response.write "verificclient: idclient = " & cid & "<BR>"
53. ' response.end
54. END IF
55. %>

Explicaţii şi parafraze
Includem static cele două fişiere adovbs.inc şi functii.asp în primele două linii. În liniile
04 - 05 urmărim numele şi parola vizitatorului nou, ca şi semaforul inreg, pentru a
prinde impostorii! Urmează să căutăm vizitatorul în tabelul clienţilor. Atunci, mai întâi
ne conectăm logic la baza de date (09-10), apoi preparăm comanda de selecţie (11-13)
Distingem aici şi coloana id_client, pe lângă celelalte două menţionate mai sus. Vom
avea nevoie permanent de acest identificator al clientului la coşul de cumpărături şi la
emiterea comenzii. Vom căuta clientul nostru după numele şi parola introduse.
În cazul că nu este nimeni în tabelul clienţilor, tabelul rezultat RS va fi vid, adică nu va
avea nici un rând. Ca atare se va ridica de la început condiţia de EOF (linia 15). În acest
caz, bietul nostru client va primi ca mesaj ceva dezarmant şi pe fond de culoare roşie!
O paranteză. Aici programul ar putea fi perfecţionat. Clientului nou nu ar trebui să nu i
se solicite să „inventeze” o parola. Mai indicat este cum se procedează la numeroase
situri printre care şi situl free.fr. Aici se generează parola care apoi îi parvine celui care
vrea să se înscrie la acest sit prin poştă la adresa menţionată. Revenim. Acum unica
modalitate este aceasta: clientul trebuie ca să intre sub un nume puţin schimbat şi îşi
precizeze o altă parolă. Este deagreabil şi pentru acesta dar şi este neproductiv pentru
administrator, deoarece va colecta până la urmă o tabelă cu vizitatori uituci!
Dacă clientul şi-a cunoscut parola, evident comanda de căutare va întoarce un tabel cu
un singur rând (se merge pe ramura ELSE, deci secvenţa dintre liniile 30-54). Din acest
rând se va prelua identificatorul clientului, cid (linia 46), ce va fi transmis tot drept
parametru ascuns. În acest timp, clientul este invitat să folosească butonul Inapoi.
Totodată, în linia 47 se înscrie în semaforul inreg valoarea 2! În sfârşit clientul a căpătat
statutul de client vechi! Şi inreg are regimul ascuns.
Am tot evitat abordarea fişierului cu funcţii pentru acest sit. A venit şi timpul lor. Deci
să vedem ce conţine pagina functii.asp. Vă prevenim că este cea mai voluminoasă listă,
dar înglobează destule subrutine şi funcţii.

Colecţia de funcţii şi subprograme a sitului


Am spus în această carte care este diferenţa dintre o funcţie şi o subrutină în partea
legată de tehnologia JSP.
LISTA 9.5 Funcţii utile paginilor acestui sit

01. <%
02. FUNCTION apostrof12(Sirul)
03. apostrof12 = REPLACE(Sirul, "'", "''")
04. END FUNCTION

05. SUB adaugJalon(numele, valoarea)


06. Response.Cookies(numele) = valoarea
07. Response.Cookies(numele).Expires = "31.12.2003"
08. Response.Cookies(numele).Path = "/"
09. Response.Cookies(numele).Secure = FALSE
10. END SUB

11. FUNCTION verificparola(byVal numeclient, byVal parola, byRef Con)


12. ' response.write "verificparola: numeclient = " & numeclient & "<BR>"
13. ' response.write "verificparola: parola = " & parola & "<BR>"

14. sqlString = "SELECT id_client FROM Clienti " &_


15. "WHERE nume_client='" & numeclient & "' " &_
16. "AND parola_client='" & parola & "'"
17. SET RS = Con.Execute(sqlString)
18. IF RS.EOF THEN
19. verificparola = - 1
20. ELSE
21. verificparola = RS("id_client")
22. adaugJalon "numeclient", numeclient
23. adaugJalon "parola", parola
24. END IF
25. END FUNCTION

26. FUNCTION SELECTED(valoare1, valoare2)


27. IF cSTR(valoare1) = cSTR(valoare2) THEN
28. SELECTED = "SELECTED"
29. ELSE
30. SELECTED = ""
31. END IF
32. END FUNCTION

33. SUB eroareInFormular(mesajDeEroare)


34. %>

35. <html>
36. <head><title>Eroare in formular</title></head>
37. <body bgcolor="lightyellow">
38. <center>
39. <table width="500" border="1" cellpadding="4" cellspacing="0">
40. <tr>
41. <td><font face="Arial" size="3" color="darkblue"><b>Informatie introdusa este
eronata:</b></font>
42. <font size="2" color="red"><b><br><%=mesajDeEroare%></b></font><br>
43. <form method="post" action="inreg.asp">
44. <input name="error" type="hidden" value="1"><% campuriFormular %>
45. <input type="submit" value="Inapoi">
46. </form>
47. </td>
48. </tr>
49. </table>
50. </center>
51. </body>
52. </html>
53. <%

54. Response.End
55. END SUB

56. SUB campuriFormular


57. FOR EACH resursa IN Request.Form
58. %>
59. <input name="<%=resursa%>" type="hidden"
value="<%=Server.HTMLEncode(Request(resursa))%>">
60. <%
61. NEXT
62. END SUB

63. ' Functii pentru inregistrare


64. SUB adaugClient
65. ' Obtin campurile de inregistrare
66. numeclientnou = TRIM(Request("numeclientnou"))
67. parolanoua = TRIM(Request("parolanoua"))
68. emailclient = TRIM(Request("emailclient"))
69. adresaclient = TRIM(Request("adresaclient"))
70. codpostalclient = TRIM(Request("codpostalclient"))

71. ' Verific campurile obligatorii


72. IF numeclientnou = "" THEN
73. eroareInFormular "Trebuie sa specificati numele dvs."
74. END IF

75. IF parolanoua = "" THEN


76. eroareInFormular "Trebuie si parola dvs."
77. END IF

78. IF emailclient = "" THEN


79. eroareInFormular "Neaparat adresa dvs. de email."
80. END IF

81. IF adresaclient = "" THEN


82. eroareInFormular "Trebuie sa specificati adresa dvs."
83. END IF

84. IF codpostalclient = "" THEN


85. eroareInFormular "Trebuie sa specificati codul dvs. postal."
86. END IF

87. ' Verificare format email


88. IF formatgresitEmail(emailclient) THEN
89. eroareInFormular "Format gresit de casuta postala."
90. END IF

91. ' Oare nu este deja in BD acest client


92. IF dejaInBD(numeclientnou) THEN
93. eroareInFormular "Introduceti un alt nume. Cel introdus exista deja in tabelul
clienti din BD."
94. END IF

95. ' Adaug un client la BD


96. sqlString = "INSERT INTO Clienti (" &_
97. "nume_client, parola_client, email_client, adresa_client, cod_postal_client" &_
98. ") VALUES (" &_
99. " '" & apostrof12(numeclientnou) & "', " &_
100. " '" & apostrof12(parolanoua) & "', " &_
101. " '" & apostrof12(emailclient) & "', " &_
102. " '" & apostrof12(adresaclient) & "', " &_
103. " '" & apostrof12(codpostalclient) & "')"

104. Con.Execute sqlString

105. numeclient = numeclientnou


106. parola = parolanoua

107. adaugJalon "numeclient", numeclient


108. adaugJalon "parola", parola
109. END SUB

110. SUB actualizezClient

111. ' Preia campurile din formular


112. adresaclient = TRIM(Request("adresaclient"))
113. codpostalclient = TRIM(Request("codpostalclient"))
114. ' Verific campurile obligatorii

115. IF adresaclient = "" THEN


116. eroareInFormular "Nu ati introdus adresa."
117. END IF

118. IF codpostalclient = "" THEN


119. eroareInFormular "Nu ati introdus codul postal de client."
120. END IF

121. ' Actualizez informatia din BD referitoare la client


122. ' sqlString = "UPDATE Clienti SET " &_
123. ' "adresa_client='" & apostrof12(adresaclient) & "'," &_
124. ' "cod_postal_client='" & apostrof12(codpostalclient) & "' " &_
125. ' "WHERE id_client=" & idclient

126. ' Con.Execute sqlString


127. END SUB

128. FUNCTION formatgresitEmail(cp)


129. IF INSTR(cp, "@") = 0 OR INSTR(cp, ".") = 0 THEN
130. formatgresitEmail = TRUE
131. ELSE
132. formatgresitEmail = FALSE
133. END IF
134. END FUNCTION

135. FUNCTION dejaInBD(nClient)


136. sqlString = "SELECT nume_client FROM Clienti " &_
137. "WHERE nume_client='" & apostrof12(nClient) & "'"

138. SET RS = Con.Execute(sqlString)


139. IF RS.EOF THEN
140. dejaInBD = FALSE
141. ELSE
142. dejaInBD = TRUE
143. END IF
144. RS.Close
145. END FUNCTION

146. FUNCTION arataStareComanda( starea, dataLivrare )


147. ' Care este starea comenzii
148. SELECT CASE starea
149. CASE 0
150. arataStareComanda = "Produs nu este in stoc"
151. CASE 1
152. arataStareComanda = "In curs de livrare"
153. CASE 2
154. arataStareComanda = "Livrat la data de " & dataLivrare
155. CASE ELSE
156. arataStareComanda = "Stare necunoscuta"
157. END SELECT
158. END FUNCTION
159. %>
Explicaţii şi parafraze
Prima funcţie denumită apostrof12, se ocupă de dublarea acelui apostrof stingher.
Reamintim contextul: vă aduceţi aminte de acea valoare Scott’s Company şi de prolmea
de la SQL. Funcţia are ca parametri literalul ce urmează a fi transliterat.
Urmează să ne întâlnim acum cu acele jaloane, cookies, prezentate cu lux de amănunte
în capitolul 6.
Subrutina care se ocupă de înregistrarea unui jalon am denumit-o adaugJalon. Are doi
parametri fictivi, numele şi valoarea. Din punct de vedere al tehnologiei ASP, cookie
este o colecţie ca şi colecţiile Form, ServerVariables ale obiectului request. Request are
în total vreo cinci colecţii. Nu le prezentăm.
În linia 07 înregistrăm într-un fişier din directorul Cookie al sesiunii utilizatorului
Windows, un jalon cu denumirea stabilită de conţinutul primit de paramterul numele.
Mai clar, pentru ca să înregistrăm un jalon denumit foo şi sub denumirea de Gheorghita
Marius, care să expire la 31 dec. 2003, recurgem la două linii ca acestea:
Request.Cookie(“foo”) = “Gheorghita Marius”
Request.Cookie(“foo”).Expire = “31.12.2003”

Deoarcere dorim ca acest jalon să fie persistent, recurgem la atributul Expires (linia 07).
În lipsa acestui atribut jalonul „va dăinui” doar atât cât durează sesiunea utilizatorului.
Aplicaţia de faţă îşi mai pasează parametrii şi prin intermediul acestui jalon.
Un jalon persistent este o soluţie nefericită, pentru că spaţiul dedicat jaloanelor este
limitat. Într-un singur sit Web nu se admit decât maximum 25-30 blocuri tip cookie. Per
total, un calculator nu poate înmagazina decât pe vreo 4 Kb, ceea ce ar reveni la cca.
250-300 jaloane.
Să ne ocupăm mai pe scurt de funcţia de verificare a parolei, denumită verificparola,
întrucât am făcut-o deja în paragraful consacrat prezentării limbajului VBScript. Ea
începe de la linia a 11-a. Are trei parametri. Primii doi sunt pasaţi prin valoare, iar Con
este pasat prin referinţă. Funcţia prepară o comandă de selecţie, pentru că verifică parola
unui client din tabelul clienţilor. Comanda este formată în liniile 14-16. Executarea are
loc în linia a 17-a. Atunci se obţine o instanţă a unui obiect tip RecordSet denumit RS.
Dacă acest tabel rezultat nu are nici un rând, clientul nu există, deci se îndeplineşte de la
început condiţia EOF. Ca atare, funcţia va întoarce -1.
Poate că aţi remarcat până acum acea linie
idclient = verificparola(numeclient, parola, Con)

Dacă există, vedeţi cum are loc marcarea clientului (linia 21) şi cum creăm acele două
jaloane de care am spus mai sus (liniile 22 şi 23).
Despre funcţia SELECTED am mai vorbit în paragraful despre VBScript. Se compară
doi literali. Comparaţia are loc în sensul lexicografic al codului UNICODE. Secvenţa
lexicografică aranjează caracterele astfel: !, @, #, $, %, ^, &, cifrele 0, 1, 2, 3, ..., 9, apoi
literele mici, cele mari ş.a.m.d.. Blancul are valoarea cea mai mică, mai mică chiar decât
semnul mirării. Miraţi-vă dar aceasta este secvenţa lexicografică. Ea corespunde unor
coduri binare stabilite pentru aceste caractere (vezi /1/).
A venit rândul subrutinei eroareInFormular (linia 33). Acesta preia mesajul de eroare în
unicul parametru fictiv. Această funcţie este apelată de către subrutina adaugClient, ce
va fi prezentată mai jos.
Ea cheamă la rându-i subrutina campuriFormular (linia 56). Aici întâlnim instrucţiunea
FOR EACH proprietate IN obiect.colecţie

VBScript nu operează numai cu date logice, întregi, date zecimale şi şiruri de caractere
ci şi cu obiecte ActiveX. Request este un obiect ActiveX. Form este o colecţie a lui
request.
Formularul are o serie de câmpuri logice. Ca orice buclă FOR, ea se termină printr-un
NEXT (este vorba de grupul 57 - 61). Corpul ei nu face altceva decât să extragă şi să
afişeze valoarea acelui câmp, pentru ca vizitatorul să nu mai fie nevoit a-l completa, deci
de a pierde timpul cu reumplerea întregului formular, în caz de eroare de completare!
Cu începere de la linia a 63-a şi până la linia a 109-a se întinde subrutina adaugClient.
Se preiau conţinuturile rubricilor şirului de interogare (liniile 66-70), se elimină spaţiile
redondante (TRIM).
Apoi se cercetează valorile rubricilor formularului de înscriere prin triadele IF ... END
IF. În caz de rubrică necompletată, se anunţă mesajul respectiv şi se revine la pagina
inreg.asp.
Se verifică în linia 88 corectitudinea formatului căsuşei poştale cu funcţia denumită
formatgresitEmail.
Ne întrebăm în linia 92 dacă vizitatorul nu se află deja în tabelul clienţi. Acest caz apre
când cineva ar recurge la acelaşi nume!
În sfârşit, în zona 96-103 compunem comanda de inserare a valorilor acelui client.
Executarea ei se produce în linia 104. Se memorează în două variabile locale numele şi
parola clientului, apoi în final, se înregistrează în blocuri tip cookie numele clientului şi
parola sa.
Am văzut care sunt dezavantajele acestor cookie. Mai este unul: dacă posesorul unui PC
dezactivează intenţionat facilitatea de înregistrare a jaloanelor, aplicaţia aceasta nu va
mai funcţiona corect!
Funcţia care verifică corectitudinea formatului căsuţei poştale se află în liniile 128-134.
Ea recurge la serviciile unei funcţii de bibliotecă VBScript cu numele INSTR (adică in
string, în şir). Se caută în şirul de caractere al adresei de e-mail un caracter @ şi cel puţin
un punct. Funcţia întoarce valoarea logică FALSE, dacă formatul căsuţei poştale nu este
corect!
O altă funcţie adhoc, dejainBD verifică existenţa în tabelul Clienţi a unui aceluiaşi nume
(liniile 135-145). Preparăm comanda de căutare SQL în tabelul clienţilor şi o executăm.
Căutăm un client cu numele nClient (parametrul fictiv). Dacă există aşa ceva, atunci
funcţia va întoarce valoarea logică adevărat, TRUE. În caz contrar, ea va întoarce
valoarea logică fals, FALSE.
Ca exerciţiu vă adresăm o altă întrebare:
3. Vă solicităm să descifraţi subrutina actualizezClient (liniile 110-127).
Ultima funcţie din acest lung periplu se referă la starea comenzii. O comandă emisă la
cererea vizitatorului trece ca orice tranzacţie prin stadiile: în curs de livrare, a fost livrat
la data de ... sau are o stare necunoscută. Toate aceste cazuri sunt decelate de
instrucţiunea compusă SELECT din liniile 148-157.
10
Capitolul

Coşul de cumpărături şi partea


legată de comenzi şi plăţi
Nu disperaţi! Suntem la finalul exemplului. Situl electronic nu poate fi conceput
fără coşul de cumpărături ş programele care se ocupă de formele de plată.

Coşul de cumpărături, interceptarea … „e-


hoţilor”

P rogramul de bază este cosuri.asp. Programul însoţitor este denumit


adaugacos.asp.
Orice client are propriul său coş electronic care este păstrat într-un tabel denumit
cos, până când acesta doreşte comanda fermă. Coşul este piesa strategică pentru
compartimentul de marketing al proprietarului magazinului virtual.
Ca să nu adormiţi citind aceste liste, a venit rândul ca să vă întrebăm mai des în care linii
se realizează obiectivele de mai jos pentru pagina cosuri.asp:
LISTA 10.1 Pagina cosuri.asp

01. <!-- #INCLUDE FILE="adovbs.inc" -->


02. <!-- #INCLUDE FILE="functii.asp" -->
03. <%

04. ' Obtin id-ul produsului


05. idProdus = TRIM(Request("pid"))
06. numeclient = TRIM(Request("numeclient"))
07. inreg = TRIM(Request("inreg"))
08. parola = TRIM(Request("parola"))
09. ' response.write "cosuri: nume client este " & numeclient & "<BR>"
10. ' response.write "cosuri: parola = " & parola & "<BR>"
11. ' response.write "cosuri: inreg " & inreg & "<BR>"
12. ' Deschid conexiunea logica cu BD
13. Set Con = Server.CreateObject( "ADODB.Connection" )
14. Con.Open "sd"

15. idclient = verificparola(numeclient, parola, Con)


16. ' response.write "cosuri: idclient este " & idclient & "<BR>"
17. ' response.end
18. IF idclient > 1 AND inreg = "2" THEN
19. %>
20. <!-- #INCLUDE FILE="adaugcos.asp" -->
21. <%
22. ELSE
23. %>
24. <!-- #INCLUDE FILE="login.asp" -->
25. <%
26. END IF
27. %>

Explicaţii şi parafraze
1. În ce mod se includ fişierele adovbs.inc şi functii.asp?
2. Comentariul din linia 04 este incomplet. Ce credeţi că se obţine în liniile 05-08?
3. Acele response.write sunt instrucţiuni sau comentarii? Ce este response dar ce este
write (indicaţie: response este tot un obiect implicit ca şi request).
4. Unde se obţine acel număr logic (handle) de acces la baza de date (specificaţi
liniile)?
5. Variabila idclient este tot una cu idClient? Ce valori poate conţine aceasta?
(indicaţie: aveţi în vedere şi pagina functii.asp)
6. Pentru care valori ale semafoarelor idclient şi inreg se alipeşte pagina adaugcos.asp?
7. Dar pagina login.asp?
8. A scrie END IF este tot una cu a scrie ENDIF?
Iată, v-am mai trezit poate din letargia pe care aţi capătat-o, citind adormiţi ce fac aceste
liste!
Să continuăm într-o manieră similară şi cu pagina adaugCos.asp a cărei listă o vedeţi
mai jos:
LISTA 10.2 Pagina adaugCos.asp

01. <!-- #INCLUDE FILE="functii.asp" -->


02. <%
03. ' Obtin identificatorul produsului si clientului
04. idProdus = TRIM(Request("pid"))
05. numeclient = TRIM(Request("numeclient"))
06. parola = TRIM(Request("parola"))
07. ' response.write "adaugcos.asp: nume client este " & numeclient & "<BR>"
08. ' response.write "adaugcos.asp: parola = " & parola & "<BR>"
09. idclient = verificparola(numeclient, parola, Con)
10. ' response.write "adaugcos.asp: idclient este " & idclient & "<BR>"
11. ' response.end

12. ' Caut in tabelul cos sa vad daca am client deja cu un anume id
13. ' si chiar cu un acelasi id de produs, ca sa il insumez
14. IF idProdus <> "" THEN
15. sqlString = "SELECT id_cos FROM cos " &_
16. "WHERE id_client_cos=" & idClient & " " &_
17. "AND id_produs_cos=" & idProdus

18. SET RS = Con.Execute(sqlString)


19. IF RS.EOF THEN
20. sqlString = "INSERT INTO cos (" &_
21. "id_client_cos, " &_
22. "id_produs_cos, " &_
23. "cantitate_cos " &_
24. ") VALUES (" &_
25. idClient & ", " &_
26. idProdus & ", 1)"
27. ELSE
28. sqlString = "UPDATE cos SET " &_
29. "cantitate_cos=cantitate_cos+1 " &_
30. "WHERE id_cos=" & RS("id_cos")
31. END IF
32. RS.Close
33. SET RS = Nothing

34. Con.Execute sqlString


35. END IF

36. ' Actualizez cantitatile din cosul de cumparaturi


37. IF Request("updateQ") <> "" THEN
38. SET RS = Server.CreateObject("ADODB.Recordset")
39. RS.ActiveConnection = Con
40. RS.CursorType = adOpenDynamic
41. RS.LockType = adLockOptimistic
42. sqlString = "SELECT id_cos, cantitate_cos FROM cos " &_
43. "WHERE id_client_cos=" & idClient
44. RS.Open sqlString

45. WHILE NOT RS.EOF


46. newQ = TRIM(Request("pq" & RS("id_cos")))
47. eliminProdus = TRIM(Request("pq" & RS("id_cos")))
48. IF newQ = "" OR newQ = "0" THEN
49. RS.Delete
50. ELSE
51. IF isNumeric(newQ) THEN
52. RS("cantitate_cos") = newQ
53. END IF
54. END IF
55. RS.MoveNext
56. WEND
57. RS.Close
58. SET RS = Nothing
59. END IF
60. %>

61. <html>
62. <head><title>Cosul de cumparaturi</title></head>
63. <body bgcolor="white">
64. <center>
65. <font face="Arial" size="3" color="darkgreen"><b>Cosul de cumparaturi al
domnului/doamnei/d-soarei. <%=numeClient%></b></font>
66. <%

67. ' Obtin id-ul cosului de cumparaturi


68. sqlString = "SELECT id_cos, nume_produs, " &_
69. "pret_produs, cantitate_cos " &_
70. "FROM cos, produse " &_
71. "WHERE id_client_cos=" & idClient & " " &_
72. "AND id_produs_cos = id_produs " &_
73. "ORDER BY id_cos DESC"

74. SET RS = Con.Execute(sqlString)


75. IF RS.EOF THEN
76. %>
77. <p><b>Cosul este gol!</b><p>
78. <form action="verificclient.asp">
79. <input type="submit" value="Scuzati o verificare de rutina!">
80. </form>
81. <%
82. ELSE
83. totalDePlata = 0
84. %>
85. <form method="post" action="cosuri.asp">
86. <input name="updateQ" type="hidden" value="1">
87. <input name="numeclient" type="hidden" value="<%=numeclient%>">
88. <input name="parola" type="hidden" value="<%=parola%>">
89. <table bgcolor="lightyellow" border="1" cellpadding="4" cellspacing="0">
90. <tr bgcolor="lightgreen">
91. <th>Produsul</th>
92. <th>Pretul (lei)</th>
93. <th>Cantitatea (buc)</th>
94. </tr>
95. <%
96. WHILE NOT RS.EOF
97. totalDePlata = totalDePlata + (RS("pret_produs") * RS("cantitate_cos"))
98. %>
99. <tr>
100. <td><%=Server.HTMLEncode(RS("nume_produs"))%></td>
101. <td><%=RS("pret_produs")%></td>
102. <td><input name="pq<%=RS("id_cos")%>" type="text" size="4"
value="<%=RS("cantitate_cos")%>"></td>
103. </tr>
104. <%
105. RS.MoveNext
106. WEND

107. IF totalDePlata > 80000000 THEN


108. ' Posibil impostor intercepteaza-l
109. ' Aici nu am cum sa-i prind pe impostori
110. ' Oricum astia se arunca la furat pe banii lui ... Trahanache!
111. ' Daca stiti dvs. alta metoda mai buna ziceti-mi-o!
112. ' Il iau pe nemteste daca tot mananca lebedele!
113. %>
114. <center>
115. <table border="3" cellpadding="13" cellspacing="5">
116. <tr>
117. <td>Entschuldigung! Aber Sie sind ein impostor!
118. <P>Die Polizei ist alarmiert gewessen!
119. <P>Ihre Eintritt caput im unseren Site!
120. </td>
121. </tr>
122. </center>
123. </table>
124. <%
125. ELSE
126. %>
127. <tr bgcolor="yellow">
128. <td colspan="2" align=right><b>Total de plata:</b></td>
129. <td><%=totalDePlata%></td>
130. </tr>
131. <tr>
132. <td colspan="3"><table border="0">
133. <tr>
134. <td align="right"><input type="submit" value="Schimb continutul cosului"></td>
135. </form>
136. <form method="post" action="completarecomanda.asp">
137. <input name="numeclient" type="hidden" value="<%=numeclient%>">
138. <input name="parola" type="hidden" value="<%=parola%>">
139. <td><input type="submit" value="Finalizarea comenzii"></td>
140. </form>
141. <form action="index.asp">
142. <td><input type="submit" value="Mai cumpar!"></td>
143. </form>
144. </tr>
145. </table>
146. </td>
147. </tr>
148. </table>
149. <%
150. END IF
151. END IF
152. %>
153. </center>
154. </body>
155. </html>
Explicaţii, parafraze şi întrebări
1. Funcţia TRIM este una creată de noi în pagina functii.asp sau nu? Ce realizează
ea?
2. Câmpul pid este un câmp logic sau nu?
3. Ce rost au acele apostrofuri din prima linie? (vezi liniile unde apar cuvintele
response.write)
4. Ce este response, dar write?
5. Dacă am fi scris con şi nu Con era greşit?
6. Dacă am fi scris fără virgule parametrii din parantezele încadratoare de după
cuvântul verificparola era greşit?
7. Care este sensul semantic al cuvântului verificparola?
8. Ce vrea să însemne în linia 14 operatorul de comparaţie <> , dar notaţia “”?
9. Ce face comanda SQL din liniile 15-17?
10. Dar cea din linia 18 ?
11. Dar comanda SQL din liniile 20-26?
12. Cum spunem denumirii RS, ce este ea în fond un obiect, un tabel?
13. În care linii se execută comenzi SQL?
14. Ce să însemne oare IF RS.EOF THEN?
15. Pe ramura ELSE are loc o … (spuneţi dvs. ce anume)?
16. De unde şi până unde ţine IF-ul din linia 14?
17. Dar IF-ul din linia 19?
18. Dacă RS este un obiect atunci close (linia 33) ce este?
19. În care linie are loc creşterea cu o unitate a numărului bucăţilor produsului
adăugat în coş?
Aici ne oprim!
Să privim acum linia 36. Aici se anunţă prin comentariu că va avea loc o actualizare a
conţinutului coşului de cumpărături, dacă semaforul updateQ, plasat în alt program este
diferit de zero.
Creeăm un obiect tip RecordSet, dar alegem un aşa-zis cursor evoluat. Când apelăm un
obiect RecordSet, acesta este deschis în modul cel mai economic ca volum de resurse
implicate. Aceasta revine la a i se pune la dispoziţie un cursor, ce permite doar mişcarea
de avansare spre sfârşitul tabelului rezultat, cum i se mai spune obiectului tip RecordSet.
Există însă şi deschiderea tabelului cu un cursor static:
RS.CursorType = adOpenStatic

ca şi deschiderea cu un cursor dinamic:


RS.CursorType = adOpenDynamic

cum se poate vedea în acest program. Instrucţiunea din linia 41 anunţă faptul că se poate
modifica conţinutul tabelului. În acest sens se foloseşte proprietatea LockType a
obiectului RS, plasată pe valoarea adLockOptimistic.
În figura 10.1 vedem un coş cu trei produse: maus, laptop şi DVD. Sunt comandate
două bucăţi de maus. Cumpărătorul se răzgândeşte şi înscrie un zero în dreptul
laptopului, deci renunţă la marfă. Apoi selectează butonul „Schimb conţinutul coşului”.

FIGURA 10.1 Aspectul coşului cumpărătorului Vernescu Florica

În următorul moment se reafişează coşul fără acest laptop.


Acum vă întrebăm din nou:
31. Ce se realizează în liniile 46 ?
32. De unde şi până unde (ca număr al liniilor) se întinde blocul while?
33. Ce este RS dar Open?
În cadrul acestui bloc semaforul newQ preia conţinutul pq urmat de un număr, care este
identificatorul coşului. În semaforul eliminProdus memorăm literalul pd, urmat de
identificatorul coşului.
Dacă newQ este vid sau (OR) este egal cu 0 (linia 48) se elimină acel produs din coş.
Altfel (liniile 51-53) rămâne să se verifice dacă newQ este numeric. Dacă este aşa,
înseamnă că vizitatorul a înscris o nouă valoare în dreptul acelui produs, deci schimbă
conţinutul coşului. Cu RS.MoveNext se avansează la următorul produs din coşul id_cos.
În linia 57 se închide logic tabelul RS. Mai mult chiar, RS preia condiţia Nothing, nimic.
Altfel spus, tabelul rezultat dispare de pe ecran.
Din nou vă întrebăm:
34. Ce se realizează în liniile 68-73, dar în linia 74?
35. Ce condiţie se verfică în linia 75?
36. Ce marchează acel separator din linia 76?
Costul total valoric al coşului se formează în variabila totalDePlata; în linia 83 acest
total este iniţializat.
În proximul bloc while se urmăreşte produs cu produs, rubrica număr de bucăţi şi se
multiplică cu costul produsului. Întrebare:
37. Care este linia unde se efectuează o atare operaţie?
Dacă totalul depăşeşte valoarea de 80 milioane (linia 107) se consideră că este vorba de
un impostor, deoarece numai un hoţ cumpără cât mai mult pe banii altuia! Aici este
poate o lipsă a programului că am recurs la un aşa compromis. Nu mai lăsăm ca acel
client şi acel coş să se transforme în ordin de plată ca să nenorocim un plătitor de bună
credinţă! În liniile următoare îi zicem impostorului ce se va întâmpla în limba germană!

FIGURA 10.2 Aspectul coşului unui posibil impostor care a profitat de acces la coşul
cumpărătoarei Vernescu Florica
Emiterea comenzii
Când efectuăm un clic pe butonul „Finalizarea comenzii”, va intra în acţiune fişierul
denumit completarecomanda.asp. Întrebare:
38. Care este linia din programul de mai sus unde se anunţă că va intra în acţiune
programul completarecomanda.asp?
Să ne ocupăm de lista sa:
LISTA 10.3 Pagina completareComanda.asp

01. <!-- #INCLUDE FILE="functii.asp" -->


02. <%

03. ' Obtin ionfo de login


04. numeclient = TRIM( Request( "numeclient" ) )
05. parola = TRIM( Request( "parola" ) )

06. ' response.write "completarecomanda.asp: nume client = " & numeclient &
"<BR>"
07. ' response.write "completarecomanda.asp: parola sa = " & parola & "<BR>"
08. ' response.end

09. ' Deschid conexiunea logica la BD


10. Set Con = Server.CreateObject( "ADODB.Connection" )
11. Con.Open "sd"
12. idclient = verificparola(numeclient, parola, Con)
13. IF idclient > 0 THEN
14. %>
15. <!-- #INCLUDE FILE="finalcomanda.asp" -->
16. <% ELSE %>
17. <!-- #INCLUDE FILE="login.asp" -->
18. <%
19. END IF
20. %>

Explicaţii, parafraze şi întrebări


Nu scăpaţi de întrebări! Aşadar:
39. În care linie se crează o instanţă a obiectului Con?
40. Dacă există un client, atunci ce întoarce verificparola? (indicaţie : examinaţi
pagina functii.asp)
41. Dacă idclient este egal cu -1 (funcţii.asp), care fişier se va include?
Finalizarea şi urmărirea comenzii
Programul care va realiza efectiv finalizarea comenzii este denumit
finalcomanda.asp. Îi redăm mai jos lista:
LISTA 10.4 Pagina finalComanda.asp

01. <!-- #INCLUDE FILE="adovbs.inc" -->


02. <!-- #INCLUDE FILE="functii.asp" -->

03. <%
04. ' Regasesc informatiile de inregistrare
05. sqlString = "SELECT * FROM clienti " &_
06. "WHERE id_client=" & idClient

07. ' Adauga noua adresa si informatia de plata


08. ' Mai intai care este id-ul clientului

09. SET RS = Con.Execute( sqlString )


10. IF NOT RS.EOF THEN
11. adresaclient = RS( "adresa_client" )
12. codpostalclient = RS( "cod_postal_client" )
13. END IF

14. ' Deschid conexiunea logica la BD


15. Set Con = Server.CreateObject( "ADODB.Connection" )
16. Con.Open "sd"

17. ' Incep o tranzactie


18. Con.BeginTrans

19. ' Transfer datele din tabelul cos in tabelul comenzi


20. sqlString = "INSERT INTO comenzi (" &_
21. "id_comanda, " &_
22. "id_produs_comanda, " &_
23. "cantitate_comanda, " &_
24. "id_client_comanda, " &_
25. "data_intrare_comanda, " &_
26. "stare_comanda " &_
27. ") SELECT " &_
28. "id_cos, " &_
29. "id_produs_cos, " &_
30. "cantitate_cos, " &_
31. "id_client_cos, " &_
32. "NOW(), " &_
33. "0 " &_
34. "FROM cos WHERE " &_
35. "id_client_cos =" & idclient
36. Con.Execute sqlString

37. ' Goleste cosul de cumparaturi fiindca s-a transferat totul in comanda de livrare
38. sqlString = "DELETE FROM cos " &_
39. "WHERE id_client_cos=" & idclient
40. Con.Execute sqlString

41. ' Finalizez tranzactia


42. Con.CommitTrans
43. %>

44. <html>
45. <head><title>Comanda gata de plasare</title></head>
46. <body>
47. <center>
48. <table border=1 width=500 bgcolor="lightyellow" cellpadding="10"
cellspacing="0">
49. <tr>
50. <td><font face="Arial" size="3"><b>Va multumim pentru acceptarea livrarii
produselor!</b><br><form action="index.asp">
51. <input type="submit" value="Mai cumpar"></form>
52. </td>
53. </tr>
54. </table>
55. </body>
56. </html>

Explicaţii, parafraze şi întrebări


Cercetăm să vedem dacă în tabelul clienţi există un client cu numărul din idClient.
42. Care sunt liniile unde se realizează acest lucru?
Dacă tabelul rezultat RS nu este vid, deci clientul există, preluăm în adresaclient şi
codpostalclient valori din coloanele obiectului RS. Priviţi liniile 11 şi 12.
În linia 18 aplicăm metoda BeginTrans() din cadrul bibliotecii ADO, Activex Data
Object. Metoda este afiliată obiectului Con, conexiunea logică.
O paranteză. Ca să ne ocupăm de operaţiile cu baze de date, obiectul tip ADO denumit
aici Con, este însoţit de trei metode: una pentru debutul tranzacţiei, BeginTrans(), alta
pentru sfârşitul ei, CommitTrans() şi în sfârşit a treia, destinată reluării unei tranzacţii
neterminate corect (pentru termenul rollback, vezi referinţa /1/). Este denumită chiar
RollBackTrans(). Încheiem paranteza!
Trimitem apoi conţinutul coşului posesorului idClient pe de-a-întregul în altă tabelă din
baza mypisi.mdb, cu numele de comenzi. Întrebări:
43. De la ce linie începe secvenţa de transfer a datelor în această tabelă?
44. Ce realizează comanda INSERT şi ce câmpuri sunt implicate?
45. Care este criteriul de selecţie din această comandă? Descifraţi-i sensul său
semantic?
46. Care linii din codul de mai sus conduc la radierea coşului clientului din baza
cos?
Mai avem de tratat două pagini. Mai întâi iată lista paginii plata.asp:
LISTA 10.5 Pagina plata.asp

01. <!-- #INCLUDE FILE="adovbs.inc" -->


02. <!-- #INCLUDE FILE="functii.asp" -->
03. <%

04. ' Informatii de login


05. numeclient = TRIM(Request("numeclient"))
06. parola = TRIM(Request("parola"))

07. ' response.write "numeclient = " & numeclient & "<BR>"


08. ' response.write "parola = " & parola & "<BR>"

09. ' Deschid o conexiune logica la BD


10. Set Con = Server.CreateObject("ADODB.Connection")
11. Con.Open "sd"

12. ' Obtin ID-ul clientului


13. idClient = verificParola(numeclient, parola, Con)
14. ' response.write "idclient = " & idclient & "<BR>"
15. ' response.end

16. IF idClient > 0 THEN


17. %>
18. <!-- #INCLUDE FILE="starecomenzi.asp" -->
19. <% ELSE %>
20. <!-- #INCLUDE FILE="login.asp" -->
21. <%
22. END IF
23. %>

La lista de mai sus parcă am fi tentaţi a vă ruga ca să


47. Descifraţi singuri!
Am ajuns la ultima pagină a sitului, cea denumită starecomenzi.asp:
LISTA 10.6 Pagina stareComenzi.asp

01. <!-- #INCLUDE FILE="functii.asp" -->


02. <%
03. ' Obtin ID-ul clientului
04. idClient = verificParola(numeclient, parola, Con)
05. ' response.write "idclient = " & idclient & "<BR>"
06. ' response.end

07. IF idclient > 1 THEN


08. sqlString = "Select comenzi.*, nume_produs " &_
09. "from comenzi, produse " &_
10. "WHERE id_produs_comanda=id_produs " &_
11. "AND id_client_comanda=" & idclient & " " &_
12. "ORDER BY data_intrare_comanda DESC"

13. SET RS = Con.Execute( sqlString )


14. %>
15. <html>
16. <head><title>Starea comenzii</title></head>
17. <body>
18. <center>
19. <%
20. IF RS.EOF THEN
21. %>
22. <b>Nu ati lansat nici o comanda</b>
23. <%
24. ELSE
25. %>
26. <table cellpadding="4" cellspacing="0" bgcolor="lightyellow" border="1">
27. <tr>
28. <th>ID comanda</th>
29. <th>Data comanda</th>
30. <th>Nume produs</th>
31. <th>Stare comanda</th>
32. </tr>
33. <%
34. WHILE NOT RS.EOF
35. %>
36. <tr>
37. <td><%=RS( "id_comanda" )%></td>
38. <td><%=RS( "data_intrare_comanda" )%></td>
39. <td><%=RS( "nume_produs" )%></td>
40. <td><%=arataStareComanda( RS( "stare_Comanda" ), RS(
"data_livrare_comanda" ) )%></td>
41. </tr>
42. <%
43. RS.MoveNext
44. WEND
45. %>
46. </table>
47. <%
48. END IF
49. ELSE
50. %>
51. <p><form action="index.asp">
52. <input type="submit" value="Intrati din nou in magazin!">
53. </form>
54. </center>
55. </body>
56. </html>
57. <%
58. end if
59. %>

Explicaţii, parafraze şi … din nou întrebări


Dacă clientul din conţinutul variabilor locale numeclient şi parola, este găsit în tabelul
clienţilor (linia 07), atunci idClient va fi diferit de valoarea -1.
Se va prepara comanda de selectare din două tabele, comenzi şi produse. Din tabelul
produse ne interesează coloanele nume_produs şi id_produs, iar din tabelul comenzi,
id_client_comanda şi id_produs_comanda.
Criteriul de căutare va fi coincidenţa pe de o parte a identificatorului produsului pentru o
anume comandă cu id_produs şi totodată şi pe de altă aprte a identificatorul clientului
acelei comenzi, id_client_comanda, cu idclient. Ordonarea se face după data de intrare a
comenzii, data_intrare_comanda.
Când nu întoarce nici un obiect RecordSet (linia 20) se intră prin ramura THEN. În caz
contrar, se parcurge rând după rând, marfă după marfă, cu bucla WHILE acest tabel
rezultat. În prealabil se afişează un antet (liniile 28-31). Funcţia arataStareComanda
întoarce conţinutul stării comenzii şi data sa de livrare, după care se reintră în sit.
Întrebare:
47. Care se realizează în linia 40 de fapt?

La final de capitol
În acest ultim capitol al tehnologiei ASP ne-am ocupat de :
1. Pagina de bază a părţii legate de coşul de cumpărături, cosuri.asp.
2. Cum se adaugă un produs în coşul de cumpărături, adaugCos.asp.
3. Cum este prins un posibil impostor, adaugCos.asp.
4. Cum se emite un ordin de plata de fapt, cum se transmite conţinutul coşului din
tabelul cos în tabelul comezi, vezi paginile: completarecomanda.asp,
finalcomanda..asp, plata.asp şi starecomenzi.asp.
Întrebări şi răspunsuri
Nu vom adresa decât întrebări cărora le dăm şi răspunsurile. Nu vom cere să se scrie un
cod în ASP aşa cum am făcut-o de altfel şi la tehnologia JSP. Motivaţia o cunoaşteţi: am
dorit ca să vă faceţi o idee asupra efortului pe care un programator angajat la firma
dumneavoastră ar primi sarcina dificilă de realizare a unui sit comercial.
Întrucât au fost destule întrebări adresate pe parcursul expunerii acestei tehnologii, ne
rezumăm aici la un şir restrâns de întrebări. Aşadar:

Întrebări
Observaţie: Numerotarea lor a început din cadrul acestor capitole dedicate prezentării
tehnologiei ASP.
49. Ce realizează comanda SQL de mai jos:
SELECT nume_autor FROM Autori WHERE nume_autor = ‘Eminescu’

50. Dar ce realizează comanda SQL de mai jos:


SELECT nume_autor FROM Autori WHERE nume_autor LIKE ‘%escu’

51. Ce realizăm cu comanda următoare:


INSERT clienti (nume_client, adresa_client) VALUES (’Ionescu’, ’Bucuresti, str.
Cuza Voda nr 123’)

52. Ce urmărim să facem în cazul de mai jos


UPDATE Parole SET nume_client = ’Popescu’, parola = ’gigi_cel_jedy’ WHERE
nume_client = ’ Ionescu’

53. Ce este greşit în comanda de mai jos:


INSERT clienti (nume_client, adresa_client) VALUES (’Scott’s Company’,
’Bucuresti, str. Cuza Voda nr 123’)

54. Comanda şterge întreaga tabelă Parole sau nu?


DELETE Parole WHERE parola = ’top_secret’

55. La urma urmei ce este un obiect RecordSet?


56. Explicaţi ce se realizează în secvenţa de mai jos:
Myfile = “page0.asp”
IF Myfile = “page0.asp” THEN
%>
<!-- #INCLUDE FILE = “index.asp” - - >
<%
END IF
%>
IF Myfile = “page1.asp” THEN
%>
<!-- #INCLUDE FILE = “otherpage.asp” - - >
<%
END IF
%>

Răspunsuri doar la aceste întrebări


49. Selecţia înregistrărilor din tabelul Autori după autorul Eminescu.
50. O selecţie a tuturor înregistrărilor cu nume de autori care se termină cu escu.
51. Inserăm o înregistrare în tabelul clienti cu valorile care se văd.
52. Să modificăm în tabelul Parole două coloane ale sale, nume clientului şi parola
sa, doar acolo unde numele clientului este Popescu.
53. Trebuie aşa scris:
INSERT clienti (nume_client, adresa_client) VALUES (’Scott’’s Company’, ’Bucuresti,
str. Cuza Voda nr 123’)

54. Nu, numai înregistrările a căror parolă este top_secret.


55. Un tabel cu rânduri.
56. Dacă variabila myfile conţine literalul page0.asp, se încarcă dinamic pagina
page1.asp. În caz contrar, se alege otherpage.asp pentru alipirea dinamică la
pagina din care se face apelul cu secvenţa de mai sus.
<%
Libelle = “Zisei eu “”Ura!”””
%>
<form method=”post” action=”pagina.asp”>
<input name=”ce” type=”text” value=<%=Libelle%>
<input type=”submit” value=”Trimite”>
</form>

Corect este aşa:


Libelle = Server.HTMLEncode(“Zisei eu “”Ura!”””)

Introduction1
Le e-commerce
Le progrès technique dans le domaine des circuits intégrés à permis de décliner
les dimensions de l’ordinateur. Les mainframes étaient prioritairement destinés
aux centres de calcul territoriaux qui traitaient les données pour plusieurs unités
économiques, les mini-ordinateurs étaient utilisés comme ordinateurs
d’entreprise et les micro-ordinateurs traitaient les données d’un service ou
bureau. Ont suivi les ordinateurs de bureau (desktop). L’adoption large des
ordinateurs personnels grâce aux programmes de bureautique (traitement de
texte, tableur,…) a mené à une certaine démocratisation de l’informatique. Les
simplifications apportées aux ordinateurs personnels et à leurs systèmes
d’opération, nécessaires pour assurer les moindres coûts, leur ont apporté un
handicap par rapport à la protection des données, la capacité de travailler
simultanément avec plusieurs utilisateurs (multi-user) ou d’exécuter plusieurs
processus en même temps (multi-tasking).

La montée en puissance de l’informatique


La montée en puissance des ordinateurs personnels a permis l’adoption au début
des années 1990 du système Unix par les ordinateurs PC, sous le nom déjà
célèbre de Linux. Ceci a mené à la confrontation de deux cultures et philosophies
informatiques différentes. L’une qui vient d’un monde de l’informatique
professionnelle, attentive à la sécurité de l’information, aux capacités de
communication et favorable aux systèmes ouverts, représentée par Linux ; l’autre
qui vient du monde de l’informatique utilisateur, commerciale avec des tendances
monopolisatrices représentée par Windows. Indifféremment de la manière dont
va se solder la confrontation des systèmes Linux et Windows, ce qui est à retenir
de cette évolution, c’est que la notion de terminal non-intelligent a disparu et avec
elle aussi la notion d’informatique centralisée. Parallèlement se sont beaucoup
développées les technologies de réseau d’ordinateurs et l’informatique distribuée.
Le modèle d’ordinateur central supposait la concentration des calculs et
traitements de données dans l’ordinateur central qui devait servir de multiples
terminaux passifs, qui ne faisaient rien d’autre que de faciliter l’affichage et la
saisie de données. Avec le remplacement des terminaux par des ordinateurs de
bureau qui disposent d’intelligence et de capacités de calcul de plus en plus
importantes, on arrive naturellement à une démocratisation du traitement des
données dans le réseau. Le rôle d’ordinateur central disparaît et apparaissent un

1
Introducerea la “Cours de commerce éléctronique” predat de domnul prof. Dr. Mihai Calciu,
la Universitatea I Lille. Sunt prezentate doar o parte din capitole. Restul şi actualizări se pot
vedea la http://mihai.calciu.free.fr.
ou plusieurs ordinateurs qui jouent le rôle de serveurs. En parallèle, le rôle du
terminal disparaît et apparaît celui de l’ordinateur client.
Aujourd’hui, le multimédia utilise l’ordinateur pour intégrer et assurer un accès
interactif pour du contenu statique (textes, images et graphiques) et dynamique
(audio, vidéo et animations). L’hypermédia combine l’accès nœud et liens de
l’hypertexte avec du contenu multimédia. Le World Wide Web est un cadre de
communication hypermédia basé sur l’ordinateur et le réseau Internet, qui permet
aux consommateurs et aux firmes de fournir du contenu hypermédia et d’y
accéder de manière interactive.

Le e-commerce
Le commerce électronique ou e-commerce est défini comme étant la vente et
l’achat à travers les médias digitaux. Les possibilités visuelles et multimédia et le
caractère intuitif de la navigation de type nœud et lien ont d’abord révélé
l’Internet comme un nouveau canal de distribution pour la vente en détail. Les
premières applications étaient de type boutique électronique ou magasin on-line.
Elles utilisaient les pages web écrites en langage html pour la présentation de
l’information et des langages de programmation disponibles sur les serveurs.
Le site web où l’on peut acheter des biens et des services, n’est qu’une forme de
commerce électronique. Elle représente une faible partie du chiffre d’affaires du
secteur. Plus récemment, le commerce électronique est passé à une vitesse
supérieure. A coté des boutiques électroniques on-line apparaissent de nouvelles
formes d’intermédiation commerciale appelées places de marché, qui réunissent
de l’information en provenance de multiples offreurs sur Internet. Se développent
aussi les formes dynamiques de commerce comme les enchères, le regroupement
ad-hoc des acheteurs, le troc électronique et les marchés boursiers.
Pour pouvoir supporter ces nouvelles formes de commerce et le commerce entre
entreprises, il est nécessaire d’automatiser de nombreux échanges d’information.
Cela suppose le transfert d’information structurée d’un ordinateur à un autre pour
des traitements automatiques. Historiquement, la première forme de commerce
électronique a été le magasin on-line ou le shopping cart. Les vendeurs
communiquaient directement avec les consommateurs par l’intermédiaire de
leurs sites web en utilisant les méthodes de marketing traditionnelles. C’est la
forme la plus adaptée à la communication homme-machine. Cette démarche s’est
avérée coûteuse, spécialement pour les détaillants. Le nombre grandissant des
sites de vente en ligne et de leurs messages publicitaires inondait les acheteurs et
rendait difficile le choix des fournisseurs.
Avec la difficulté grandissante des vendeurs et acheteurs de se retrouver de
manière intuitive et efficace, est apparu le besoin de créer des places de marché
on-line. Les places de marché sont des intermédiaires dignes de confiance qui ont
comme première mission d’agir en qualité de lieu central de collecte aidant les
acheteurs et les vendeurs à se retrouver et à faire du commerce de manière
efficace.
La place de marché se substitue au besoin de l’acheteur d’effectuer une seule
transaction avec une seule entité et prend en charge la facturation du client,
l’intermédiation des services post-achat, la gestion de retours et d’autres
situations. En d’autres termes, la place de marché devient un marchand de
références qui remplace les différents vendeurs. Dans ces conditions, pour assurer
la fluidité dans la collecte et la présentation de l’offre et dans le déroulement des
transactions, une forte automatisation des transferts d’information structurée
(documents, formulaires) est nécessaire par la communication de machine à
machine, pour faciliter le « commerce silencieux ». Conçus pour servir aussi bien
le commerce de détail (b-to-c, business to consumer) que celui de gros (b-to-b,
business to business), les lieux de marché connaissent une meilleure diffusion et
atteignent des degrés d’efficience et de réduction des coûts, supérieurs dans le
b-to-b.
La typologie des lieux de marché qu’on observe actuellement permet de
distinguer au moins trois catégories : les méga, micro et méta lieux de marché.
Les méga places de marché ont un caractère horizontal. Elles couvrent un très
large spectre de catégories de produits et proposent des gammes de produits
plutôt larges que profondes. Elles cherchent à satisfaire un large spectre de
besoins pour un grand nombre de consommateurs. Les catégories de produits
sont multiples. Dans chaque catégorie, l’offre de produits est multiple et provient
d’une multitude de producteurs. Les micro places de marché sont verticales par
défaut. Elles apportent l’offre la plus grande de produits dans la même catégorie.
Elles se distinguent par la profondeur de la gamme de produits. Les méta lieux de
marché n’ont pas de correspondant off-line. Ils cherchent à offrir des solutions à
des problèmes à la place de catalogues de produits.
Même s’ils sont capables à long terme de réduire les chaînes traditionnelles de
distribution en éliminant des intermédiaires, ils se développeront à court terme à
l’intersection des canaux de distribution traditionnels.

Le e-business
Naturellement, les possibilités visuelles et multimédia ont d’abord révélé
l’Internet comme un nouveau canal de distribution pour la vente en détail. On
s’est vite aperçu que les implications étaient beaucoup plus larges et que le e-
commerce affectait encore plus profondément les échanges entre entreprise (le b-
to-b). En développant leurs interfaces d’échange, les entreprises doivent adapter
leurs structures et processus internes, leur back-office, pour faire face aux
exigences de flexibilité, synchronisation et réactivité induites par les nouveaux
mécanismes d’échange. Ce qui les amène à une refonte de leurs systèmes
d’information dans des systèmes de e-business.
Le e-business se définit comme l’intégration des applications de front et back-
office dans un moteur qui permet de redéfinir les modèles d’affaires et de
maximiser la valeur pour le client. Les systèmes d’information des entreprises ont
subi à l’ombre de l’Internet une révolution silencieuse. On renonce maintenant
aux applications traditionnelles, construites pour résoudre des problèmes
spécifiques à l’entreprise, souvent avec des ressources maison. Les systèmes
modernes sont actuellement constitués autour d’un nombre réduit de
composantes nommées applications d’entreprise, le plus souvent commerciales.
Les entreprises ressentent de plus en plus la pression de la diffusion des
possibilités de commande en libre-service, du coût excessif des conseils
techniques avant la vente, un coût croissant des erreurs de commande, des
problèmes de coordination engendrés par la prolifération des canaux de vente et
la complexité croissante des produits. Elles cherchent à augmenter l’efficacité de
la force de vente, coordonner les ventes en équipe, faciliter la tâche du client, lui
permettre de configurer ou personnaliser l’offre.
Les applications de marketing direct permettent, à partir des adresses de mener
des campagnes de diffusion de messages promotionnels envers des clients ou
prospects. L’automatisation du management des campagnes et des processus de
marketing direct facilite la gestion et le déploiement de tels programmes, en
automatisant la gestion des réponses, la segmentation de la clientèle et assure des
aspects logistiques des évènements.
La planification de ressources de l’entreprise ou ERP (enterprise resource
planning) se trouve au cœur de l’entreprise, derrière la vente et la gestion de la
relation client et devant l’achat et les relations avec les fournisseurs. L’ERP n’est
pas un seul système mais un cadre qui contient des applications administratives
(finance, comptabilité), de gestion des ressources humaines (salaires, primes),
planification des ressources de fabrication (MRP ou manufacturing resource
planning). L’ERP est le système d’opération interne de l’entreprise, c’est la
colonne vertébrale du e-business. Les entreprises qui l’ont adopté ont vu leurs
stocks et leurs coûts se réduire et ont constaté une amélioration générale de leur
fonctionnement. Le e-commerce favorise la diffusion de l’ERP.
L’intégration des applications d’entreprise ou l’EAI (enterprise applications
integration), permet de faire communiquer tout type d’applications, que ce soit
des développements « maison » ou des progiciels intégrés. L’EAI n’occupe pas
une position particulière dans le flux de transformation : achat, production, vente.
Dans l’industrie de l'automobile, de grands acteurs comme Ford, General Motors
et plus récemment Renault, mettent en commun leurs fournisseurs sur une place
de marché (e-marketplace). Ces industriels, qui il y a quelques années
construisaient encore eux-mêmes la majeure partie de leurs véhicules, vont
pouvoir se recentrer sur le marketing, la gestion du client ou la distribution, et
proposer ainsi des véhicules mieux adaptés aux besoins des usagers.
Déroulé dans un nouveau cadre concurrentiel caractérisé par la dérégulation et la
globalisation, le processus d’intégration inter et intra-entreprises, déterminé par
l’adoption des NTIC, modifie de manière substantielle les systèmes
d’organisation et d’échange des entreprises. On assiste progressivement au
passage de systèmes d’organisation hiérarchiques, de commande vers des
systèmes collaboratifs, de type réseau. Les échanges inter et intra entreprises sont
de moins en moins transactionnels et de plus en plus relationnels. Même s’il
s’agit d’évolutions technologiques normales, on peut considérer l’Internet comme
un phénomène éclair qui a imprégné ces changements d’un esprit ouvert et
humain.
Par le recours aux nouvelles technologies en général, et à Internet en particulier,
l’entreprise grâce à une information mieux maîtrisée et plus rapidement transmise
à ses employés pour leur permettre de prendre plus vite les décisions les plus
efficaces, peut réussir à augmenter son chiffre d’affaires et en même temps à
diminuer ses coûts.
1
Chaptre

Le commerce électronique et ses


technologies

L ’objectif du cours est d’introduire aux technologies Internet adaptés à la


mise en place de solutions de commerce électronique. Le premier chapitre
propose une introduction au commerce électronique et à la
programmation de pages serveur ASP, PHP et JSP. Seront présentées les formes du
commerce électronique et des technologies disponibles pour la création de sites Web
commerciaux1.
Les trois chapitres suivants (2, 3 et 4) sont un cours accéléré d'ASP, PHP et JSP dans le
contexte du commerce électronique. On étudie la création de scripts dans les pages
serveur (ASP, PHP ou JSP) permettant d'enregistrer des informations provenant des
clients. On montre également comment effectuer un suivi de ces informations à l'aide de
cookies et de variables de session. Enfin, on montre comment manipuler des fichiers à
partir de pages serveur (ASP, PHP ou ASP) La mise en place proprement dite du
magasin en ligne commencera au Chapitre 5, avec la création de pages permettant de
gérer un catalogue de produits. La création des pages des produits d’un magasin en ligne
sera abordée dans le Chapitre 6. Et dans le Chapitre 7 comment permettre au clients
d'effectuer des recherches dans le catalogue de produits. Dans les chapitres 9 et 10 on
construira un panier de courses virtuel (caddie électronique) en faisant appel à des
variables de session et à des tables d’une base de données. Des mises à jours des cours
ainsi que d’autres supports et application seront disponibles en ligne à l’adresse
http://mihai.calciu.free.fr .
Une application Web est un site Web qui contient des pages stockées sur un serveur
Web et dont le contenu est partiellement ou totalement indéterminé. Le contenu final
d'une page est déterminé uniquement lorsque l'utilisateur requiert une page depuis le

1
Ce support de cours utilise et adapte le texte de S. Walther et J. Levine "E-Commerce,
programmation avec ASP3" (Campus Press, Paris, 2000) à d’autres technologies (PHP et JSP) qui
sont ouvertes et permettent aux étudiants de mettre en ligne des applications de e-commerce
gratuitement.
serveur Web. Le contenu final d'une page variant d'une requête à une autre en fonction
des actions de l'utilisateur, ce type de page est appelée page dynamique. Les applications
Web sont construites de manière à répondre à différents types de défis et de problèmes.
Cette section décrit les utilisations courantes des applications Web et donne un exemple
simple.
Tout système interactif doit être capable de réagir (répondre) aux inputs (entrée ou
requêtes) qui lui sont adressées. Les systèmes de commerce électronique n’échappent
pas à cette exigence. Il est essentiel que le système soit capable de recevoir des requêtes
de la part du client et qu’il soit capable d’afficher des réponses adaptées. Le service web
(le protocol http) intègre les fonctionnalités fondamentales d’une telle interaction que la
technologie des pages serveur utilise et développe de manière substantielle. Dans la
majorité des solutions (notamment dans ASP) ces fonctionnalités sont encapsulées dans
des objets spécialisés pour la Réponse et la Requête. Dans ce chapitre on traitera les
sujets suivants2: Utilisation de l'objet Response (Réponse) pour envoyer du contenu au
serveur Web. Utilisation de l'objet Request (Requête) pour traiter les chaînes de requête
HTML. Utilisation de l'objet Request pour extraire les informations saisies par les
utilisateurs dans des formulaires HTML. Utilisation de l'objet Request pour obtenir les
en-te tes de navigateurs et les variables de serveur. Nous sommes maintenant prêts à
commencer la mise en place d'un site de commerce électronique faisant appel à des
pages ASP, PHP ou JSP. Ce chapitre vous présentera les deux objets ASP les lus
importants Response et Request. Ces objets vous permettront d'interagir avec les clients
visitant votre site.

Introduction au commerce électronique


Dynamique du commerce éléctronique

L a croissance exponentielle du Web fait la une de tous les médias. Il n'est pas
difficile de comprendre pourquoi. Le taux d’adoption du commerce
électronique ne cesse de croître.
A l'heure actuelle, le commerce électronique génère déjà un chiffre d'affaires
global plus important que celui de l'aéronautique ou des télécommunications.
eBay, une entreprise fondée il y a moins de cinq ans par quelqu'un qui voulait
simplement trouver Un moyen plus efficace de vendre la collection de distributeurs
de bonbons de sa femme, vient de racheter Butterfield & Butterfield, une maison
de vente aux enchères vieille de 135 ans. Amazon, une entreprise qui n'a, elle aussi,
que cinq ans, vend cinq fois plus de livres en ligne que la plus grande chaîne
traditionnelle de librairies des Etats-Unis, Barnes and Noble.

2
Ce support de cours utilise et adapte le texte de S. Walther et J. Levine "E-Commerce,
programmation avec ASP3" (Campus Press, Paris, 2000) à d’autres technologies (PHP et JSP) qui
sont ouvertes et permettent aux étudiants de mettre en ligne des applications de e-commerce
gratuitement.
Evolution des technologies
Il n'y a pas si longtemps, la création de sites Web, en particulier les sites de
commerce électronique, était réservée à des programmeurs diplômés et
expérimentes. Pour mettre en ligne un magasin électronique, il était nécessaire de
maîtriser la syntaxe complexe de langages tels que le Perl, voire de langages de
programmation de bas niveau tels que le C++.
Heureusement, ont été développées des technologies permettant de créer
rapidement des sites Web commerciaux : l'ASP (Active Server Pages) de
Microsoft, le PHP (Persnal Home Pages)s, CFS (ColdFusion) de Allaire et JSP
(Java Server Pages) de Sun.
Toutes ses solutions supportent des sites de commerce électronique de grande
envergure. Par exemple Dell.fr ou de Fnac.com (deux sites qui ont recours à des
pages ASP).
Dans ce chapitre
Le présent chapitre est une introduction aux deux sujets de ce cours: le commerce
électronique et les pages serveur. Nous traiterons les questions suivantes:
• Quelles sont les formes du commerce électronique?
• Quelles technologies sont disponibles pour le commerce électronique?
• Que sont les pages ASP, PHP ou JSP?

Formes de commerce éIectronique


B2B, B2C et C2C
Le commerce électronique est l'achat ou la vente de produits ou de services via un
réseau électronique ; a l'heure actuelle, le support le plus courant pour ce type de
transaction est Internet.
Il y à trois sortes de transactions électroniques. Premièrement, elles peuvent avoir
lieu entre une entreprise et un client (on appelle ce type de commerce électronique
B2C pour business to consumer) ; c'est ce genre de transaction qui vient en premier
a l’esprit lorsqu'on pense au commerce électronique. Amazon est par exemple une
entreprise "B2C". Amazon permet aux particuliers de trouver et d'acheter tout ce
qui les intéresse en matière de livres, de CD, d'électronique et de vidéo. Le "B2C"
peut s'appliquer a des services aussi bien qu'a des produits.
Deuxième type de commerce électronique : celui qui implique des transactions
entre deux entreprises (on dit aussi B2B pour business to business). Ce type de
commerce électronique est moins médiatise. Cisco Systems, qui crée une grande
partie de l'infrastructure physique d'Internet permettant aux entreprises de
communiquer est une entreprise "B2B".
Enfin, une forme de commerce électronique qui a connu un succès important ces
dernières années est celle qui implique un rapport direct entre consommateurs
finaux (ou C2C, pour consumer to consumer). Les exemples les plus connus de ce
type d'entreprise sont eBay aux Etats-Unis ou iBazar en France. eBay et iBazar
permettent a leurs clients de vendre des objets par des enchères publiques et
prélèvent une commission pour chaque objet vendu.
Info
Aux origines du commerce électronique, il y a l'EDI ou Electronic Data Interchange.
L’EDI est une méthode structurée de transmission des informations d'un ordinateur a
l'autre. Il a été développé pour permettre aux entreprises d'échanger électroniquement
des documents tels que des factures ou des commandes. L’EDI peut également servir à
transmettre d'autres types d’informations il est, par exemple, utilisé aux Etats-Unis pour
transférer des dossiers d'étudiants ou de patients entre différents organismes.
Avec la diffusion du web sémantique et le passage du HTML au XML les solutions EDI
propriétaires et chères pour les PMEs sont remplacés progressivement par des solutions
ouvertes fonctionnant sur Internet.
Plus que du payement éléctronique
On considère souvent que l'élément essentiel du commerce électronique est la
sélection d'un produit par le client suivie de son achat au moyen d'une carte
bancaire. Autrement dit, les cartes bancaires seraient la composante essentielle du
commerce électronique. Ce n'est pas toujours vrai. Supposons par exemple que
vous étés le propriétaire d'une (vraie) boutique vendant d’électroménager. Il peut
être intéressant pour vous de mettre en place un site Web faisant office de
catalogue pour tous les produits que vous vendez, même si vous n'offrez aucun
moyen a vos visiteurs d'acheter vos produits en ligne. L'intérêt de votre site Web
sera simplement d'inciter les clients potentiels à se rendre dans votre boutique. Il
s'agit la d'une forme tout a fait envisageable de commerce électronique.
Info
Pour plus d'informations générales sur le commerce électronique, vous pouvez vous
rendre sur le site du ministère français de l'économie
(voir http://www.finances.gouv.fr/electrophees/index.htm) ou, pour des informations
plus complètes, mais en anglais, celui du gouvernement des Etats-Unis, a l'adresse
http://www.ecommerce.gov.

Solutions propriétaires: exemple les produits


Microsoft pour le commerce électronique
Presentation des solutions Microsoft
Pour tester ces solutions on part du principe que vous utilisez à la fois un serveur
Web Microsoft et un logiciel de base de données Microsoft.
Microsoft propose deux serveurs Web le "serveur Web personnel", Personal Web
Server ou PWS, et Internet Information Server, ou IIS.
Vous devrez également avoir accès à une base de données, Microsoft Access ou
Microsoft SQL Server au choix. Les pages qui suivent résument brièvement les
différences qui existent entre ces logiciels elles indiquent en outre quels autres
outils Microsoft peuvent être employées pour créer des sites Web commerciaux.
Personal Web Server
Le logiciel Personal Web Server (PWS) peut etre employé de deux manières
différentes. IT peut servir à héberger un site à très faible trafic (pour partager des
documents sur l’intranet d'une entreprise, par exemple). Il peut également servir A
tester un site avant d'en transférer le contenu sur Internet Information Server
Il est fortement déconseille d'utiliser PWS pour héberger un "vrais site Web
Internet. PWS ne permet de gérer qu'un nombre limite de connexions simultanées.
Internet Information Server
Contrairement à PWS, IIS peut prendre en charge des centaines, voire des milliers
de connexions simultanées. Microsoft fait appel à IIS pour son propre site
(http://www.microsoft.com) qui est le quatrième le plus visite de tout le Web, avec
environ cinq millions de visiteurs par jour.
IIS ne peut être utilisé que sous Windows NT Server ou Windows 2000 et plus. Il
est inclus avec ces deux systèmes d'exploitation.
Info
Si vous avez des projets de site Web très ambitieux, utilisez IIS avec Windows 2000
Advanced Server. Windows 2000 Advanced Server autorise le clustering de serveurs, ce
qui permet de repartir un site Web sur plusieurs machines.
Access
Pour créer un site Web commercial) vous aurez besoin d'une base de données
permettant de stocker les informations relatives aux produits et aux commandes.
Microsoft Access est une base de données bureautique et non une base de données
client serveur telle que SQL Server (voir ci-dessous). De ce fait, vous ne devez
utiliser Access que pour tester votre site Web ou pour créer un site A faible trafic.
En principe, une base de données Access ne peut prendre en charge qu'un
maximum de 30 connexions simultanées.
Une fois que vous avez crée votre site Web à l'aide d'Access, vous pouvez le
transformer en base de données SQL Server à l'aide d’outils de migration intégrès à
Access 2000.
SQL Server
Microsoft SQL Server peut prendre en charge des milliers de connexions
simultanées et des bases de données d'une taille de plusieurs teraoctets. En
pratique, les possibilités de SQL sont largement suffisantes, quelle que soit la taille
du magasin que vous projetez de mettre en ligne. Une grande partie des sites de
commerce électronique les plus importants du Web font d'ailleurs appel à SQL
Server.
Visual lnterDev
Microsoft Visual InterDev est un environnement de développement pour la
création de sites Web. A la base, il s'agit d'un Editeur de texte très perfectionné
permettant de créer et de modifier des pages Web sur un serveur local ou distant.
Visual InterDev peut être employé pour créer des pages ASP ou des pages HTML
"normales".
Visual Interdev est fortement intégré à SQL Server. Visual InterDev peut servir à
créer et a modifier des tables de bases de données et des procédures. Il peut être
employé avec n'importe quelle base de données ODBC ou OLE DB.
Vous n'avez pas besoin de Visual InterDev pour créer des pages ASP. N’importe
quel éditeur de texte standard peut faire l'affaire, par exemple le Bloc-notes ou le
Wordpad, qui sont fournis avec toutes les versions de Windows. Cependant, Visual
lnterDev facilite la gestion des pages dans le cas d'un site important et est fourni
avec plusieurs outils de débogage.
Info
Il y a d’autres produits Microsoft pour la création de pages Web comme Word ou
FrontPage. Nous ne conseillons pas l'emploi de Word et de FrontPage pour la création
de sites Web comprenant des pages ASP. Ils ont tendance à modifier le code source
d'une page sans prévenir. Autrement dit, il sont susceptible de faire disparaître ou de
rendre inutilisable un script ASP que vous avez passé des heures a écrire.

Autres solutions: la formule EasyPHP, les solutions


JAVA et Dreamweaver
Presentation
Il y à d’autres solutions moins onéreuses et contraignantes qui sont équivalentes à
ASP. Ici on a retenu celles qui tournent autour des pages serveur PHP et JSP.
Pour tester ces solutions il faut disposer d’un serveur Web et un logiciel de base de
données. Il serait bien que les services offerts par ces logiciels soit disponibles chez
les hébergeurs de sites web.
Le serveur de pages web Apache
Le serveur web qui domine l’Internet est Apache. Approximativement 60% des
sites web publiés utilisent ce serveur de pages web. Il est inclus dans la formule
EasyPHP qui est disponible gratuitement sur Internet. Grâce à sa rapidité et à sa
solidité, le serveur web Apache est adopté par beaucoup de fournisseurs d’accès
Internet (ISP) comme free.fr.
Le serveur de bases de données MySQL
Toutes les applications de commerce electronique reposent sur des serveurs de
bases de données. MySQL est un serveur de bases de données réputé être un des
plus rapides dans le monde. Grâce à cette rapidité et à sa solidité il à été adopté
entre autres par la NASA. Il est aussi inclus dans le package EasyPHP avec un
programme très puissant (intitulé phpMyAdmin.php) qui permet de gérer les bases
de données en ligne. L’accés à une base de données MySQL et le service PHP de
gestion de la base de donnée en ligne est aussi mis à disposition gratuitement.
L’éditeur de sites web Dreamweaver
Dreamweaver (version MX6) de Macromédia est peut-être actuellement le
meilleur éditeur de sites web. A part la création de pages web statiques qui
intègrent les évolutions dans la technologie client comme le HTML dynamique (les
calques et le feuilles de style en cascade CSS), le XHTML, le XML, Dreamweaver
dans ses dernières versions couvre aussi la création d’applications web, laissant le
choix entre les technologies de pages serveur ColdFusion, ASP.NET, ASP, JSP et
PHP. Cette évolution de l’édition de pages web vers l’édition d’applications web
exprime la tendance sur le marché et a été possible pour Macromedia grâce à la
fusion avec la société Allaire, un expert des solutions coté serveur et propriétaire de
la formule ColdFusion.
Dreamweaver est un logiciel commercial. Des versions d’essaye qui possèdent
toutes les fonctionalités de la version définitive et valables pendant plusieurs
semaines peuvent être téléchargées du site web de Macromedia.
En absence du logiciel Dreamweaver, n’importe quel éditeur de texte standard peut
faire l'affaire, par exemple le Bloc-notes ou le Wordpad, qui sont fournis avec
toutes les versions de Windows. Microsoft Word est aussi un très bon éditeur de
pages web statiques, il ne doit pas être utilsé pour créer des pages serveur pour les
mêmes raisons que celle évoquées dans le cas de l’éditeur de pages web Frontpage.

Que sont les pages serveur


Pages statiques et pages dinamiques
Les chapitres qui suivent sont consacrés à la création de sites Web commerciaux a
l'aide de pages serveur.
Une page serveur est un fichier situé sur votre serveur Web et contenant l'extension
.asp, .php ou .jsp. Ces extensions permettent de distinguer les pages serveur d'un
fichier HTML "normal", dont l'extension est .htm ou .html.
Lorsqu'un internaute se rend sur un site Web et demande un fichier HTML normal,
le serveur Web va simplement chercher ce fichier sur le disque dur ou dans la
mémoire (cache) de l'ordinateur et l'envoie au navigateur de l'utilisateur. Le
navigateur interprète le contenu HTML du fichier et l'affiche.
Lorsqu'une requête porte sur une page HTML normale, le serveur Web ne prend
pas en compte le contenu du fichier il se contente d'envoyer le fichier sans le traiter
en aucune façon ; c'est le navigateur de l'utilisateur qui se charge ensuite
d'interpréter le contenu du fichier HTML.

Les pages serveur


Lorsqu'une requête porte sur une page serveur en revanche, le serveur Web a un
rôle plus actif (et se fait parfois aidé par un serveur d’applications). Avant que le
fichier ne soit envoyé au navigateur de l'utilisateur, il est d'abord traité par le
serveur Web (ou le serveur d’applications). Le serveur interprète et exécute tous les
scripts en ASP, PHP ou JSP d'une page avant de l'envoyer au navigateur de
l'utilisateur.
Ainsi, le Listing 1.1 est une page serveur très simple qui affiche l'heure courante.
LISTING 1.1: Affichage de l'heure courante par des pages serveur
(.asp, .php ou .jsp)
HEURE.ASP HEURE.PHP HEURE.JSP
01. <HTML> 01. <HTML> 00. <%@ page
02. <HEAD><TITLE>Heure 02. <HEAD><TITLE>Heure import="java.util.*"%>
courante<ITITLE></HE courante<ITITLE></HEAD 01. <HTML>
AD> > 02. <HEAD><TITLE>Heure
03. <BODY> 03. <BODY> courante<ITITLE></HEAD>
04. Void 1'heure courante: 04. Void 1'heure courante: <? 03. <BODY>
<%= TIME() %> print (Date("h:i :s A")); ?> 04. Void 1'heure courante: <%
05. </BODY> 05. </BODY> Calendar now =
06. </HTML> 06. </HTML> Calendar.getInstance(); %>
<%=
now.get(Calendar.HOUR_O
F_DAY)
+":"+now.get(Calendar.MIN
UTE) %>
05. </BODY>
06. </HTML>
Lorsqu'un internaute demande le fichier heure.xxx, le serveur constate qu'il
s'agit d'une page serveur du fait de son extension (.asp, .php ou .jsp). Ainsi,
avant d'envoyer le fichier au navigateur de l'utilisateur, il effectuera un
traitement des scripts contenus dans le fichier.
ASP Analyse
Le texte <%=TIME( )%> de la ligne 04 du fichier heure.asp sera remplacé
par l’heure courante. L’heure est produite dynamiquement par l’ordinateur
serveur suite à l’interprétation du script.
PHP Analyse
Le texte <? print (Date("h:i:s A")); ?> de ligne 04 du fichier heure.php sera
remplacé par l’heure courante. La fonction PHP date() retourne une date sous
forme d'une chaîne, au format donné par la chaîne format
JSP Analyse
Dans heure.jsp le scriptlet <% Calendar now = Calendar.getInstance(); %> crée
un objet de type Calendar nommé now comme nouvelle instance du composant
Calendar (Calendrier). Ensuite dans l’expression <%= now.get
(Calendar.HOUR_OF_DAY ) + ":" + now.get( Calendar.MINUTE ) %> sont
affichés les valeurs des propriétés heure et minute de l’objet crée.
Les pages serveur produisent du pur html
Le Listing 1.2 montre le fichier qui sera effectivement envoyé au navigateur
Web. Notez qu'il s'agit d'un fichier HTML normal. Tous les scripts sont
traités par le serveur avant que le fichier ne soit envoyé à l'utilisateur. Les
pages serveur étant traitées au niveau du serveur et non au navigateur, elles
sont compatibles avec tous les navigateurs Web.
LISTING 1.2 : Le fichier heure.xxx après traitement (xxx représente asp, php ou
jsp)
01. <HTML>
02. <HEAD><TITLE>Heure courante<ITITLE></HEAD>
03. <BODY>
04. Voir 1'heure courante : 4.55.36 AM
05. </BODY>
06. </HTML>

Scripts des pages serveur


Avantages des scripts
Les pages serveur contiennent des scripts serveur. ASP utilise Microsoft Visual
Basic Scripting Edition (VBScript) comme langage de script. Cependant une page
ASP peut contenir des scripts écrits dans d'autres langages, par exemple en Jscript
(la version Microsoft du JavaScript) ou en PerlScript. PHP utilise des scripts en
langage PHP et JSP utilise le Java.
Les langages de script tels que le VBScript se distinguent des langages de
programmation complets tels que le Visual Basic ou le Java par une syntaxe et des
règles simplifiées. Ainsi, en VBScript, il n'est pas nécessaire de déclarer un type de
données particulier pour les variables.
De plus contrairement au Visual Basic ou au Java, une page ASP n'a pas besoin
d'être compilée pour être exécutée. Si vous modifiez une page ASP, celle-ci est
automatiquement recompilée lors de la prochaine requête.
L'avantage de l'utilisation d'un langage de script lors de la création de pages Web
est que le site Web reste ainsi facilement modifiable, même après sa mise en ligne.
Si vous découvrez un bogue sur votre site Web, il suffit d'ouvrir dans le Bloc-notes
la page ou se trouve le problème et de le corriger.
Richesse des langages complets
Le fait que les pages ASP utilisent un langage de script ne signifie pas qu'elles
soient lentes ou que leur portée soit limitée. Les scripts ASP sont exécutés dans le
même process que le serveur Web et font appel au multithreading. De ce fait, une
page ASP peut prendre en compte un grand nombre de connexions simultanées.
JSP arrive au même fins que ASP en passant par une solution plus élégante et
astucieuse qui permet de profiter de toute la puissance d’un langage de
programmation complet comme le Java.

Objets et composants des pages serveur


Interêt des objets et composants
Les possibilités des pages serveur seraient très limitées si elles ne pouvaient
contenir que des scripts. Elles pourraient afficher l'heure courante et toutes sortes
de messages, mais elles ne fourniraient aucun moyen d'obtenir des informations
venant de l'utilisateur, de stocker des données dans une base de données ou de créer
des fichiers sur le serveur. Heureusement, une page ASP peut contenir des
composants serveur.
En général, les composants disposent de méthodes, de propriétés et de collections.
Les méthodes d'un composant déterminent quelles actions il est possible d'effectuer
avec ce composant. Les propriétés d'un composant peuvent être lues ou modifiées
pour définir l'état du composant. Enfin, les collections d'un composant sont des
ensembles de clés et de paires de valeurs associées au composant.
Supposons que un livre soit un composant. Ce composant disposera de méthodes
déterminant ce qu'il est possible de faire avec lui le lire, l'utiliser pour caler une
table ou le déchirer. Il présentera des propriétés poids ou nombre de pages, par
exemple. Enfin, il disposera d'une collection de clés et de paires de valeurs :
chaque numéro de page (les clés) y est associe à une page de texte (les valeurs).
Exemples d’objets et composants
Les pages ASP comprennent deux types de composants les composants intégrés et
les composants supplémentaires.
Les six composants intégrés des pages ASP sont les suivants:
1. Objet Application représente les informations pouvant être partagées entre
tous les utilisateurs d'une application ASP.
2. Objet ObjectContext : est utilise' avec les pages ASP transactionnelles.
3. Objet Request : représente toutes les informations envoyées au serveur par
le navigateur, y compris les variables de formulaire et les chaînes de
requête.
4. Objet Response : représente toutes les informations envoyées au navigateur
par le serveur, y compris le contenu HTML envoyé par la page ASP.
5. Objet Server permet de faire appel a différentes fonctions du serveur.
6. Objet Session : représente les informations concernant une session
utilisateur donnée.
Info
La nouvelle version d’ASP faisant partie de Windows 2000 comprend un objet integré
supplémentaire, ASPError. Cet objet représente les informations concernant les erreurs
ayant eu lieu sur une page ASP.

Illustration
Le Listing 1.3 montre par exemple comment utiliser les fonctionnalités des pages
serveur (en ASP l’objet Response) pour afficher le texte "Bonjour !" dans le
navigateur.
LISTING 1.3: Bonjour
BONJOUR.ASP BONJOUR.PHP BONJOUR.JSP
01. <HTML> 01. <HTML> 01. <HTML>
02. <HEAD><TITLE>Bonjour 02. <HEAD><TITLE>Bonjour 02. <HEAD><TITLE>Bonjour</
</TITLE> </HEAD> </TITLE> </HEAD> TITLE> </HEAD> <BODY>
<BODY> <BODY> 03. <%= "Bonjour!” %>
03. <% Response.Write 03. <? print "Bonjour!” ?> 04. </BODY>
"Bonjour!” %> 04. </BODY> 05. </HTML>
04. </BODY> 05. </HTML>
05. </HTML>
Divers composants supplémentaires sont fournis avec ASP. Voici ceux que vous
utiliserez sans doute le plus couramment:
Ad Rotator. Ce composant sert à afficher des bannières publicitaires sur un site
Web. Il permet de spécifier avec quelle fréquence chaque bannière sera affichée.
Browser Capabilities. Ce composant permet de renvoyer un code HTML différent
en fonction des possibilités du navigateur. Il servira par exemple à envoyer des
pages avec des frames uniquement aux navigateurs prenant en charge cette
fonction.
Content Linking. Ce composant permet de relier plusieurs pages HTML entre
elles pour y faciliter la navigation. Il servira par exemple a relier entre elles les
pages d'un livre en ligne.
File Access. Ce composant permet de travailler avec le système de fichiers de
l'ordinateur, pour ouvrir et enregistrer des fichiers texte, par exemple.
Contrairement aux composants intégrés, avant de pouvoir utiliser un composant
supplémentaire, il faut en créer une instance. La page ASP du Listing 1.4 crée une
instance du composant AdRotator et affiche une bannière publicitaire.
LISTING 1.4: Utilisation du composant Ad Rotator
<HTML>
<HEAD><TITLE>Banni&egrave;re publicitaire</TITLE></HEAD> <BODY>
<% Set LaPub = Server.CreateObject("MSWC.Adrotator") %>
<CENTER><%=LaPub.GetAdvertisernent("adrot.txt" )%></CENTER> </BODY>
</HTML>
ASP-Analyse
Les script ASP crée un objet de type AdRotator nomé LaPub, qui ensuite
affiche les banières dans l’ordre indiqué dans le fichier adrot.txt
On observe que l’utilisation du composant AdRotator en ASP ressemble
beaucoup avec l’utilisation du composant Calendar dans heure.jsp dans le
listing 1.1.
Info
Quelle est Ia différence entre un composant et un objet? Un objet est une instance d'un
composant. Les objets ASP intégrés sont nommés objets et non composants parce qu'ils
sont crées de manière implicite.
En JSP et aussi en Java à la place de composant on parle de classe ou de JavaBean.
Vous n'êtes pas obligé de vous contenter des composants livrés avec ASP. Il
existe des centaines de composants crées par différents éditeurs de logiciels que
vous pouvez inclure dans vos scripts. Les composants vous serviront par
exemple a envoyer des fichiers de l'utilisateur vers le serveur a transférer des
fichiers entre serveurs on à envoyer et à recevoir du courrier électronique. Vous
pouvez également créer vos propres composants à l'aide de langages tels que
Visual Basic, le C++ ou le Java.

Conclusion
Les pages serveur et l’accès aux bases de données
ASP comprend un ensemble particulier d'objets qui méritent une description
séparée: les objets de données ActiveX (ActiveX Data Objects, ou ADO). Les
objets ADO permettent d'accéder a une base de données à partir d’une page ASP.
Les objets ADO peuvent être employés pour insérer, modifier et supprimer des
lignes dans le tables des bases de données. Ils peuvent également servir à extraire
un ensemble d'enregistrements à partir d'une requête et à afficher ces
enregistrements dans une page ASP
Dans ce cours, vous verrez comment utiliser les objets ADO pour stocker et
extraire des données dans des bases de données Access et SQL Server. Cependant,
les objets ADO peuvent être utilises avec n'importe quelle base de données ODBC
où OLE DB, et en particulier les bases de données Oracle, Sybase, Informix, DB2
et Ingres.
En PHP il y à des fonctions adaptées à chaque serveur de bases de données qui
assurent les traitement évoqués. En JSP il y à pléthore de composants Java qui
assurent ces fonctionalités.
En résumé
Ce chapitre a introduit les deux principaux sujets de ce cours: Le commerce
électronique et les pages serveur. Dans la première partie de ce chapitre, nous
avons évoqué la croissance rapide du commerce électronique et les différentes
formes qu'il pouvait prendre.
Dans la seconde partie, nous avons parlé des technologies Microsoft et non-
Microsoft permettant de créer des sites Web commerciaux.
La troisième partie, enfin, était consacrée aux pages serveur. Nous y avons vu en
quoi une page serveur différait d'une page HTML normale et qu'elle pouvait faire
appel a des scripts, des objets, des composants et, pour accéder à des bases de
données, à des objets spécialisés d’accès aux données.
Questions Réponses
Q Quelles sont les limitations des pages ASP? Peuvent-elles servir à créer
n'importe quel type de site Web commercial?
R Comme vous l’avez vu dans ce chapitre, les pages ASP sont actuellement
utilisées sur certains des sites les plus importants et les plus visités du Web. Ainsi,
Dell vend quotidiennement pour plus de 20 millions d'euros de matériel
informatique via ses sites, qui font appel à IIS et aux pages ASP.
La technologie ASP est très polyvalente. S'il y manque une fonction, elle peut être
ajoutée par 1'intermédiaire de composants personnalisés.
Q Quels systèmes d'exploitation sont compatibles avec ASP?
R Lcs pages ASP fonctionnent en natif sons Microsoft NT 4.0, sons Microsoft NT
Workstation 4.0 avec Peer Web Services et sous Windows 95, 98 avec Personal
Web Server
Avec Chili!ASP de Chili!Soft (http://www.chilisoft.com), les pages ASP peuvent
egalement fonctionner sous Solaris SUN et AIX IBM. Chili!ASP permet aux pages
ASP de fonctionner sur les serveurs Apache, Netscape Enterprise, FastTrack, Lotus
Domino Go et Website Pro de O'Reilly.
Il existe une version de Personal Web Server et des pages ASP, mais celle-ci n'est
malheureusement plus prise en charge par Microsoft.
Testez vos connaissances
1. Quelles sont les trois formes de commerce électronique ?
2. Personal Web Server pent-il être employé pour un site Web commercial
recevant des milliers de visiteurs par jour ?
3. Access peut-il être employé pour un site Web commercial recevant des milliers
de visiteurs par jour ?
4. Est-il nécessaire d'utiliser Visual InterDev pour créer des pages ASP ?
5. Comment le serveur Web distingue-t-il une page ASP d'une page HTML
normale?
6. Les pages ASP sont-elles compatibles avec tous les navigateurs Web ?
7. Est-il possible de créer des scripts ASP en utilisant un autre langage que le
VBScript?
2
Chaptre

Comprendre les applications Web 1


Utilisations courantes des applications Web
Présentation
Les applications Web peuvent être utilisées de diverses façons par les utilisateurs et les
développeurs, notamment pour :
• Permettre aux utilisateurs de trouver rapidement et facilement des informations sur
un site Web riche en contenu.
Ce type d'applications Web permet aux utilisateurs de rechercher, d'organiser et de
parcourir le contenu à leur convenance. Les exemples incluent des réseaux intranet
d'entreprises, tels Microsoft MSDN et Amazon.com.
• Collecter, enregistrer et analyser des données fournies par les utilisateurs.
Auparavant, les données saisies dans des formulaires HTML étaient envoyées sous
forme de messages électroniques aux employés ou sous forme d'applications CGI pour
le traitement. Une application Web peut enregistrer les données d'un formulaire
directement dans une base de données et créer des rapports Web pour l'analyse. Les
exemples incluent des pages de banques en ligne, de contrôle des stocks, des sondages
et des formulaires de commentaires.
• Mettre à jour des sites Web dont le contenu change souvent.
Une application Web évite au créateur d'avoir à mettre fréquemment à jour le
code HTML du site. Les fournisseurs de contenu tels que les rédacteurs en chef
alimentent l'application Web et celle-ci met automatiquement le site à jour, comme par
exemple The Economist et CNN.

1
Adapté du système d’aide du logiciel d’édition de sites Web Dreamweaver MX.
Exemple d'application Web
Présentation
Vincent, professionnel de la création Web, utilise Dreamweaver depuis de nombreuses
années. Il est chargé de la maintenance des sites intranet et Internet d'une entreprise de
taille moyenne comptant 1000 employés. Le responsable du service marketing, lui
soumet un jour un problème. Pour mieux cibler la clientèle son service aurait besoin de
la date de naissance des clients. Malgré le faite que l’entrée dans le site web commercial
de la société passe par un formulaire d’enregistrement qui prévoit optionnellement la
date de naissance, on constate que les client ne remplissent pas ces informations. Le
responsable marketing suggère qu’il faut trouver des astuces pour inciter les clients de
saisir leur date de naissance.
Vincent propose entre autre d’offrir aux clients qui enregistrent leur date de naissance
l’occasion de connaître à toute instant leur biorythme2.
Cahier des charges de l’application
Cette application Web exécutera les tâches suivantes :
• Permettre aux clients de saisir leur login sur une page Web au moyen d'un
simple formulaire HTML
• Stocker la date de naissance des clients dans une base de données
• Calculer les biorythmes pour le mois courant en fonction de la date de
naissance
• Permettre aux clients de suivre leurs prévisions de forme (biorythmes) au fil du
temps
• Permettre au responsable marketing d'accéder à la liste des clients enrichie avec
les dates de naissance.
Vincent met rapidement en place l'application à l'aide de Dreamweaver MX, logiciel
doté des outils nécessaires à la création rapide et facile de ce type d'applications.

Fonctionnement d'une application Web


Présentation
Une application Web est un ensemble de pages ordinaires et dynamiques. Une page
ordinaire n'est pas modifiée lorsqu'un utilisateur la consulte : le serveur Web transmet la

2
Les biorythmes sont des cycles ou des rythmes énergétiques de la vie qu’enregistrent les individus
depuis leur naissance, qui se répètent avec une certaine périodicité (tous les 23 jours pour le
biorythme physique, tous les 28 jours pour le biorythme intellectuel et tous les 33 jours pour le
biorythme affectif) et qui ont connu une certaine vogue et reconnaissance scientifique, mais qui
actuellement relèvent plus de l’astrologie. Pour une illustration on peut consulter l’adresse Internet
http://www.astro.qc.ca/biorythme/.
page au navigateur qui la sollicite sans la modifier. A l'inverse, une page Web
dynamique est modifiée par le serveur avant d'être transmise au navigateur qui la
sollicite. C'est pourquoi cette page est dite dynamique.
Vous pouvez par exemple créer une page pour afficher les résultats du programme de
mise en forme et faire en sorte que certaines informations (telles le nom et les résultats
de l'employé) soient déterminées lorsqu'une page est sollicitée par un employé.

Traitement des pages Web ordinaires


Présentation
Un site Web ordinaire comprend un jeu de pages et de fichiers HTML associés hébergés
sur un ordinateur exécutant un serveur Web.
Un serveur Web est un logiciel qui fournit des pages Web en réponse à des requêtes de
navigateurs Web. Une requête de page est générée lorsqu'un utilisateur clique sur un lien
d'une page Web, choisit un signet dans le navigateur ou saisit une URL dans le champ
Adresse du navigateur et clique sur OK.
Le contenu final d'une page Web est déterminé par le créateur de la page et n'est pas
modifié lorsqu'un utilisateur la sollicite.
Example
<html>
<head>
<title>Appeler le Department</title>
</head>
<body>
<strong>Appler le Department</strong><br>
Parler à quelqu’un du département Marketing.
</body>
</html>

Chaque ligne du code HTML de la page est rédigée par le créateur avant que la page ne
soit placée sur le serveur. Ce code HTML n'étant pas modifié une fois la page sur le
serveur, cette page est dite statique.
Pages statiques et dynamiques
Remarque : au sens strict du terme, une page dite « statique » peut ne pas être statique
du tout. Une image survolée ou une animation Flash, par exemple, peuvent animer une
page statique. Cependant, ce système d'aide qualifie une page de statique si elle est
adressée au navigateur sans modifications.
Processus de traitement des pages Web ordinaires
Lorsqu'un serveur Web reçoit une requête de page statique, il lit la requête, localise la
page et la transmet au navigateur qui l'a sollicitée, tel qu'indiqué dans la figure
ci-dessous :
FIGURE 1 – Processus de traitement des pages Web ordinaires

Source: Système d’aide de Dreamweaver


Figure 2. Processus de traitement des pages dynamiques

Source: Système d’aide de Dreamweaver


Dans le cas des applications Web, certaines lignes de code ne sont pas déterminées au
moment où l'utilisateur sollicite la page. Ces lignes doivent être déterminées via un
mécanisme avant que la page ne soit transmise au navigateur. Ce mécanisme est
présenté dans la section suivante.

Traitement des pages dynamiques


Présentation
Lorsqu'un serveur Web reçoit une requête de page Web ordinaire, il transmet
simplement cette page au navigateur requérant. Le serveur Web réagit différemment
lorsqu'il reçoit une requête de page dynamique : il transmet cette page à une extension
logicielle spéciale chargée d'achever la page. Ce logiciel spécial est appelé serveur
d'application. Le serveur d'application lit le code de la page, termine cette page en
fonction des instructions figurant dans le code, puis en retire le code.
Il en résulte une page statique que le serveur d'application renvoie au serveur Web,
lequel transmet alors cette page au navigateur requérant. Le navigateur reçoit
uniquement du code HTML pur lorsque la page lui est transmise.
Accès à une base de données
Présentation
Un serveur d'application vous permet de travailler avec des ressources côté serveur
telles que les bases de données. Une page dynamique peut, par exemple, ordonner au
serveur d'application d'extraire des données de la base de données et de les insérer dans
le code HTML de la page.
L'instruction d'extraction des données de la base est nommée requête de base de
données. Une requête est composée de critères de recherche rédigés dans un langage de
base de données appelé SQL (Structured Query Language). La requête SQL est rédigée
dans les scripts ou les balises côté serveur de la page.
Le pilote de base de données
Un serveur d'application ne peut pas communiquer directement avec une base de
données car le format propriétaire de cette dernière rend les données indéchiffrables, de
la même manière qu'un document Word ouvert dans Bloc-notes est indéchiffrable. Le
serveur d'application peut communiquer uniquement via un pilote de base de données.
Un pilote de base de données est un logiciel qui agit comme un interprète entre le
serveur d'application et la base de données.
Les requêtes SQL et les jeux d’enregistrements
Une fois que le pilote a établi la communication, la requête est exécutée par rapport à la
base de données et un jeu d'enregistrements est créé. Un jeu d'enregistrements est un
sous-ensemble de données extraites d'une ou de plusieurs tables de base de données. Le
jeu d'enregistrements est renvoyé au serveur d'application et les données sont utilisées
dans la page dynamique. Voici un exemple simple de requête de base de données
rédigée en SQL :
SELECT nom, prenom, annee FROM clients
Cette instruction crée un jeu d'enregistrements à trois colonnes et le remplit de lignes
comportant le nom, le prénom et les points de mise en forme de tous les employés de la
base de données.
Processus de traitement des pages dynamiques avec accès à une base de données
Voici une illustration du processus d'interrogation de la base de données via des requêtes
et de la transmission des données au navigateur :
Figure 3. - Processus de traitement des pages dynamiques
avec accès à une base de données

Source: Système d’aide de Dreamweaver


Choix du serveur de bases de données
Vous pouvez utiliser pratiquement toutes les bases de données avec votre application
Web, si vous possédez les pilotes de base de données requis.
Si vous prévoyez de créer de petites applications peu onéreuses, vous pouvez utiliser
une base de données fichier, créée par exemple sous Microsoft Access. Si vous
prévoyez de créer des applications stratégiques robustes, vous pouvez utiliser une base
de données serveur, créée par exemple avec Microsoft SQL Server, Oracle 9i ou
MySQL.
Si votre base de données réside sur un système autre que votre serveur Web, assurez-
vous qu'il existe une connexion rapide entre les deux systèmes pour un fonctionnement
efficace et rapide de votre application Web.
Création de pages dynamiques
Utilisation des langages de programmation intégrés
La création d'une page dynamique consiste à écrire d'abord le code HTML, puis à
ajouter les scripts et les balises côté serveur au code HTML pour rendre la page
dynamique. Lorsque vous visualisez le code obtenu, le langage apparaît incorporé dans
le code HTML de la page. Par conséquent, ces langages sont appelés langages de
programmation HTML intégrés.
Exemple d’instructions de programmation
L'exemple ci-dessous utilise le code JSP (Java Server Pages) :
<html>
<body>
<b>Appeler le Department</b><br>
<% departement="Marketing"%>
Parler à quelqu’un du <%= departement %>.
</body>
</html>

Les instructions incorporées dans cette page exécutent les actions suivantes :
1. Création d'une variable appelée departement et assignation de la chaîne
« Marketing » à cette variable.
2. Ecriture de la valeur de la chaîne de la variable, « Marketing », dans le
code HTML.
Résultats renvoyés par le serveur d’applications
Le serveur d'application renvoie la page suivante au serveur Web :
<html>
<body>
<b>Appeler le Department</b><br>
Parler à quelqu’un du Marketing.
</body>
</html>

Le serveur Web transmet la page au navigateur requérant, lequel l'affiche de la manière


suivante :
Appeler le Department
Parler à quelqu’un du Marketing.
Quelques technologies
Le langage de script ou de balise utilisé dépend de la technologie du serveur. Les
langages les plus employés pour les cinq technologies de serveur prises en charge par
Dreamweaver MX sont :
TABLEAU 1. Les technologie serveur supportés par Dreamweaver

Technologie de serveur Langage

ColdFusion CFML (ColdFusion Markup Language)

ASP.NET Visual Basic


C#

Pages ASP (Active Server Pages) VBScript


JavaScript

JSP (JavaServer Pages) Java

PHP PHP
Source : les système d’aide de Dreamweaver

Dreamweaver peut rédiger les scripts ou les balises côté serveur nécessaires au
fonctionnement de vos pages, mais vous pouvez aussi les écrire manuellement dans
l'environnement de codage Dreamweaver.

Choix d'une technologie de serveur


Choix par rapport au langage de script maîtrisé
Vous pouvez utiliser Dreamweaver MX pour créer des applications Web à l'aide de cinq
technologies de serveur : ColdFusion, ASP.NET, ASP, JSP ou PHP. Chacune de ces
technologies correspond à un type de document dans Dreamweaver. Le choix de l'une
de vos applications Web repose sur plusieurs facteurs, notamment votre niveau de
connaissance des différents langages de script et le serveur d'application que vous
envisagez d'utiliser.
Si vous n'avez jamais créé d'applications Web ou d'applications en général, vous
préférerez sûrement utiliser ColdFusion en raison de son environnement de script
serveur convivial intégré à Dreamweaver. Dreamweaver prend également en charge
d'autres technologies de serveur, telles que JSP, PHP, ASP ou ASP.NET.
Choix par rapport au serveur
Votre choix de technologie de serveur dépend également du serveur d'application que
vous souhaitez utiliser pour votre application Web. Un serveur d'application est un
logiciel qui aide un serveur Web à traiter des pages Web contenant des scripts ou des
balises côté serveur. Par exemple, si vous disposez de ColdFusion MX, vous pouvez
choisir ColdFusion comme technologie de serveur. Si vous avez accès au serveur
Microsoft Internet Information Server 5 (IIS) avec la plate-forme .NET, vous pouvez
choisir ASP.NET. Faites appel à PHP si vous avez accès à un serveur Web avec un
serveur d'application PHP ; JSP peut également convenir si vous pouvez accéder à un
serveur Web avec un serveur d'application JSP, tel que Macromedia JRun.
Ressources pour les technologies de pages serveur
• Vous trouverez une version de ColdFusion MX destinée aux développeurs sur
le CD Dreamweaver MX (version Windows uniquement) et sur le site Web de
Macromedia.
• Pour plus d'informations sur les serveurs d'application, voir Configuration d'un
serveur d'application.
• Pour en savoir plus sur ColdFusion, consultez la documentation ColdFusion
dans Dreamweaver (Aide > Utilisation de ColdFusion) ou visitez le site Web
de Macromedia (http://www.macromedia.com/fr/software/coldfusion/)
• Pour en savoir plus sur ASP.NET, visitez le site Web Microsoft (http://asp.net/
- en anglais).
• Pour en savoir plus sur ASP, visitez le site Web Microsoft
(http://msdn.microsoft.com/library/default.asp?URL=/library/psdk/iisref/aspgui
de.htm - en anglais).
• Pour en savoir plus sur JSP, visitez le site Web de Sun
(http://java.sun.com/products/jsp/ - en anglais).
• Pour en savoir plus sur PHP, visitez le site Web de PHP (http://www.php.net/ -
en anglais).

Configurer Dreamweaver pour ASP, PHP et JSP


Présentation
Pour construire des applications web avec Dreamweaver, il y à quelques logiciels
serveurs à installer et quelques instructions de configuration à suivre.
Prérequis en terme de logiciels serveurs
Pour pouvoir tester les applications en local (sur le même ordinateur) avant de les
publier sur un ordinateur distant, on doit s’assurer que des logiciels adaptés: serveurs de
pages web et/ou d’applications web, ainsi que des serveurs de bases de données sont
installés et fonctionnent sur l’ordinateur local.
ASP
Les serveurs de pages et d’applications web de type ASP sont Microsoft IIS,
fourni avec Windows NT Server, Windows 2000 et Windows XP Professionnel.
Microsoft ; PWS, version réduite de IIS fonctionnant sous Windows 98 et NT
Workstation et Sun Chili!Soft ASP, dont il existe une version pour Windows,
Linux, Solaris et d'autres plates-formes.
Les serveurs de bases de données ne sont pas fournis avec Windows mais doivent
être installés séparément. Des serveurs de bases de données usuels sous Windows
sont Acces, Oracle ou SQL Server.
JSP
Des serveurs d’application adaptés sont Apache Tomcat (gratuit), IBM
Websphere, Macromedia Jrun, BEA Weblogic. Tomcat s’installe facilement en
tandem avec le serveur de pages web Apache qui est disponible dans la formule
freeware EasyPHP. Comme serveur de base de données on peut utiliser MySQL
qui est également disponible dans EasyPHP.
PHP
Dans la solution EasyPHP serveur d'application PHP est intégré au serveur de
pages web Apache par le module mod_php. Et les serveur de bases de données
MySQL fait aussi partie de l’ensemble.
Définition d’une application web en Dreamweaver
La définition d'un site Dreamweaver pour l'application Web se déroule en trois
étapes :
1. Définition d'un dossier situé sur le disque dur comme dossier local
Dreamweaver dans lequel seront stockées les copies de travail des fichiers du
site (voir Définition d'un dossier local).
2. Définition d'un dossier situé sur l'ordinateur exécutant le serveur Web comme
dossier distant Dreamweaver (voir Définition d'un dossier distant).
3. Définition de l'emplacement vers lequel Dreamweaver doit transférer les pages
dynamiques devant être traitées pendant la procédure de création du site (voir
Définition du dossier de traitement des pages dynamiques).
Pour accéder à la boite de dialogue de définition d’un site choisissez dans le menu de
Dreamweaver : Site> Nouveau site pour créer un site nouveau ou Modifier les sites pour
changer la définition d’un site existant. Puis quand la boîte de dialogue Définition du
site s'ouvre si l'assistant s'affiche, cliquez sur Avancé.
Exemples de configurations JSP, ASP et PHP
Voici à titre d’exemple la définition des versions ASP, JSP et PHP du site qui contient
les exemples de ce cours, intitulé cours_comelec:
TABLEAU 2 – Définition d’une application web en utilisant les technologies ASP,
JSP et PHP

Type d’application web PHP JSP ASP


Infos locales
Nom du site cours_comelec_php cours_comelec_jsp cours_comelec_asp
Dossier racine D:\Program D:\Program D:\MesDocuments\com
Files\EasyPHP\www\c Files\Apache Tomcat elec_asp\_asp\
ours_comelec 4.0\webapps\tomcat-
docs\appdev\comelec_j
sp\web\
http du site http://localhost/cours_c http://localhost:8080/co D:\MesDocuments\com
omelec/ urs_comelec/ elec_asp\
Infos distantes
Accès FTP FTP *
Hôte FTP ftpperso.free.fr claree.univ-lille1.fr -
Répertoire du hôte ./cours_comelec /opt/tomcat/webapps/co -
urs_comelec/
Nom d’utilisateur mihai.calciu calciu -
Mot de passe ******** ******** -
Serveur d’évaluation
Modèle serveur PHP MySQL JSP ASP VBscript
Accès Local/Réseau Local/Réseau Local/Réseau
Dossier du serveur D:\Program D:\Program D:\MesDocuments\com
d’évaluation Files\EasyPHP\www\c Files\Apache Tomcat elec_asp\_asp\
ours_comelec 4.0\webapps\cours_co
melec
Préfixe URL http://localhost/cours_c http://claree.univ- http://localhost/comelec
omelec/ lille1.fr/cours_comelec/ _asp/
* En absence d’un hébergeur pour la version ASP ce site fonctionne seulement en locale

Termes fréquemment utilisés


Un glossaire
Cette section répertorie les termes fréquemment employés.
Un serveur d'application est un logiciel qui aide un serveur Web à traiter des pages Web
contenant des scripts ou des balises côté serveur. Lorsqu'une page de ce type est requise
par le serveur, le serveur Web transmet cette page au serveur d'application afin qu'il la
traite avant de l'envoyer au navigateur.
Les serveurs d'application les plus utilisés sont Macromedia ColdFusion, Macromedia
JRun Server, la plate-forme .NET de Microsoft, IBM WebSphere et Apache Tomcat.
Une base de données est un ensemble de données stockées sous forme de tables.
Chaque ligne d'une table correspond à un enregistrement de données et chaque colonne
correspond à un champ de l'enregistrement, tel qu'illustré ci-dessous.
Un pilote de base de données est un logiciel qui agit comme un interprète entre un
serveur d'application et une base de données. Les données d'une base de données sont
stockées dans un format
propriétaire. Un pilote de base de
données permet à l'application Web
de lire et de manipuler des données
qui, sans cela, seraient
indéchiffrables.
Un système de gestion de base de
données (SGBD ou système de base
de données) est un logiciel utilisé
pour créer et manipuler des bases de
données. Les systèmes de base de
données les plus courants sont
Microsoft Access, Oracle 9i et
MySQL.

Une requête de base de données désigne l'opération permettant d'extraire un jeu


d'enregistrements d'une base de données. Une requête est constituée de critères de
recherche exprimés en langage de base de données appelé SQL. La requête peut, par
exemple, spécifier que seules certaines colonnes ou certains enregistrements doivent être
inclus dans le jeu d'enregistrements.
Une page dynamique est une page Web
qui est personnalisée lors de son exécution
par un serveur d'application et cela avant
que la page ne soit transmise à un
navigateur.
Un jeu d'enregistrements est un sous-
ensemble de données extraites d'une ou
plusieurs tables d'une base de données, tel
qu'illustré ci-dessous :
Une base de données relationnelle est une base de données contenant plusieurs tables
qui partagent des données. La base de données suivante est relationnelle car deux tables
partagent la colonne DepartmentID.
Une technologie de serveur est une technologie utilisée par un serveur d'application
pour modifier des pages dynamiques lors de l'exécution.
L'environnement de développement Dreamweaver MX prend en charge les
technologies de serveur suivantes :
• Macromedia ColdFusion
• Microsoft ASP.NET
• Pages ASP (Active Server Pages) de Microsoft
• Pages JSP (JavaServer Pages) de Sun
• PHP (PHP Hypertext Preprocessor)
Vous pouvez également utiliser l'environnement de codage de Dreamweaver pour
développer des pages destinées à une technologie de serveur quelconque non répertoriée
ci-dessus.
Une page statique est une page Web qui n'est pas modifiée lors de son exécution par un
serveur d'application avant que la page ne soit envoyée à un navigateur.
Une application Web est un site Web qui contient des pages stockées sur un serveur
Web et dont le contenu est partiellement ou totalement indéterminé. Le contenu final de
ces pages est déterminé uniquement lorsque l'utilisateur requiert une page depuis le
serveur Web. Le contenu final d'une page variant d'une requête à une autre en fonction
des actions de l'utilisateur, ce type de page est appelée page dynamique.
Un serveur Web est un logiciel qui fournit des pages Web en réponse à des requêtes de
navigateurs Web. Une requête de page est générée lorsqu'un utilisateur clique sur un lien
d'une page Web, choisit un signet dans le navigateur ou saisit une URL dans le champ
Adresse du navigateur et clique sur OK.
Les serveurs Web les plus courants sont Microsoft Internet Information Server,
Microsoft Personal Web Server, Apache HTTP Server, Netscape Enterprise Server et
iPlanet Web Server.
ANNEXE - Création de l’application biorythme avec
Dreamweaver
Cahier des charges de l’application
L’application biorythme décrite en début du chapitre devra exécuter les tâches
suivantes :
• Permettre aux clients de saisir leur login sur une page Web au moyen d'un
simple formulaire HTML
• Stocker la date de naissance des clients dans une base de données
• Calculer les biorythmes pour le mois courant en fonction de la date de
naissance
• Permettre aux clients de suivre leurs prévisions de forme (biorythmes) au fil du
temps
• Permettre au responsable marketing d'accéder à la liste des clients enrichie avec
les dates de naissance.
Adaptation du cahier de charges à la technologie utilisée
Connaissant ces exigences et les possibilités de Dreamweaver les taches peuvent être
mieux précisés et ordonnées de la manière suivante:Créer une base de données avec une
table biorythme_clients dans laquelle seront stockées les informations client (login, mot
de passe, nom et prénom, mail, date de naissance)
• Créer un formulaire HTML pour permettre aux clients de s’enregistrer dans la
base de données en saisissant leurs données personnelles.
• Permettre au responsable marketing d'accéder à la liste des clients enrichie avec
les dates de naissance.
• Calculer les biorythmes pour le mois courant en fonction de la date de
naissance
• Permettre aux clients de suivre leurs prévisions de forme (biorythmes) au fil du
temps

Création de la table clients dans la base de


données
Gestion de la base de données en ligne
Chaque serveur de bases de données est secondé par un logiciel d’administration qui
souvent permet de créer et de gérer la base de données en ligne sur le web. Free.fr utilise
et met à la disposition de chaque abonné le logiciel phpMyAdmin qui est aussi inclus
dans le paquet EasyPHP.
Pour créer la table clients dans la base de données dont on dispose, on se connecte avec
un navigateur web au service d’administration de la base (pour l’administration distante
sur free.fr on va utiliser l’adresse http://sql.free.fr et pour l’administration locale sur
notre ordinateur on va utiliser l’adresse http://localhost/mysql/).
Si on travaille sur le serveur de bases de données local on sélectionne la base de données
de l’application biorythme. Si on travaille sur le serveur de bases de données distant de
free.fr on ne contrôle qu’une seule base et elle est présélectionnée.
Création de la table clients avec un programme d’administration
Dans la base de données sélectionnée on crée une nouvelle table avec huit colonnes
(champs) en remplissant le formulaire HTML comme dans la figure 4.

FIGURE 4 – Formulaire de création d’une table dans le programme phpMyAdmin

Créer une table clients en SQL


Si on maîtrise le langage SQL (qui est la norme pour toutes les logiciels de bases de
données professionnels) on peut utiliser la commande SQL suivante pour créer la même
table sans passer par les formulaire de la figure 4.
LISTING 2.1 Comande SQL de création d’un table dans un base de données

CREATE TABLE `biorythme_clients` (


`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
`nom` VARCHAR(50) NOT NULL,
`mail` VARCHAR(50) NOT NULL,
`login` VARCHAR(10) NOT NULL,
`pass` VARCHAR(8) NOT NULL,
`jour` SMALLINT NOT NULL,
`mois` SMALLINT NOT NULL,
`annee` INT NOT NULL,
UNIQUE (`nom`)
);
Création d’un formulaire HTML pour permettre aux
clients de s’enregistrer
Création d’une page serveur
Avec la table clients crée on ouvre en Dreamweaver l’application biorythme (dans cette
exemple elle apparaît comme une sous-application du site cours_comelec).
Une nouvelle page dynamique est crée. Elle va accueillir le formulaire d’enregistrement
des clients. Parmi toutes les technologies serveurs proposées (ColdFusion,ASP,
ASP.NET, JSP, PHP) c’est une page de type PHP qui sera choisi. Dans cette page on
écrit un texte qui invite les clients de s’enregistrer et on sauvegarde la page sous le nom
enregistrer.php (dans le dossier biorythme).
Définition de la connéxion à la base de données
Ensuite une connexion à la base de données sera définie pour être utilisée dans cette
page. Dans le menu Dreamweaver on choisi Fenêtre -> Base de données -> + suivi par
l’option Connexion MySQL. Dans la boite de dialogue qui s’affiche sont introduits les
éléments qui définssent la connexion. Ils diffèrent en fonction de la localisation du
serveur de bases de données comme l’illustre le tableau 3.
TABLEAU 3 - Définition d’une connexion à un serveur de bases
de données local et distant

Distant Local
Nom de la connexion Conn_biorythme_client_distant Conn_biorythme_client_local
Seveur MySQL sql.free.fr Localhost
Nom d’utilisateur mihai.calciu root
Mot de passe *********
Base de données mihai.calciu Biorythme

FIGURE 5 – Menu d’accès aux objets d’application génériques


et spécifiques en Dreamweaver
Sélection de l’objets d’application approprié
A l’aide des objets d’application de Dreamweaver3, on peut générer automatiquement la
page d’enregistrement des clients. Dans la figure 5 on voit la liste des objets
d’application génériques et l’accès à des objets d’application spécifiques à chaque
technologie serveur.
Configuration de l’objet formulaire d’insertion d’Enregistrements
Les objets génériques rassemblent les interactions les plus courantes avec le serveur de
bases de données ils permettent de réaliser en quelques clicks des pages d’application
qui aurait nécessité un travail de programmation relativement important.
La figure 6. montre comment on configure l’objet Formulaire d’insertion
d’enregistrement. Cet objet insère du code serveur et du HTML dans la page courante, à
l’aide d’une interface générique, indépendante de la technologie serveur utilisée.
Il s’agit de code HTML qui construit le formulaire à partir de la définition des champs
dans la base de données et de code serveur (PHP, ASP ou JSP) qui fait la connexion à la
base de données et insère la valeur des champs du formulaire dans une ligne
(enregistrement) de la table.
FIGURE 6 – Création d’une page d’enregistrement des clients avec l’objet
Formulaire d’insertion de Dreamweaver

3
Ce ne sont pas des objets dans le sens de la programmation orientée objets mais des wizards.
Création automatique du formulaire d’enregistrement
Le résultat est une page serveur (enregistrer.php) capable de soutenir le dialogue avec le
client et d’enregistrer les données saisies (voir figure 7).
Figure 7 – Page serveur qui enregistre les clients

Permettre au responsable marketing d'accéder à


la liste des clients.
Les objets tableau dynamique, barre et état de navigation
L’opération inverse à l’enregistrement dans la base est l’affichage de la liste des clients
déjà enregistrés. Elle aussi est obtenue avec peu d’effort grâce à Dreamweawer. L’objet
tableau dynamique qui produit le code HTML d’un tableau qui affiche dynamiquement
un nombre préfixé d’enregistrements du jeu d’enregistrements sélectionnés de la base
par une requête SQL. Si le jeu d’enregistrements est plus grand que le nombre fixé de
lignes dans une page, on peut faciliter la navigation parmi les pages multiples du tableau
dynamique à l’aide d’autres objets. Ces objets sont la barre de navigation et l’état de
navigation du jeux d’enregistrement (évoqués dans le figure 5).
Illustration
Voici une illustration :
FIGURE 8 – Page d’accès à la liste des clients
Calculer les biorythmes pour le mois courant en
fonction de la date de naissance
Présentation des calculs
La formule de calcul des biorythmes est sin (2*PI*jours_depuis_naissance/période), où
la période est spécifique pour chaque rythme ou cycle (23, 28 ou 33 jours). Pour calculer
les biorythmes il faut calculer le nombre de jours vécus par l’individu depuis sa
naissance et la formule se charge du calcul.
Transmission des donnees à l’application (formulaire ou chaîne de requête?)
Le client doit transmettre à la page d’application chargé de faire les calculs (par exemple
biorythme.php) le jours, le mois et l’année de naissance. Ces informations peuvent être
transmises à travers un formulaire installé dans la page appelante ou elles peuvent être
communiquées directement dans une chaîne de requête comme dans l’exemple présenté
dans la figure 9.
FIGURE 9. – Calcul du biorythme dans un page en utilisant
des informations de la chaîne de requête

Explication des chaînes de requête


En fonction de la localisation de la page l’appel prendra une des formes suivantes :
• http://localhost/cours_comelec/biorythme.php?jour=6&mois=9&annee=1984
(pour le site local) ou
• http://mihai.calciu.free.fr/cours_comelec/biorythme.php?jour=6&mois=9&ann
ee=1984 (pour le site distant).
Après le point d’interrogation on trouve les variables de la chaîne de requête avec les
valeurs qui leur sont attribuées. Ce sont ces variables et leurs valeurs que la page serveur
doit capter et utiliser dans les calculs. Dans le code serveur de type PHP ont peut utiliser
directement le nom des variables (précédé du signe $) pour accéder à leurs valeurs.
Exemple en PHP
Voici le code de la page PHP qui calcule le nombre de jours vécus par la personne et
ensuite les valeurs de son biorythme.
LISTING 2.2 - Code de la page PHP qui calcule le biorythme

01. <body bgcolor="#FFFFCC">


02. <p align="left">Bonjour,</p>
03. <p align="left">Vous &ecirc;tes n&eacute; le <? echo "$jour.$mois.$annee"; ?></p>
04. <? $jours_depuis_naissance = (date("U")-date("U",
mktime(0,0,0,$mois,$jour,$annee)))/(3600*24); ?>
05. <p align="left">Vous avez v&eacute;cu : <?php echo $jours_depuis_naissance; ?>
06. jours </p>
07. <p align="left">Les valeurs de vos biorythmes sont :</p>
08. <table><tr><td>Type de
biorythme</td><td>physique</td><td>affectif</td><td>intellectuel</td> </tr>
09. <tr><td>P&eacute;riodicit&eacute; (en
jours)</td><td>23</td><td>28</td><td>33</td></tr>
10. <tr>
11. <td>Valeur du biorythme</td>
12. <td><?php echo sin(2*3.1416*$jours_depuis_naissance/23); ?></td>
13. <td><?php echo sin(2*3.1416*$jours_depuis_naissance/28); ?>&nbsp;</td>
14. <td><?php echo sin(2*3.1416*$jours_depuis_naissance/33); ?>&nbsp;</td>
15. </tr>
16. </table>
17. </body>
18. </html>
Analyse
L’application affiche d’abord à la ligne 3, la valeur du jour, du mois et de l’année
de naissance récupérée de la chaîne de requête. Ensuite ces valeurs rentrent dans
la formule de calcul du nombre de jours depuis la naissance de la ligne 4, qui
utilise de fonction spécialisée de PHP pour traiter les dates et le temps. On voit
bien que la différence entre la date d’aujourd’hui et la date de naissance retourne
le nombre de secondes vécues qui est transformé en jours depuis la naissance en
divisant par le nombre de secondes d’une journées (3600*24). Ensuite dans les
cellules d’un tableau HTML aux lignes 12 à 14 sont calculés les valeurs des trois
types de biorythmes en utilisant la formule évoqué.
Une fois enregistrés avec leur date de naissance, les clients peuvent suivre leurs
biorythmes tout simplement en s’identifiant sur le site avec leur login et mot de
passe. Pour cela la page serveur doit :
• se connecter à la base de données et sélectionner l’enregistrement avec les
données du client ;
• utiliser les données extraites pour fournir un message personnalisé et les
calculs que le client attend.
La connexion à la base de données, la sélection de la table biorythme_clients et
l’extraction du jeu d’enregistrement se fera de la même manière que dans les
pages précédentes.
3
Chaptre

Interaction des sites de commerce


electronique avec le visiteur
L’Affichage dynamique ou la réponse du serveur
(l'objet Response)
Rappels
Les précédents chapitres étaient une introduction aux pages serveur. Nous y avons vu
qu’une page serveur est une page HTML normale contenant des scripts; ces scripts
peuvent être utilisés pour envoyer des informations au navigateur de manière
dynamique.
Qu'est-ce qu'un contenu dynamique? Le contenu d'une page HTML normale est
statique. Chaque fois qu'un utilisateur demande une page HTML, son contenu reste
inchangé. Une page serveur, en revanche, peut être différente à chaque fois que
l'utilisateur tente d'y accéder.
Dans le contexte d'un site Web commercial, il est souvent nécessaire de fournir un
contenu dynamique à l'utilisateur. Ainsi, si vous proposez à vos clients d'afficher vos
produits par catégorie, cette liste de produits devra être générée de manière dynamique
pour les différentes catégories de produits. De même, une fois que 1'utilisateur est prêt à
passer commande, la page du bon de commande doit, elle aussi, être générée de manière
dynamique.
Les formes et objets de la Réponse
Pour créer du contenu dynamique à partir d'une page ASP, vous pouvez utiliser 1'objet
ASP intègre Response. Celui-ci représente toutes les informations envoyées du serveur
Web au navigateur Web. En JSP l’objet Réponse est masqué par la balise expression
<%= et %>, il prend la main dans la servlet (le programme qui représente la page JSP
après sa traduction en langage JAVA). En PHP la fonction print offre les
fonctionnalités qu’on recherche.
Ainsi, la page serveur du Listing 3.1 affiche la date et l’heure courantes. Chaque fois
que l'utilisateur accédera à cette page, la date et l'heure affichées seront différentes.
LISTING 3.1: Affichage d'une page dynamique

ASP JSP PHP


01. <HTML> 01. <HTML> 01. <HTML>
02. <HEAD><TITLE>Date et 02. <HEAD><TITLE>Date et 02. <HEAD><TITLE>Date et
heure</TITLE></HEAD> heure</TITLE></HEAD> heure</TITLE></HEAD>
03. <BODY> 03. <BODY> 03. <BODY>
04. <% 04. <%= 04. <?
05. Response.Write NOW() 05. new java.util.Date() 05. print (Date("h:i :s A"));
06. %> 06. %> 06. ?>
07. </BODY> 07. </BODY> 07. </BODY>
08. </HTML> 08. </HTML> 08. </HTML>

Analyse
Comme vous pouvez le constater, La plus grande partie du Listing 2.1 est composée
de code HTML. Le contenu dynamique est généré dans le corps (BODY) de la page
HTML. Les lignes 4 à 6 contiennent un script très simple.
Pour ASP à la ligne 5, la méthode Write de l'objet Response est utilisée pour afficher
la date et l'heure courantes, pour lesquelles on fait appel à la fonction VBScript
NOW (). En JSP on affiche la valeur de l’objet Date, dont un instance est crée par la
l’instruction new. En PHP on utilise la fonction print pour afficher la valeur de
l’objet Date dans un format indiqué par la chaîne de format.
Les méthodes d’affichage
En général, les méthodes d’affichage servent à afficher la valeur d'une fonction,
d'une variable ou d’une chaîne. Ainsi, la page serveur du Listing 3.2 affiche le texte
(chaîne de caractères) "Bienvenue sur notre site".
LISTING 3.2: Bienvenue sur notre site

ASP JSP PHP

01. <HTML> 01. <HTML> 01. <HTML>


02. <HEAD><TITLE>Bienvenue 02. <HEAD><TITLE>Bienvenue 02. <HEAD><TITLE>Bienvenue
</TITLE></HEAD> </TITLE></HEAD> </TITLE></HEAD>
03. <BODY> 03. <BODY> 03. <BODY>
04. <% 04. <%= 04. <?
05. Response.Write "Bienvenue 05. "Bienvenue sur notre site" 05. print "Bienvenue sur notre
sur notre site" 06. %> site";
06. %> 07. <IBODY> 06. ?>
07. <IBODY> 08. </HTML> 07. <IBODY>
08. </HTML> 08. </HTML>

Affichage de chaînes longues


Si vous souhaitez afficher des chaînes de caractères très longues, vous pouvez repartir
les chaînes sur plusieurs lignes en faisant appel à des opérateurs adaptés. Voici par
exemple une page serveur affichant les premières lignes de La Chartreuse de Parme de
Stendhal:
LISTING 3.3: Chaînes longues

ASP JSP PHP

01. <HTML> 01. <HTML> 01. <HTML>


02. <HEAD><TITLE>cha&i 02. <HEAD><TITLE>cha&icirc; 02. <HEAD><TITLE>cha&icir
circ;nes nes c;nes
longues<ITITLE></HE longues<ITITLE></HEAD> longues<ITITLE></HEAD
AD> 03. <BODY> >
03. <BODY> 04. <%= 03. <BODY>
04. <% 05. "Le 15 mai 1796, le general 04. <?
05. Response.Write "Le 15 Bonaparte " + 05. print "Le 15 mai 1796, le
mai 1796, le general 06. "fit son entrée dans Milan à general Bonaparte ".
Bonaparte " &_ la tête de cette jeune armée 06. "fit son entrée dans Milan
06. fit son entrée dans "+ à la tête de cette jeune
Milan à la tête de cette 07. "qui venait de passer le armée ".
jeune armée " &_ pont de Lodi, " + 07. "qui venait de passer le
07. "qui venait de passer le 08. "et d'apprendre au monde pont de Lodi, ".
pont de Lodi, qu'après tant de siècles " + 08. "et d'apprendre au monde
08. et d'apprendre au 09. "César et Alexandre qu'après tant de siècles ".
monde qu'après tant de avaient un successeur." 09. "César et Alexandre
siècles " &_ 10. %> avaient un successeur."
09. "César et Alexandre 11. </BODY> 10. ?>
avaient un successeur." 12. </HTML> 11. </BODY>
10. %> 12. </HTML>
11. </BODY>
12. </HTML>

Analyse
Dans les scripts ASP, JSP et PHP des lignes 4 à 10, on montre comment afficher une
chaîne qui, dans le code, est repartie sur plusieurs lignes. En ASP la combinaison de
caractères &_ sert à indiquer que la chaîne se poursuit sur la ligne suivante. En JSP
(en langage JAVA) le signe + est aussi un opérateur de concaténation de chaînes de
caractères. En PHP le point joue le rôle de lien entre plusieurs chaînes de caractères.
Affichage de caractères spéciaux
Certains caractères ne s'afficheront pas correctement. Il s'agit des chevrons ouvrant et
fermant (< et >) ainsi que des guillemets.
Le problème vient du fait que ces caractères ont une signification spéciale en HTML.
Les chevrons servent à marquer le début et la fin des balises HTML. Lorsque le
navigateur rencontre ce type de caractère dans une page, il l'interprète comme
appartenant à une balise HTML.
Pour résoudre ce problème, les caractères doivent être codes avant d'être envoyés au
navigateur. Cette tâche est très simple à effectuer dans le cas d'une page ASP. Il
suffit d'utiliser la méthode HTMLEncode() de l'objet Server pour coder la chaîne
avant son envoi au navigateur.
Ainsi, la page ASP du Listing 3.4 code correctement la chaîne ">>N'hésitez pas à
comparer nos prix ! <<" avant de l'envoyer au navigateur.
LISTING 3.4: Codage HTML d'une chaîne

01. <HTML>
02. <HEAD><TITLE>Codage HTML dune cha&icirc;ne</TITLE></HEAD>
03. <BODY>
04. <%
05. Response.Write Server.HTMLEncode(">>N'h&eacute;sitez pas &agrave; comparer nos
prix! <<")
06. %>
07. </BODY>
08. </HTML>

Vous constaterez par la suite qu'il est souvent nécessaire de coder ainsi les chaînes
lorsqu'on travaille avec des formulaires HTML. Nous verrons d'ailleurs dans ce
chapitre comment utiliser la méthode HTMLEncode() avec un formulaire HTML
(voir la section "Utilisation de la collection Form" ci-dessous).
Affichage des guillemets
Le langage VBScript fait appel aux guillemets pour marquer le début et la fin des
chaînes. Cela pose un problème lorsque la chaîne elle-même contient des
guillemets. En effet, le VBScript, Java ou PHP interpréteront un guillemet situé à
l'intérieur d'une chaîne comme la fin de cette chaîne. Ainsi, le Listing 3.5 générera
une erreur.
LISTING 3.5 : Mauvaise utilisation des guillemets

01. <HTML>
02. <HEAD><TITLE>Mauvaise utilisation des guillemets</TITLE></HEAO>
03. <BODY>
04. <%
05. Response.Write "Il lisait "La Chartreuse de Parme"."
06. %>
07. <~BODY>
08. </HTML>

Analyse
Le Listing 3.5 génère une erreur à cause des guillemets de la ligne 5. Le
VBScript, Java et PHP interprètent le deuxième guillemet comme la fin de la
chaîne.
II existe deux moyens de résoudre ce problème. Le premier consiste insérer
deux guillemets de suite. Le VBScript interprète deux guillemets successifs
comme on seul guillemet la page ASP du Listing 3.6 montre comment utiliser
cette méthode. En JSP (Java) et PHP en précédera le guillemets à afficher par le
caractère \.
LISTING 3.6. Bonne utilisation des guillemets

ASP JSP PHP

01. <HTML> 01. <HTML> 01. <HTML>


02. <HEAD><TITLE>Bonne 02. <HEAD><TITLE>Bonne 02. <HEAD><TITLE>Bonne
utilisation des utilisation des utilisation des
guillemets</TITLE></HEA guillemets</TITLE></HE guillemets</TITLE></HEA
D> AD> D>
03. <BODY> 03. <BODY> 03. <BODY>
04. <% 04. <%= 04. <?
05. Response.Write "Il lisait 05. "Il lisait \"La Chartreuse 05. print "Il lisait \"La
""La Chartreuse de de Parme\"." Chartreuse de Parme\"." ;
Parme""." 06. %> 06. %>
06. %> 07. </BODY> 07. </BODY>
07. </BODY> 08. </HTML> 08. </HTML>
08. </HTML>

Deuxième méthode pour traiter les guillemets


Il existe en ASP une deuxième méthode pour insérer des guillemets dans une
chaîne VBScript. Celle-ci consiste a utiliser la fonction CHR() de VBScript. Le
Listing 3.7 fait appel à cette méthode.
LISTING 3.7: Bonne utilisation des guillemets

01. <HTML>
02. <HEAD><TITLE>Bonne utilisation des guillemets</TITLE></HEAD>
03. <BODY>
04. <%
05. Response.Write "Il lisait " & CHR(34) & "La Chartreuse de Parme "& CHR(34)
06. %>
07. </BODY>
08. </HTML>

Vous pouvez faire appel, au choix, à l'une ou à l'autre de ces deux méthodes, en
fonction de vos préférences.
Utilisation des délimiteur de sortie <%= et %>
Plutôt que d'utiliser la méthode Write de l'objet Response pour envoyer du contenu
au navigateur, vous pouvez utiliser les délimiteurs <%= et %>. Ainsi, le Listing 3.8
utilise ces délimiteurs à la place de la méthode Write pour afficher l'heure courante.
LISTING 3.8 : Délimiteurs de sortie

01. <HTML>
02. <HEAD><TITLE>D&eacute;limiteurs de sortie</TITLE></HEAD>
03. <BODY>
04. <%=TIME()%>
05. </BODY>
06. <~HTML>
Analyse
La ligne 4 permet d'afficher l'heure courante. File utilise les délimiteurs <%= et
%> pour envoyer au navigateur la valeur de la fonction VBScript TIME ().
Différence entre les délimiteurs <%= %> <% %>
En ASP et JSP il est important de ne pas confondre les délimiteurs de sortie
<%= et %> avec les délimiteurs de script <% et %>. Les premiers permettent
d'envoyer du contenu au navigateurs. Les seconds servent à marquer le début et
la fin d'un script.
Quand doit-on utiliser en ASP les délimiteurs <%= et %>, et quand doit-on
utiliser la méthode Write de l'objet Response? Les deux méthodes sont
parfaitement interchangeables. Cependant, l'utilisation des délimiteurs de sortie
<%= et %> est souvent plus pratique lorsqu'il faut afficher les valeurs d'une
série de variables ou de fonctions dans une page ASP.
Ainsi, le Listing 3.9 pourrait faire appel à la méthode Write, mais le code est
plus facile à lire lorsqu'on emploie les délimiteurs <%= et %>.
LISTING 3.9: Affichage d'une série de valeurs

01. <HTML>
02. <HEAD><TITLE>D&eacute;limiteurs de sortie</TITLE></HEAD>
03. <BODY>
04. <br>Nous sommes le <%=DATE()%>
05. <br>et il est <%=TIME()%> heures.
06. </BODY>
07. </HTML>

Terminer l'exécution d'un script avec l'objet Response


Jusqu'à maintenant, il n'a été question que d'une seule méthode de l'objet Response,
la méthode Write, qui permet d'envoyer do contenu au navigateur Web de
l'utilisateur. La méthode End est une autre méthode très utile de l'objet Response.
Elle permet d'arrêter l'exécution d'un script.
Ainsi, le Listing 3.10 contient deux messages. Le deuxième message du script n'est
pas affiche" par le navigateur parce que la méthode End de l'objet Response est
appelée entre le premier et le second message.

LISTING 3.10: Arrêt de l'exécution d'un script

01. <HTML>
02. <HEAD><TITLE>Arr&ecirc;t de 1'ex&eacute;cution d'un script</TITLE><~HEAD>
03. <BODY>
04. <¾
05. Response.Write "Premier message
06. Response. End
07. Response.Write "Second message
08. %>
09. <IBODY>
10. </HTML>

Analyse
La ligne 5 permet d'afficher le premier message. Dans la ligne 6, la méthode
End de l'objet Response est appelée. Cette méthode provoque l'arrêt immédiat
du traitement de la page. De ce fait, seul le contenu généré par les lignes 1 à 5
est envoyé au navigateur.

La requête adressé au serveur (l'objet Request)


Présentation
La réponse représente tout le contenu envoyé par le serveur Web au navigateur. La
requête représente quant à lui tout le contenu envoyé par le navigateur au serveur
Web. Cet objet vous servira à obtenir des informations en provenance de vos
clients.
Les collections de la requête
L'objet Request dispose de quatre collections très utiles:
• La collection QueryString, qui représente les variables de chaînes de
requête ;
• La collection Form, qui représente les champs de formulaire HTML;
• La collection ServerVariables, qui représente les en-têtes de navigateurs et
les variables de serveurs;
• La collection Cookies, qui représente les cookies du navigateur.
Dans les sections ci-dessous, vous apprendrez à utiliser les trois premières de ces
collections. Il sera question de la quatrième collection (Cookies) dans le chapitre
suivant.

Utiliser les chaînes de requête


Présentation
Une chaîne de requête est la partie d'une URL qui apparaît après le point
d'interrogation. Voici un exemple d'URL contenant une chaîne de requête:
http: //fr.search.yahoo.com/search/fr?p=Active+Server+Pages

Dans cet exemple, la chaîne de requête contient une variable nommée p dont la
valeur est "Active Server Pages". Si vous entrez cette chaîne dans le champ
d'adresse de votre navigateur, celui-ci affichera toutes les pages de Yahoo! en
rapport avec l'ASP.
Les chaînes de requête servent à transmettre des informations du serveur au
navigateur. En général, l'utilisateur ne saisit pas directement une chaîne de requête
dans le champ d'adresse U navigateur. En revanche, il est courant de créer dans une
page un lien contenant une chaîne de requête.
Faire un choix
Les chaînes de requête peuvent permettre à l'utilisateur de faire un choix. Ainsi, on
client pourra cliquer sur différentes catégories de produits pour en afficher la liste.
La page ASP du Listing 3.11 permet au visiteur de faire son choix entre deux
catégories de produits: Les pommes Reine des reinettes, et les pommes Golden
delicious.
LISTING 3.11 Choix de pommes

ASP JSP PHP

01. <HTML> 01. <HTML> 01. <HTML>


02. <HEAD><TITLE>Pomme 02. <HEAD><TITLE>Pomme 02. <HEAD><TITLE>Pomme
s</TITLE></HEAD> s</TITLE></HEAD> s</TITLE></HEAD>
03. <BODY> 03. <BODY> 03. <BODY>
04. veuillez choisir un type de 04. veuillez choisir un type de 04. veuillez choisir un type de
pomme&nbsp; pomme&nbsp; pomme&nbsp;
05. <p><a 05. <p><a 05. <p><a
href="page2.asp?pomme href="page2.jsp?pomme= href="page2.php?pomme
=reinette">Reine des reinette">Reine des =reinette">Reine des
reinettes</a> reinettes</a> reinettes</a>
06. <p><a 06. <p><a 06. <p><a
href="page2.asp?pomme href="page2.jsp?pomme= href="page2.php?pomme
=golden">Golden golden">Golden =golden">Golden
delicious</a> delicious</a> delicious</a>
07. </BODY> 07. </BODY> 07. </BODY>
08. </HTML> 08. </HTML> 08. </HTML>

Analyse
Les pages html du Listing 3.11 comprennent deux liens hypertexte vers une
page nommée page2.asp et respectivement page2.jsp ou page2.php. Le premier
lien passe une chaîne de requête nommée pomme avec la valeur reinette. La
seconde chaîne de requête se nomme également pomme sa valeur est golden. En
cliquant sur l'ou ou l'autre lien, le visiteur peut choisir le type de pomme à
afficher.
Répondre au choix
Dans la page serveur page2.xxx, il est possible de savoir sur quel lien
l'utilisateur à cliqué en faisant appel aux paramètres de requête. Le Listing 3.12
correspond à la page page2.xxx.
LISTING 3.12 : Utilisation d'une chaîne de requête

ASP JSP PHP

01. <HTML> 01. <HTML> 01. <HTML>


02. <HEAD><TITLE>Page 02. <HEAD><TITLE>Page 2 02. <HEAD><TITLE>Page 2
2 </TITLE></HEAD> </TITLE></HEAD> </TITLE></HEAD>
03. <BODY> 03. <BODY> 03. <BODY>
04. <% 04. <% 04. <?
05. pomme = 05. String pomme = 05. $pomme =
Request.OueryString("p request.getParameter("pom $HTTP_GET_VARS["pom
omme") me");%> me"];
06. Response.Write "Vous 06. <%= "Vous avez 06. print "Vous avez
avez s&eacute;lectionn&eacute; s&eacute;lectionn&eacute;
s&eacute;lectionn&eacut la vari&eacute;t&eacute; la vari&eacute;t&eacute; ".
e; la "+pomme $pomme
vari&eacute;t&eacute; " 07. %> 07. ?>
& pomme 08. </BODY> 08. </BODY>
07. %> 09. </HTML> 09. </HTML>
08. </BODY>
09. </HTML>

Analyse
ASP : Ligne 5, la collection QueryString de l'objet Request sert à récupérer le
contenu de la variable de chaîne de requête pomme. Le contenu de cette
variable est affecte a one variable locale VBScript, pomme.
JSP : Ligne 5, la méthode getParameter de l'objet request sert à récupérer le
contenu de la variable de chaîne de requête pomme. Le contenu de cette
variable est affecte a one variable locale Java de type chaîne (String), pomme.
Enfin, la valeur de cette variable est affichée ligne 6.
PHP : Ligne 5, la collection $http_GET_VARS de PHP sert à récupérer le
contenu de la variable de chaîne de requête pomme. Le contenu de cette
variable est affecte a une variable locale PHP, pomme.
ASP,JSP et PHP : Enfin, la valeur de cette variable est affichée ligne 6.
Passer plusieurs variables de chaîne de requête
Il est possible de passer plusieurs variables de chaîne de requête à l'aide d'une
seule chaîne de requête. Il suffit pour cela de séparer les variables les unes des
autres à l'aide de caractères &. Ainsi, la page ASP du Listing 3.13 passe deux
variables de chaîne de requête, fruit et variété.
LISTING 3.13 Passage de plusieurs variables de chaîne de requête

ASP JSP PHP

01. <HTML> 01. <HTML> 01. <HTML>


02. <HEAD><TITLE>Fruits 02. <HEAD><TITLE>Fruits<IT 02. <HEAD><TITLE>Fruits<ITI
<ITITLE></HEAD> ITLE></HEAD> TLE></HEAD>
03. <BODY> 03. <BODY> 03. <BODY>
04. S&eacute;lectionnez 04. S&eacute;lectionnez un 04. S&eacute;lectionnez un
un type de fruit type de fruit type de fruit
05. <p><a 05. <p><a 05. <p><a
href="page2b.asp?fruit href="page2b.jsp?fruit=poir href="page2b.php?fruit=poir
=poire&variete=crassa e&variete=crassane">Poir e&variete=crassane">Poire
ne">Poire passe- e passe-crassane </a> passe-crassane </a>
crassane </a> 06. <p><a 06. <p><a
06. <p><a href="page2b.jsp?fruit=po href="page2b.php>p?fruit=p
href="page2b.asp?fruit mme&variete=reinette">rei omme&variete=reinette">rei
=pomme&variete=rein ne des reinettes</a> ne des reinettes</a>
ette">reine des 07. <p><a 07. <p><a
reinettes</a> href="page2b.jsp?fruit=po href="page2b.php?fruit=po
07. <p><a mme&variete=golden">Po mme&variete=golden">Pom
href="page2b.asp?fruit mme golden delicious</a> me golden delicious</a>
=pomme&variete=gold 08. </BODY> 08. </BODY>
en">Pomme golden 09. </HTML> 09. </HTML>
delicious</a>
08. </BODY>
09. </HTML>

Analyse
Les liens hypertexte du Listing 3.14 contiennent des chaînes de requête
comprenant deux variables chacune: fruit et variété. Lorsque l'utilisateur clique
sur l'un de ces liens hypertexte, les deux variables de chaîne de requête sont
passées à la page page2b.xxx.
Accéder au variables de la chaîne de requête
Lorsque plusieurs variables de chaîne de requête sont envoyées à une page,
vous pouvez accéder à chacune d’entre elles par l'intermédiaire de la collection
QueryString. Le Listing 3.12 montre comment récupérer le contenu des deux
variables de chaîne de requête fruit et variété.
LISTING 3.14: Récupération de plusieurs variables de chaîne de requête

ASP JSP PHP


01. <HTML> 01. <HTML> 01. <HTML>
02. <HEAD><TITLE>Fruit 02. <HEAD><TITLE>Fruit 02. <HEAD><TITLE>Fruit
s&eacute;lectionn&eacute s&eacute;lectionn&eacute s&eacute;lectionn&eacute
;</TITLE></HEAD> ;</TITLE></HEAD> ;</TITLE></HEAD>
03. <BODY> 03. <BODY> 03. <BODY>
04. Vous avez choisi&nbsp; 04. Vous avez choisi&nbsp; 04. Vous avez choisi&nbsp;
05. <p>Fruit&nbsp: 05. <p>Fruit&nbsp: 05. <p>Fruit&nbsp: <? print
<%=Request.QueryString( <%=request.getParameter $fruit; ?>
"fruit")%> ("fruit")%> 06. <p>Vari&eacute;t&eacute;
ASP JSP PHP
06. <p>Vari&eacute;t&eacute; 06. <p>Vari&eacute;t&eacute; &nbsp; : <? print $variete;
&nbsp; : <%= &nbsp; : <%= ?>
Request.Querystring("vari request.getParameter("var 07. </BODY>
ete")%> iete")%> 08. </HTML>
07. </BODY> 07. </BODY>
08. </HTML> 08. </HTML>

Analyse
La ligne 5, les délimiteurs <%= et %> sont utilisés pour afficher la valeur de la
variable de chaîne de requête fruit. La ligne 6 affiche la valeur de la variable de
chaîne de requête type.
Passer des caractères spéciaux dans des chaînes de requête
Il n'est pas possible d'inclure directement des espaces ou d'autres caractères
spéciaux dans le nom ou la valeur d'une variable de chaîne de requête.
Supposons par exemple que vous souhaitiez passer la chaîne "reine des
reinettes" dans une variable de chaîne de requête. Vous pourriez être tenté de le
faire comme dans la page ASP du Listing 3.15.
LISTING 3.15: Chaîne de requête contenant des espaces

ASP JSP PHP

01. <HTML> 01. <HTML> 01. <HTML>


02. <HEAD><TITLE>Fruits</ 02. <HEAD><TITLE>Fruits</ 02. <HEAD><TITLE>Fruits</
TITLE></HEAD> TITLE></HEAD> TITLE></HEAD>
03. <BODY> 03. <BODY> 03. <BODY>
04. <a 04. <a 04. <a
href="page2b.asp?fruit="r href="page2b.jsp?fruit="rei href="page2b.php?fruit="r
eine des ne des eine des
reinettes">Pommes<la> reinettes">Pommes<la> reinettes">Pommes<la>
05. </BODY> 05. </BODY> 05. </BODY>
06. </HTML> 06. </HTML> 06. </HTML>

Analyse
La ligne 4 contient un lien hypertexte avec une variable de chaîne de requête
nommée fruit. Cependant, si vous cliquez sur ce lien, la valeur de la chaîne de
requête ne sera pas correctement passée à la page page2b.xxx . Sa valeur sera
coupée au niveau du premier espace.
L’encodage URL
Pour pouvoir passer une chaîne de requête comprenant des espaces ou des
caractères spéciaux (caractères accentues, en particulier), vous devez d'abord
coder la chaîne dans un "style URL". Lorsqu'une chaîne est ainsi codée, tous les
caractères posant problème sont remplacés ; les espaces, par exemple, sont
remplaces par des signes "+"
Pour coder de cette manière une chaîne de requête, utilisez la méthode
adaptée pour chaque technologie serveur. La chaîne "reine des reinettes" est
ainsi correctement codée avant d'être passée.
LISTING 3.16: Codage URL d'une chaîne de requête

ASP JSP PHP

01. <HTML> 01. <HTML> 01. <HTML>


02. <HEAD><TITLE>Fruits</TI 02. <HEAD><TITLE>Fruits</TI 02. <HEAD><TITLE>Fruits
TLE></HEAD> TLE></HEAD> </TITLE></HEAD>
03. <BODY> 03. <BODY> 03. <BODY>
04. <% 04. <% 04. <?
05. valeur = "reine des 05. String valeur = "reine des 05. $valeur = "reine des
reinettes" reinettes" reinettes";
06. valeur = 06. valeur = 06. valeur =
Server.URLEncode(valeur) java.net.URLEncoder.enco urlencode($valeur);
07. %> de(valeur); 07. ?>
08. <a 07. %> 08. <a
href="page2b.asp?fruit=<% 08. <a href="page2b.php?fruit
=valeur%>">Pommes</a> href="page2b.jsp?fruit=<% =<? print
09. </BODY> =valeur%>">Pommes</a> $valeur ; ?>">Pommes
10. </HTML> 09. </BODY> </a>
10. </HTML> 09. </BODY>
10. </HTML>

Analyse
Dans le Listing 3.16, la chaîne "reine des reinettes" est codée avant d’être
ajoutée a la même de requête. Ligne 5, la chaîne reine des reinettes" est
affectée à la variable valeur. Ligne 6, la valeur de la variable est codée à l’aide
de la méthode adapté à chaque technologies serveur :
ASP : utilise la méthode URLEncode de l'objet Serveur ;
JSP : utilise la méthode encode de l’objet URLEncoder qui se trouve
dans la bibliothèque java.net ;
PHP : utilise la fonction urlencode() ;
Ligne 8, la variable est ajoutée à la chaîne de requête.

Utiliser les Formulaires


Présentation
Pour permettre aux visiteurs de s'enregistrer ou de s'abonner à votre site Web, de
remplir un questionnaire ou de saisir leur numéro de carte bancaire, vous devez
faire appel aux formulaires HTML. Pour récupérer les informations entrées par
l'utilisateur dans le formulaire HTML, il y à des fonctionnalités disponibles dans
chaque technologie serveur.
Un formulaire simple
Ainsi, la page du Listing 3.17 contient on formulaire HTML simple demandant a
l'utilisateur de saisir son prénom.
LISTING 3.17 : Saisie du prénom jsp, php

01. <HTML>
02. <HEAD><TITLE>Saisie du
pr&eacute;nom<ITITLE></HEAD>
03. <BODY>
04. Veuillez entrer votre pr&eacute;nom
05. <FORM method="post"
action="page2d.xxx">
06. <INPUT name="prenom"
type="text">
07. <INPUT type="submit" value="OK">
08. </FORM>
09. </BODY>
</HTML>

Analyse
Le Listing 3.17 contient on formulaire HTML simple comprenant on champ
nommé "prénom". La Ligne 6 affiche ce champ ; la ligne 7 affiche on bouton
d'envoi comprenant la mention "OK".
Réponse personalisée
Lorsqu'on utilisateur saisit son prénom et qu'il clique sur le bouton OK, les
données du formulaire sont envoyées à la page page2d.xxx. Dans cette page, la
valeur du champ prénom pourra être obtenue en faisant appel à la collection
Form de l'objet Request. Le Listing 3.18 montre comment utiliser cette
collection.
LISTING 3.18: Utilisation du contenu d'un champ de formulaire

ASP JSP PHP


01. <html> 01. <html> 01. <html>
02. <head> 02. <head> 02. <head>
03. <title>Affichage du 03. <title>Affichage du 03. <title>Affichage du
pr&eacute;nom</title> pr&eacute;nom</title> pr&eacute;nom</title>
04. </head> 04. </head> 04. </head>
05. <body> 05. <body> 05. <body>
06. <% 06. <% String prenom= 06. <? $prenom =
prenom=Request.Form("pr request.getParameter("p $HTTP_POST_VARS['pr
enom"); %> renom"); %> enom']; ?>
07. Bonjour <%= prenom %> et 07. Bonjour <%= prenom 07. Bonjour <? print
bienvenue sur notre site %> et bienvenue sur $prenom ?> et
08. </body> notre site bienvenue sur notre site
09. </html> 08. </body> 08. </body>
09. </html> 09. </html>
Analyse
En Dreamweaver, le champ de formulaire est récupéré du menu Fenêtre-
>Liaison->Variable de demande ou de formulaire (les nom varient en fonction
de la solution serveur choisie.
ASP : utilise la collection Form de l’objet Request ;
JSP : utilise la methode getParameter de l’objet request ;
PHP : utilise le tableau $HTTP_POST_VARS ;
Génération d’une réponse adapté
LISTING 3.19: Appréciation du site par les visiteurs

ASP JSP PHP

01. <html> 01. <html> 01. <html>


02. <head> 02. <head> 02. <head>
03. <title>Votre 03. <title>Votre 03. <title>Votre
appr&eacute;ciation</title appr&eacute;ciation</title appr&eacute;ciation</title
> > >
04. </head> 04. </head> 04. </head>
05. <body> 05. <body> 05. <body>
06. <% note = 06. <% int note = 06. <? $note =
cINT(Request.Form("note Integer.parseInt(request.g intval($HTTP_POST_VA
")) %> etParameter("note")); %> RS['note']); ?>
07. Merci d'avoir 07. Merci d'avoir 07. Merci d'avoir
particip&eacute; &agrave; particip&eacute; &agrave; particip&eacute; &agrave;
ce sondage<p> ce sondage<p> ce sondage<p>
08. <% IF note < 3 THEN 08. <% if(note < 3){ %> 08. <? if($note < 3){ ?>
09. Response.Write "Merci 09. <%= "Merci pour votre 09. <? print "Merci pour
pour votre confiance !" confiance !" %> votre confiance !" ; ?>
10. ELSE 10. <% }else{ %> 10. <% }else{ %>
11. Response.Write 11. <%= "Comment ça, 11. <? print "Comment ça,
"Comment ça, vous vous n'aimez vraiment vous n'aimez vraiment
n'aimez vraiment pas pas notre magasin ?" %> pas notre magasin ?" ; ?>
notre magasin ?" 12. <% } %></p> 12. <? } ?></p>
12. END IF %></p> 13. </body> 13. </body>
13. </body> 14. </html> 14. </html>
14. </html>

Analyse
La page récupère la valeur du bouton radio sélectionné par le visiteur. Ligne 6
la valeur du bouton est extraite à l’aide de la méthode adapté de chaque
technologie et la valeur qui est transmise en tant que chaîne de caractère est
convertie en nombre entier.
Lignes 7 à 12 affichent un message parmi deux en fonction de l’appréciation
reçue de la part du répondant.
Vérifier que tous les champs sont remplis
Listing 3.20: Formulaire de carte bancaire

01. <HTML>
02. <HEAD><TITLE>Formulaire de carte
bancaire</TITLE></HEAD>
03. <BODY>
04. <b>Veuillez compl&eacute;ter les
champs ci-dessous&nbsp;:</b>
05. <FORM METHOD="POST"
ACTION="page2f.xxx">
06. <p>Nom
07. <br><INPUT name="client"
SIZE="30">
08. <p>Num&eacute;ro de carte bancaire
09. <br><INPUT name="numerocarte"
size="15">
10. <p>Date d'expiration
11. <br><INPuT name="expirationcart"
size="15">
12. <p><INPUT type="submit"
value="OK">
13. </FORM>
14. </BODY>
15. </HTML>

Si le visiteur oublie d'entrer son nom, son numéro de carte bancaire ou sa date
d'expiration la commande ne pourra aboutir. Le Listing 3.21 montre comment une
page ASP peut vérifier qu'aucun champ n'est resté vide.
Des précautions suplémentaires
LISTING 3.21: Vérifier que tous les champs ont été remplis asp php

01. <%
02. SUB formulaireErreur( erreur
03. %>
04. <HTML>
05. <HEAD><TITLE>Erreur</TITLE></HEAD>
06. <BODY>
07. <% erreur %>
08. <FORM method="post" action="pagel.asp"><p>
09. <INPUT TYPE="submit" value="Retour">
10. </FORM>
11. </BODY>
12. </HTML>
13. <%
14. Response.End
15. END SUB
16. ' Extraction du contenu du formulaire
17. client=TRIM( Request.Form("client")
18. numerocarte=TRIM( Request.Form("numerocarte"))
19. expirationcarte=TRIM( Request.Form("expirationcarte"))
20. 'On verifie que tous les champs ont eté remplis
21. IF client="" THEN
22. formulaireErreur "Vous n'avez pas indique~ votre nom."
23. END IF
24. IF numerocarte = " " THEN
25. formulaireErreur "Vous n'avez pas indiqué votre numéro de carte bancaire"
26. END IF
27. IF expirationcarte = " " THEN
28. formulaireErreur "Vous n'avez pas indiqué la date d'expiration de votre carte."
29. END IF
30. %>
31. <HTML>
32. <HEAD><TITLE>Merci</TITLE></HEAD>
33. <BODY>
34. Vos informations de carte bancaire ont bien été enregistrées.
35. </BODY>
36. </HTML>

Analyse
La page ASP do Listing 3.21 affiche on message d'erreur Si l'utilisateur ne
remplit pas tous les champs du formulaire. Les lignes 17 A 19 servent à extraire
le contenu des champs de formulaire à l'aide de la collection Form et à l'affecter
à des variables locales.
Notez que la fonction VBScript TRIM() est appliquée au contenu de chacun
des champs. Cette fonction permet de supprimer les espaces se trouvant au
début et a" la fin d'une chaîne (les navigateurs ont tendance à ajouter des
espaces supplémentaires à chaque champ de formulaire lors de son envoi).
Dans les lignes 21 à 29, chaque variable est comparée à one chaîne de longueur
nulle. Si l'une des variables est vide, un sous-programme nomme
formulaireErreur est appelé, et un message d'erreur est passe à ce sous-
programme.
Le sous-programme des lignes 2 a 15 affiche one page HTML présentant le
message d'erreur qui lui a été passe. Il contient également on formulaire
affichant on bouton renvoyant l'utilisateur sur la page précédente (celle do
Listing 3.21).
Notez que la méthode End de l'objet Response est appelée à la dernière ligne du
sous-programme formulaireErreur (ligne 14). Cette méthode arrête l'exécution
du script ; ainsi, seul le message d'erreur est affiche.
Si le sous-programme formulaireErreur n’est pas appelé, la page HTML des
lignes 31 à 36 est affichée. Cette page ne s'affiche que si l’utilisateur a saisi
toutes les informations demandées ; elle confirme que les informations de carte
bancaire ont été enregistrées.
Nouvel affichage du contenu des champs de formulaire
Il n'y a rien de plus énervant que de remplir un formulaire sur un site Web et de
voir s'afficher ensuite un message d'erreur qui oblige à saisir de nouveau tout le
contenu des champs. Lorsqu’un utilisateur omet de remplir un champ, il est
préférable d'afficher à nouveau toutes les informations qu'il a saisies. Pour ce
faire, vous devrez renvoyer au navigateur les données saisies dans les champs
do formulaire initial.
Vous avez créé ci-dessus un formulaire HTML contenant trois champs de
formulaire: un
pour le nom do client, un pour le numéro de sa carte bancaire et un pour la date
d'expiration de sa carte. Si un client entre son numéro de carte bancaire et sa
date d’expiration, mais qu'il omet de saisir son nom, le message d'erreur qui
s'affiche comprend un bouton renvoyant vers le formulaire initial. Lorsque ce
formulaire est de nouveau affiché, les informations de numéro et de date
d'expiration de la carte bancaire auront disparu.
Pour résoudre ce problème, il est nécessaire de modifier les deux pages dont il a
été question ci-dessus. Vous devrez d'abord modifier le sous-programme
formulaireErreur pour qu'il renvoie toutes les informations que le client a entré
dans les champs du formulaire (voir Listing 3.22).
LISTING 3.22 Passer les champs de formulaires à la page précédente

01. <%
02. SUB formulaireErreur( erreur
03. %>
04. <HTML>
05. <HEAD><TITLE>Erreur</TITLE></HEAD>
06. <BODY>
07. <% erreur %>
08. <FORM method="post" action="pagel.asp"><p>
09. <% FOR EACH item IN Request.Form %>
10. <INPUT name="<%=item%> type="hidden"
11. value="<%=Server.HTMLEncode( Request.Form( item ) )%>">
12. <% NEXT %>
13. <INPUT TYPE="submit" value="Retour">
14. </FORM>
15. </BODY>
16. </HTML>
17. <%
18. Response.End
19. END SUB
20. ' Extraction du contenu du formulaire
21. client=TRIM( Request.Form("client")
22. numerocarte=TRIM( Request.Form("numerocarte"))
23. expirationcarte=TRIM( Request.Form("expirationcarte"))
24. 'On verifie que tous les champs ont eté remplis
25. IF client="" THEN
26. formulaireErreur "Vous n'avez pas indique~ votre nom."
27. END IF
28. IF numerocarte = " " THEN
29. formulaireErreur "Vous n'avez pas indiqué votre numéro de carte bancaire"
30. END IF
31. IF expirationcarte = " " THEN
32. formulaireErreur "Vous n'avez pas indiqué la date d'expiration de votre carte."
33. END IF
34. %>
35. <HTML>
36. <HEAD><TITLE>Merci</TITLE></HEAD>
37. <BODY>
38. Vos informations de carte bancaire ont bien été enregistrées.
39. </BODY>
40. </HTML>

Analyse
La page ASP do Listing 3.22 a été modifiée pour renvoyer toutes les données
que l'utilisateur saisies dans les champs de formulaire. Les lignes 9 à 12
contiennent un script qui crée le champ de formulaire masqué pour chacun des
éléments de la collection Form. Lorsqu'un utilisateur clique sur te bouton OK,
toutes tes informations initiales du formulaire sont correctement renvoyées à la
page pagel.asp.
Notez que la méthode HTMLEncode() de l'objet Serveur est employée pour
coder le contenu des attributs VALUE des champs de formulaire masques. Ce
codage est indispensable pour éviter les erreurs qui se produiraient si
l'utilisateur entrait des guillemets ou d'autres caractères spéciaux dans un champ
de formulaire.
La page pagel.asp doit, elle aussi, être modifiée pour afficher toutes les données
initiales du formulaire. Pour cela, une valeur par défaut est affectée à chacun
des champs do formulaire HTML. Le Listing 3.23 montre la version modifiée
de la page pagel.asp.
LISTING 3.23: Formulaire de carte bancaire modifié

01. <%
02. client = TRIM(Request.Form("client"))
03. numerocarte = TRIM(Request.Form("numerocarte"))
04. expirationcarte = TRIM(Request.Form("expirationcarte"))
05. %>
06. <HTML>
07. <HEAD><TITLE>Formulaire de carte bancaire</TITLE></HEAD>
08. <BODY>
09. <b>Veuillez compl&eacute;ter les champs ci-dessous&nbsp;:</b>
10. <FORM METHOD="POST" ACTION="page2.asp">
11. <p>Nom
12. <br><INPUT name="client" SIZE="30"
13. value="<%=Server.HTMLEnCOde(client)%>">
14. <p>Num&eacute;ro de carte bancaire
15. <br><INPUT name="numerocarte" size="15"
16. <value="<%=Server.HTMLEncode(numerocarte)%>">
17. <p>Date d'expiration
18. <br><INPUT name="expirationcarte" size="15"
19. value="<%=Server.HTMLEncode(expirationcarte)%>">
20. <p><INPUT type="submit" value="OK">
21. </FORM>
22. </BODY>
23. </HTML>

Analyse
La page ASP du Listing 3.23 récupère les données initialement saisies dans les
champs formulaire et les affiche à nouveau en utilisant l'attribut VALUE de
chaque élément de formulaire. Dans les lignes 1 à 5, les données initiales du
formulaire sont obtenues à partir de page page2 asp, qui les a passées à l'aide
des champs de formulaire masqués de page2.asp.
Dans les lignes 10 à 21, les champs de formulaire sont affichés. Notez l'ajout de
l’attribut VALUE à chaque champ de formulaire ; cet attribut sert A afficher les
données initialement saisies dans le formulaire.
Obtention de chaînes de requête et de variables de formulaire
Vous avez vu ci-dessus comment utiliser la collection QueryString pour obtenir
des variables de chaînes de requête et la collection Form pour obtenir des
variables de formulaire HTML. Il s'agit dans les deux cas de collections de
l'objet Request.
Dans certaines situations, on cherche à obtenir une variable passée soit en tant
que variable de chaîne de requête, soit en tant que variable de formulaire. Il est
possible d'effectuer une recherche portant sur toutes les collections de l'objet
Request en ne spécifiant aucune collection particulière. Ainsi, la page ASP du
Listing 3.24 contient à la fois un formulaire HTML et un lien hypertexte
contenant une chaîne de requête.
LISTING 3.24: Formulaire HTML et chaîne de requête

01. <HTML>
02. <HEAD><TITLE>Formulaire et chaine de requete<~TITLE></HEAD>
03. <BODY>
04. <a href="page2.asp?var=bonjour">cliquez ici<Ia>
05. <p>
06. <FORM method="POST" ACTION="page2.asp">
07. <INPUT name--"var" size="10">
08. <INPUT type="submit" value="OK">
09. </FORM>
10. </BODY>
11. </HTML>

Analyse
Le lien hypertexte et le formulaire HTML se réfèrent tous deux à la même page,
page2.asp.
Tous deux contiennent également une variable du même nom, var. Lorsque le
visiteur clique sur le lien, la variable var est passée à la page page2.asp avec la
valeur "bonjour"
Lorsque le formulaire est envoyé, le texte saisi par l'utilisateur dans le champ de
formulaire var est passé à la page page2.asp.
Dans la page page2.asp, vous pouvez ensuite récupérer le contenu de la variable
var qu'il ai été passé à l'aide d'une chaîne de requête ou d'un formulaire HTML.
Le Listing 3.25 montre comment récupérer le contenu de la variable quelle que
soit la manière dont son contenu est passé.
LISTING 3.25 Obtention d'une chaîne de requête ou d’une variable de formulaire

01. <HTML>
02. <HEAD><TITLE>Form and Query String</TITLE></HEAD>
03. <BODY>
04. <%
05. myvar = Request("myvar")
06. Response.Write myvar
07. %>
08. </BODY>
09. </HTML>

Analyse
Ligne 5, la variable var est obtenue à l'aide de l'objet Request. La valeur de var
est affichée avec la ligne 6.
Aucune collection de l'objet Request n'ayant été spécifiée ligne 5, la recherche
de l'élément myvar porte sur toutes les collections de l'objet Request (y compris
les collections QueryString et Form). La recherche dans les collections
s'effectue dans l'ordre suivant:
1. QueryString
2. Form
3. Cookies
4. ClientCertificate
5. ServerVariables
Plusieurs collections comprennent une variable du même nom, l'objet Request
renverra la variable provenant de la première collection où la variable a été trouvée.
Info
La collection ServerVariables est traitée ci-dessous, et a collection Cookies dans
le prochain chapitre. La collection ClientCertificate dépasse quant à elle le cadre
de ce cours
Variables de serveur
La dernière partie de ce chapitre est consacrée à la collection ServerVariables.
Cette collection comprend un assortiment de variables représentant les en-têtes de
navigateur et 1es propriétés des serveurs Web. Vous apprendrez à utiliser la
collection ServerVariables pour déterminer le nom de la page ASP courante, le
nom de la page précédemment visitée par l'internaute, l'adresse IP de l'internaute
ainsi que le type de navigateur qu'il utilise.
Obtenir du nom de Ia page en cours
La collection ServerVariables comprend une variable nommée SCRIPT_NAME
qui représente le nom de la page ASP courante. Cette variable renvoie le chemin
virtuel de la page sur le serveur Web. Ainsi, le script du Listing 3.26 affiche son
propre nom.
LISTING 3.26: La variable de serveur SCRIPT_NAME

01. <HTML>
02. <HEAD><TITLE>Nom de la page</TITLE></HEAD>
03. <BODY>
04. Le nom de cette page est
05. <%= Request.ServerVariables("SCRIPT_NAME")%>
06. </BODY>
07. </HTML>

Analyse
La page du Listing 3.26 utilise la commande SCRIPT_NAME à la ligne 5
pour renvoyer le nom et le chemin de la page. Ainsi, si le nom physique
complet de la page est d:\inetpub\wwwroot\pagesweb\pageweb.asp, la
variable SCRIPT_NAME renverra le chemin virtuel /pagesweb/pageweb.
asp.
La variable de serveur SCRIPT_NAME renvoie le chemin virtuel de la page
courante et non sur chemin physique. Pour renvoyer le chemin physique
d'une page, il existe deux moyens qu consistent soit à employer la méthode
MapPath() de l'objet Server pour transformer le chemin virtuel en chemin
physique, soit à faire appel à la variable de serveur PATH_TRANSLATED.
Le script du Listing 3.27 montre l'utilisation de ces deux moyens pour
obtenir le chemin physique de la page courante.
LISTING 3.27: Obtention du chemin physique

01. <HTML>
02. <HEAD><TITLE>Nom de la page<~TITLE></HEAD>
03. <BODY>
04. Le nom de cette page est
05. <%
06. ' Renvoi du chemin physique avec Mappath()
07. chemin = Request.Servervariables("SCRIPT_NAME")
08. Response.Write Server.MapPath(chemin)
09. %>
10. <HR>
11. <%
12. Renvoi du chemin physique avec PATH_TRANSLATED
13. Response.Write Request.Servervariables( "PATH_TRANSLATED"
14. %>
15. <IBODY>
16. </HTML>

Analyse
Lignes 6 à 8, le chemin physique est renvoyé à l'aide de la méthode MapPath()
de l'objet Serveur. Ligne 7, le chemin virtuel de la page courante est obtenu à
1'aide de la variable de serveur SCRIPT_NAME; ligne 8, le chemin virtuel est
transformé en chemin physique et affiché.
Lignes 12 et 13, le chemin physique de la page courante est obtenu à partir de la
collection ServerVariables à l'aide de la variable de serveur "PATH
TRANSLATED".
La variable de serveur SCRIPT_NAME est utile lors de la création de sous-
programmes et de fonctions qui doivent être utilisées sur différentes pages.
Ainsi, vous souhaiterez peut-être réer un formulaire d'erreur standard qui
renvoie à la même page. En utilisant la variable de serveur SCRIPT_NAME
dans ce formulaire, celui-ci pourra être rendu indépendant de la page.
Identifier la dernière page visitée
La collection ServerVariables peut être utilisée pour renvoyer la valeur de l'en-
tête REFERER du navigateur. L'en-tête REFERER contient le nom de la page à
partir de laquelle le visiteur accédé à la page courante. II peut s'agir d'une page
de votre propre site Web ou de toute autre page d'Internet. La page ASP du
Listing 3.28 affiche la valeur de l'en-tête REFERER.
LISTING 3.28: Obtention de l'en-tête REFERER

01. <HTML>
02. <HEAD><TITLE>en-tête REFERER</TITLE></HEAD>
03. <BODY>
04. <% referrer=Request.Servervariables( "HTTP~REFERER" ) %>
05. Vous venez de la page <%=referer%>
06. </BODY>
07. </HTML>

La variable REFERER n'aura aucune valeur si le visiteur a saisi directement


l'adresse de la page dans le champ d'adresse de son navigateur. Par ailleurs, certains
navigateurs anciens r prennent pas en charge l'en-tête REFERER.
L'en-tête REFERER est utile pour savoir d'où viennent les visiteurs de votre site.
Cela peut par exemple vous permettre d'afficher un message spécifique aux
visiteurs provenant du Site Yahoo!
Identifier I'adresse Internet du visiteur
La variable de serveur REMOTE_ADDR permet d'obtenir l'adresse IP d'un
visiteur. Cette information peut être utilisée pour savoir à partir de quels
fournisseurs d'accès se connectent l’internautes. REMOTE ADD peut aussi limiter
l'accès de vos pages à certains visiteurs.
La page ASP du Listing 3.29 utilise la variable REMOTE_ADDR pour afficher
l'adresse IP du visiteur.
LISTING 3.29: Obtention de 1'adresse IP d'un visiteur

01. <HTML>
02. <HEAD><TITLE>Addresse IP</TITLE><~HEAD>
03. <BODY>
04. <% IP = Request.ServerVariables("REMOTE_ADDR") %>
05. Votre adresse IP est <%=IP%>
06. </BODY>
07. </HTML>

Info
Il n’est pas possible d'utiliser l'adresse IP d'un visiteur pour suivre ses
déplacement sur votre site. En effet, de nombreux fournisseurs d'accès
attribuent plusieurs adresse. P A un seul utilisateur. De ce fait, I'adresse IP du
visiteur peut changer chaque fois qu' accède à une nouvelle page de votre site.

Identifier le navigateur du visiteur


II peut être très utile de connaître le type de navigateur utilisé par le visiteur. Ainsi,
certaines balises HMTL telles que <MARQUEE> ou <IFRAME> sont reconnues
par Internet Explorer, mais pas par Netscape Navigator. Le fait d'identifier le
navigateur employé par votre visiteur vous permet ensuite de lui faire parvenir
différentes pages selon qu'il utilise Internet Explorer ou Netscape Navigator.
Pour identifier le type de navigateur utilisé, faites appel a la variable de serveur
USER_AGENT La page ASP du Listing 3.30 montre comment est utilisée cette
variable.
LISTING 3.30 Utilisée de variable USER_AGENT

01. <HTML>
02. <HEAD><TITLE>Browser Type</TITLE></HEAD>
03. <BODY>
04. <% Navigateur = Request.ServerVariables( "HTTP_USER_AGENT" ) %>
05. Vous utilisez Te type de navigateur suivant: <%= Navigateur %>
06. </BODY>
07. </HTML>
Dans le cas d'un visiteur utilisant Internet Explorer 5 pour Windows NT, la chaîne
renvoyée par l'en-tête USER_AGENT sera la suivante
Mozilla.4.0 (compatible; MSIE 5.0; Windows NT; DigExt)
Netscape Navigator 3.04 pour Windows NT renverra la valeur suivante
Mozilla/3.04 (WinNT; I) Netscape Navigator 4.0 pour Windows NT renverra la
valeur suivante Mozilla/4.07 (WinNT; I NaY) sufix, le navigateur Opera version
3.51 renverra la valeur Mozilla/4.0 (compatible; Opera l3.0; Windows NT 4.0) 3.51
En résumé
Présentation
Dans ce chapitre, vous avez fait connaissance avec les deux fonctionnalités les plus
importantes des pages serveur la Réponse et la Requête. Vous avez appris à utiliser
ces objets pour interagir avec les visiteurs de votre site Web.
Dans la première partie, vous avez appris à afficher du contenu dans le navigateur
du visiteur et à manier la méthode Write de l'objet Response ainsi que les
délimiteurs de script <%= %>. Vous avez également appris à utiliser la méthode
End de l'objet Response pour arrêter exécution d'un script ASP
Ensuite, nous nous sommes intéressés aux collections liées aux requêtes, celles qui
captent les chaînes de requête, les éléments de formulaire HTML et variables
serveur qui permet d'obtenir les en-têtes de navigateur et les propriétés du serveur.
Questions/ Réponses
Q Y a-t-il une limite à la quantité de données qu'il est possible de passer a
l'aide d’une chaîne de requête ou d'une variable de formulaire?
R La réponse à cette question dépend du navigateur. Les limites imposées par
Netscape et par Internet Explorer diffèrent.
D'une manière générale, évitez de créer des chaînes de requête d'une longueur
supérieure à 1 000 caractères. Souvenez-vous également que le codage des chaînes
de caractères peut considérablement augmenter leur longueur; en effet, lors du
codage certains caractères sont convertis en plusieurs caractères. Ainsi, le point est
converti en une suite de trois caractères (%2E).
Les variables de formulaire permettent de passer des quantités d'informations
beaucoup plus importantes. Netscape Navigator permet de faire passer jusqu'à
environ 30000 caractères dans une seule variable de formulaire ; dans Internet
Explorer il n'y apparemment pas de limite à la longueur de la variable.
Q Est-il nécessaire de toujours spécifier une collection particulière lorsqu'on
utilise 1'objet Request?
R Lorsqu'on extrait one variable de formulaire nommée myvar de l'objet
Request, on peut employer au choix Request.Form ("myvar") ou
Request("myvar"). Lorsqu'on extrait une variable de chaîne de requête nommée
var, on peut employer au choix Request.QueryString("myvar") ou
Request("myvar").
Microsoft recommande de toujours spécifier la collection lors de l'extraction d'on
variable de l'objet Request. Lorsque vous spécifiez une collection particulière, la
recherche n'aura besoin de s'appliquer qu'à cette collection et non à toutes les autre.
Cependant, en pratique les bénéfices en termes de performances sont négligeables.
Si vous préférez faire les choses dans les règles, spécifiez systématiquement la
collection; vous estes plus paresseux, vous pouvez omettre le nom de la collection
sans que cela a beaucoup de conséquences.
Atelier
Presentation
Les questions et les exercices ci-dessous sont destinés à tester vos connaissances
sur les informations traitées dans ce chapitre. Vous trouverez les réponses dans
l’Annexe "Réponses aux questions".
Testez vos connaissances
1. Existe-t-il une différence entre l'utilisation de la méthode Write de l'objet
Response d’une part et celle des délimiteurs <%= et %> d'autre part pour
envoyer du contenu au navigateur?
2. La page ASP ci-dessous passe la variable de chaîne de requête var qui a la
valeur Active Server Pages. Cependant, le script contient une erreur qui
l'empêche de fonctionner correctement. Saurez-vous le corriger?
<html>
<head><title>Script à corriger</title></head> <body>
<%
var = "Active Server Pages"
%>
<a href=page2.asp?var=<%=var%>">cliquez ici</a> </body>
</html>
3. Comment faire afficher au navigateur la chaîne "Elle lisait "La Chartreuse
de Parme" en utilisant la methode Write de l'objet Response ?
4. Comment faire en sorte qu'un script affiche toutes les variables de la
collection Form de l'objet Request?
Exercice
Créez une page ASP contenant on formulaire HTML permettant de saisir des
informations sur un produit (nommez cette page infosproduit.asp). Le formulaire
HTML contiendra deux champs de formulaire nommes nomproduit et prixproduit.
Le contenu du formulaire doit être envoyé à une page nommée infosproduits.asp.
Créez ensuite un script ASP dans la page infosproduit2.asp qui vérifie que les
champs nomproduit et prixproduit ont tous deux une valeur. Si l'un ou l'autre de ces
champs est vide, le formulaire HTML permettra de revenir à la page
infosproduits.asp (ce formulaire rendra les informations initialement saisies dans le
premier formulaire). Dans le cas contraire, affichez le message "Les informations
produit ont bien été enregistrées.".
Annexe- Installation de EasyPHP et premiers pas
en PHP1
Installer EasyPHP
• Télécharger EasyPHP sur le site www.easyphp.org
• Double cliquer sur l'executable téléchargé
• Sélectionner le répertoire d'installation et suivre la procédure
Lancer EasyPHP
On ne peut pas à proprement parler du lancement d'EasyPHP, il s'agit en fait de la
mise en route du serveur Apache et de MySQL. A l'installation, un raccourci vers
EasyPHP est créé dans le répertoire "Démarrer/Programmes/EasyPHP". Une fois
EasyPHP lancé, une icone se place dans la barre des tâches à coté de l'horloge. Un
clic droit permet d'accéder à différents menus :
• Fichier Log : renvoie aux erreurs générées par Apache et MySQL
• Configuration : donne accès aux différentes configurations d'EasyPHP
• Administration : ouvre la page d'administration des alias et du répertoire
des bases de données.
• Web local : ouvre le web local
• Démarrer/Arrêter : démarre/arrête Apache et MySQL
• Redémarrer : redémarre Apache et MySQL
• Quitter : ferme EasyPHP
Utiliser le répertoire www ou les alias Pour que vos pages PHP soient
interprétées, il est impératif de placer vos fichiers dans le répertoire www ou dans
un alias que vous avez créé. Pour visualiser vos pages il vous suffit alors d'ouvrir le
"web local" ou d'accéder à vos alias via la page d'administration.
Vos premières pages en PHP
Il existe autant de façon de programmer en PHP qu'il existe d'éditeurs spécialisés
ou non (éditeurs html, coloration synthaxique, saisie semi-automatique ...). Nous
allons, dans cet exemple, utiliser un simple éditeur de texte (ex. : notepad).
• Ouvrez un nouveau fichier

1
Source : Manuel d’installation de EasyPHP.
• Tapez la structure d'une page HTML vierge :
<html>
<head>
<title>Ma première page en PHP</title>
</head>
<body>
</body>
</html>

• L'exemple consiste à afficher la date courante. Le code PHP s'intègre


directement au code HTML et commence par <? (ou <?php) et se termine
par ?>. Affichage de la date courante :
<html>
<head>
<title>Ma première page en PHP</title>
</head>
<body>
Date courante : <? print (Date("l F d, Y")); ?>
</body>
</html>

• Enregistrement de la page.
Créez un nouveau répertoire dans le répertoire www (ou dans un alias).
Enregistrez votre première page en PHP en lui donnant une des extensions
suivantes : php, php3, php4.
Ceci n'est pas une règle absolue, mais correspond à la configuration
d'EasyPHP. Il vous sera peut-être nécessaire, si vous choisissez d'héberger
vos pages chez un hébergeur dont la configuration est différente, de modifier
ces extensions.
Pour notre exemple on choisit une extension en .php : "date.php"
• Visualisation du résultat.
Pour fixer les esprits
A NE PAS FAIRE : aller dans le répertoire www (ou dans le répertoire d'un
alias) puis dans le répertoire correspondant à votre projet et double cliquer
sur votre page d'exemple. Vous obtiendrez à coup sûr une page d'erreur.
A FAIRE : lancer EasyPHP, ouvrir le "web local", sélectionner votre
répertoire de travail puis cliquer sur "date.php". Vous obtiendrez alors une
page qui vous affichera la date courante; par exemple : "Date courante :
Sunday May 13, 2001".
A vous maintenant de créer vos propres développements.
4
Chaptre

Mise en place d’un catalogue de


produits1
Sommaire
Objectifs
• Créer une base de données pour un magasin en ligne.
• Créer une table de produits pour stocker les informations sur les produits.
• Se connecter à une base de données à partir d'une page serveur
• Utiliser des scripts serveur pour ajouter de nouveaux produits a la base de
données
• Utiliser des scripts serveur pour modifier les informations existantes sur les
produits
Présentation
Dans ce chapitre, vous allez aborder la mise en place de votre magasin en ligne.
Vous verrez comment créer et gérer une gamme de produits à 1'aide de scripts
serveur, et apprendrez quelques techniques très utiles dans le contexte de la gestion
d'une base de données.

Création de la base de données du magasin


Présentation
La première étape de la création d’un magasin en ligne est la création d'une base de
données qui stockera toutes les informations concernant vos produits. Dans ce

1
Ce support de cours utilise et adapte le texte de S. Walther et J. Levine "E-Commerce,
programmation avec ASP3" (Campus Press, Paris, 2000) à d’autres technologies (PHP et JSP) qui
sont ouvertes et permettent aux étudiants de mettre en ligne des applications de e-commerce
gratuitement.
cours, nous ferons appel à des bases de données Access et MySQL, mais les scripts
serveur de ce chapitre et des chapitres suivants de ce cours devraient fonctionner
avec d'autres bases de données; il vous suffira le cas échéant d'y apporter quelques
modifications mineures. Vous pourrez par exemple les faire fonctionner très
facilement avec des bases de données SQL Server ou Oracle.
Attention
Microsoft Access n'est pas une base de données appropriée que pour tester un
site ou pour un site a faible fréquentation. Si vous pensez que votre site sera très
fréquenté vous devriez sans doute envisager de passer à Microsoft SQL Server
ou à MySQL.
La transformation d'une base de données Access en base de données SQL
Server se fait très facilement avec les outils de mise a jour fournis par
Microsoft. Ceux-ci sont livrés avec Access 2000. Si vous utilisez Access 97,
vous pouvez les télécharger a partir de I’adresse
http://officeupdate.microsoft.com/France /downloadcatalog/dtdaccess.asp
(faites défiler la page jusqu'en bas pour trouver le fichier).

Création d’une base de données Access


1. Suivez les étapes ci-dessous pour créer une nouvelle base de données
Access
2. Lancez Access en choisissant Démarrer, Programmes, Microsoft Access.
3. Dans la boite de dialogue qui apparaît, choisissez 1'option Nouvelle base
de données Access (voir Figure 4.1).
FIGURE 4.1 - Création d'une nouvelle base de données.
4. Dans la boite de dialogue Fichier Nouvelle base de données, nommez votre
base de données shopDB et enregistrez votre nouvelle base de données sur
votre disque dur (mémorisez l'endroit où vous l'avez enregistrée !).
Une fois ces étapes effectuées, vous disposez sur votre disque dur d'un nouveau
fichier nommé shopDB.mdb. Cette base de données vous servira à stocker des
informations sur vos produits, vos utilisateurs et vos commandes.
Création d’une base de données MySQL
La collection EasyPhp vien avec un program écrit en php qui permet de gérer les
bases de données en ligne. Le programme s’appelle phpMyAdmin et il est utilisé
par le service de gestion de bases de données disponible sur Internet chez free.fr.
Vous lancez ce programme avec le navigateur web en tapant :
http://localhost/mysql/ pour l’installation locale et http://sql.free.fr/ pour le service
disponible chez free.fr.
FIGURE 4.2 - Création d'une nouvelle base de données MySQL

Assurer l’accès à un service de bases de données accessible par des pages serveur
est ce qui distingue actuellement les fournisseurs d’applications (ASP –
Application Service Providers) des simples fournisseurs de services Internet (ISP –
Internet Service Providers)
Les ASP comme free.fr offrent une base de données à chaque utilisateur qui fait la
demande, la base portera le nom de l’utilisateur tel qu’enregistré avec le
fournisseur d’accès.

Création de la table Produits


Présentation
Si vous avez suivi les paragraphes précédents, vous avez créé une nouvelle base de
données Access et MySQL. Cependant, une base de données seule n’est pas d'une
grande utilité. Avant de pouvoir stocker des informations dans une base de
données, vous devez y ajouter une ou plusieurs tables de base de données.
Une table de base de données est structurée de la même façon qu'une feuille de
calcul ou qu'un livre de comptes. Elle contient une ou plusieurs lignes divisées en
une ou plusieurs donnes. Chaque colonne ou champ a un nom et sert à enregistrer
un type particulier d'information. Chaque ligne représente un enregistrement de
base de données.
Les champs de la table produits
Si les informations sur les produits du magasin en ligne étaient stockées dans une
table de base données nommée produits, cette table comprendra les huit colonnes
suivantes:
• id : Cette colonne contient un identificateur numérique unique pour chaque
produit de la table.
• nom : Cette colonne contient le nom du produit, par exemple Panier
Cadeau.
• prix : Cette colonne contient le prix du produit, par exemple 22,5 euros;
• image : Cette colonne contient le chemin de l'image du produit.
• categorie : Cette colonne contient la catégorie du produit. Dans le cas d'une
librairie en ligne, par exemple, cette colonne pourra contenir des valeurs
telles que roman policier ou bande dessinée.
• courtedesc : Cette colonne contient une description rapide du produit, par
exemple : ce panier cadeau contient une bouteille de sauternes et un foie
gras d'oie mi-cuit.
• longuedesc : Cette colonne contient une description complète du produit. Il
peut s'agir d'une page entière d'informations.
• statut : Cette colonne contient des informations sur le statut actuel du
produit. Elle pourra par exemple indiquer qu'un produit ne doit pas,
provisoirement, être proposé à la vente.
Créer la table produits avec Access
Pour créer la table produits, procédez comme suit
1. Si Access n'est pas ouvert, lancez-le en choisissant Démarrer, Programmes,
Microso-Access. Sélectionnez l'option permettant d'ouvrir un fichier
existant, puis sélectionnez la base de données shopDB.
2. Une fois la base de données shopDB ouverte, double-cliquez sur l'option
Créer une table en mode Création. La fenêtre de la Figure 4.3 apparaît.
FIGURE 4.3 Création d'une table en mode Création

3. Entrez les informations appropriés dans la table (laissez vide la colonne


Description).
4. Faites de la colonne id la clé primaire en sélectionnant cette colonne dans
la grille et en cliquant sur l'icône clé primaire (la clé).
5. Enregistrez la nouvelle table en cliquant sur l'icône d'enregistrement (la
disquette) et en choisissant le nom Produits.
FIGURE 4.4 - Création de la table produits en ligne sur MySQL

(avec phpMyAdmin )

Création de la table produits en ligne sur MySQL (avec phpMyAdmin )


CREATE TABLE `produits` (
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
`nom` TEXT NOT NULL,
`prix` FLOAT NOT NULL,
`image` TEXT NOT NULL,
`categorie` TEXT NOT NULL,
`courtdesc` BLOB NOT NULL,
`longuedesc` BLOB NOT NULL,
`statut` INT NOT NULL
);

Usages de la table
Vous venez de créer une table nommée produits. Chaque ligne de la table
représentera un produit particulier du magasin en ligne. Dans le reste de ce
chapitre, nous verrons comment utiliser des scripts serveur pour se connecter à la
base de données et modifier les informations qui y sont contenues.

Connexion à une base de données


Utilisation des DSN
Dans cette partie, vous verrez comment ouvrir une connexion avec une base de
données l’aide d'un script serveur. Cependant, avant de pouvoir ouvrir cette
connexion, vous devez fournir à la page serveur des informations sur
l'emplacement physique de la base de données. En d'autres termes, vous devez
fournir au script une méthode lui permettant de trouver la base de données sur le
disque dur. L'une des méthodes pour y parvenir est de faire appel à DSN (Data
Source Name).
Plusieurs types de DSN peuvent être crées. Si vous créez un DSN fichier (File
DSN), Les informations de connexion à la base de données seront stockées dans un
fichier. Si vous créez un DSN système (System DSN), les informations de
connexion seront stockées dans la base de registre de l'ordinateur.
Il n’y a pas de raison particulière d'utiliser un type de DSN plutôt qu'un autre; tous
deux fonctionnent parfaitement bien. Dans le cas présent, nous créerons un DSN
système.
Création d‘un d’un DSN pour un pilote de base de données (ODBC)
1. Ouvrez le panneau de configuration en choisissant Démarrer, Paramètres,
Panneau de configuration.
2. Double-cliquez sur l'icône source de données ODBC.
3. Sélectionnez 1'onglet DSN système, puis cliquez sur Ajouter
4. Sélectionnez Microsoft Access Driver et cliquez sur Terminer
5. Dans la boite de dialogue installation ODBC pour Microsoft Access,
cliquez sur le bouton sélectionner et retrouvez la base de données shopDB
sur votre disque dur (la base de données que vous avez créée plus haut).
Cliquez sur OK.
6. Dans le champ nom de la source de données, entrez accessShopDSN et
cliquez sur OK (voir Figure 4.4).
7. Cliquez sur OK pour refermer la boite de dialogue Administrateur de
source de données ODBC.
FIGURE 4.5 Creation d’un DSN en Windows.
Une fois ces opérations effectuées, vous avez crée un nouveau DSN système
nommé accessShopDSN. Vous n'avez besoin de créer qu'un seul DSN par base de
données utilisée dans vos scripts. Une fois le DSN créé, tous vos scripts peuvent
utiliser le même DSN pour se connecter à la base de données. Cependant, si vous
déplacez votre base de données, vous devrez mettre à jour le DSN en répétant la
procédure ci-dessus.

Info
La procédure permettant de créer un DSN pour une base do données SQL
Server Oracle ressemble beaucoup a celle décrite ci-dessus. Ainsi, pour créer un
DSN pour une base de données SQL Server, il vous suffira de choisir SQL
Server Driver à l’étape 4. Vous devrez également fournir un login et un mot de
passe SQL Server.
Connexion à une base de données (ODBC) en ASP
Maintenant que vous avez créé un DSN, vous pouvez l'utiliser pour ouvrir une
connexion avec la base de données. Pour créer une connexion, vous devez utiliser
un objet de données ActiveX ou ADO (ActiveX Data Object). L'ADO est une
collection d'objets permettant à des scripts ASP d'interagir avec des bases de
données. Il s'agit d'objets ActiveX pouvant être utilisés de la même façon que
n'importe quel composant ASP, par exemple le composant File Access.
Dans une page ASP, une connexion à une base de données est représentée par
l'objet ADO Connection. Le Listing 4.1 montre comment utiliser l'objet
Connection avec le DSN que nous venons de créer pour ouvrir une connexion avec
une base de données.
LISTING 4.1 Connexion à une base de données

<%
Set Con = Server.CreateObject("ADODB.Connection")
Con.Open "accessShopDSN"
%>

Analyse
Ce script ouvre une connexion avec [a base de données Access shopDB en
faisant appel au DSN accessShopDSN. Ligne 2, une instance de l'objet
Connection est créée. Ligne 3, la connexion à la base de données est ouverte
à l'aide de la méthode open de l'objet Connection.
Définition de la connexion à une base de données avec Dreamweaver en
utilisant le DSN
FIGURE 4.6 – Connexion à une base de données avec Dreamweaver

Usages de la connexion
Ouverture d'une connexion avec une base de données peut être comparée à
l'établissement d'une connexion avec un fournisseur d'accès Internet. Une fois la
connexion établie, des messages peuvent être envoyés dans les deux sens entre le
script ASP et la base de données. Vous pouvez par exemple passer un message du
script a la base de données pour lui indiquer d'insérer un nouvel enregistrement ou
de mettre a jour une information donnée. Dans les deux sections ci-dessous, vous
verrez comment passer ce type de message.

Ajout de produits à la table Produits


Présentation
Les bases de données nécessitent d'utiliser un langage spécifique. Pour obtenir
quelque chose d'une base de données, vous devez lui parler "dans sa langue". Le
langage de la plupart des bases de données modernes, est le SQL (pour Structured
Query Language langage de requête structurée).
Ainsi, pour ajouter un nouvel enregistrement a une table de base de données à
partir d'une page serveur, vous devez d'abord ouvrir une connexion avec la base de
données, puis envoyer à la base de données une chaîne lui demandant d'insérer un
nouvel enregistrement. Pour insérer un nouvel enregistrement dans une base de
données, on fait appel a l'instruction SQL INSERT INTO.
Scripts pour insérer un enregistrement
Le script du Listing 4.2 insère un nouvel enregistrement dans la table produits.
Listing 4.2: Insertion d'un nouvel enregistrement

ASP JSP PHP

01. <% 01. <% Driver 01. <?


02. Set conn = mysql_driver = 02. $conn =
Server.CreateObject("AD 02. (Driver)Class.forName("or mysql_pconnect('localhost
ODB.Connection") g.gjt.mm.mysql.Driver").ne ', 'root', '')
03. conn.Open "accessDSN" wInstance(); 03.
04. sqlString = "INSERT INTO 03. Connection conn = 04. sqlString = "INSERT INTO
produits (nom, prix ) " DriverManager.getConnec produits (nom, prix ) ".
05. "values ( 'Panier cadeau', tion("jdbc:mysql://localhost 05. "values ( 'Panier cadeau',
149.5 )" :3306/shopDB",”root”,””); 149.5 )"
06. Con.Execute sqlString 04. sqlString = "INSERT INTO 06. mysql_query($sqlString ,
07. Con.close produits (nom, prix ) "+ $conn);
08. %> 05. "values ( 'Panier cadeau', 07. ?>
149.5 )"
06. PreparedStatement
statement =
conn.prepareStatement(s
qlString);
07. statement.executeUpdate(
);
08. conn.close();

Analyse ASP
Ce script insère un nouveau produit dans la table produits. Les lignes 2 et 3
ouvrent une connexion avec la base de données. Ligne 5, une chaîne
contenant l'instruction SQL INSERT INTO est affectée à la variable
sqlString. L'instruction SQL est exécutée ligne 7. Ligne 8 enfin, la
connexion avec la base de données est refermée.
Analyse PHP
Ce script insère un nouveau produit dans la table produits. La ligne 2 ouvre
une connexion avec la base de données. Ligne 4, une chaîne contenant
l'instruction SQL INSERT INTO est affectée à la variable sqlString.
L'instruction SQL est exécutée ligne 6.
Analyse JSP
Ce script insère un nouveau produit dans la table produits. Les lignes 1 et 2
créent un nouvelle instance du pilot jdbc pour mysql. La 3 ouvrent une
connexion avec la base de données. Ligne 5, une chaîne contenant
l'instruction SQL INSERT INTO est affectée à la variable sqlString. Un
objet instruction SQL est crée sur la ligne 7 et exécuté sur la ligne 8. Ligne 9
enfin, la connexion avec la base de données est refermée.
La syntaxe de base de l'instruction SQL INSERT INTO est très simple
INSERT INTO nom_table ( liste_colonnes ) VALUES ( liste_valeurs).
nom_table permet d'indiquer a quelle table le nouvel enregistrement doit être ajouté
liste_colonnes permet d'indiquer la ou les colonnes de la table concernées, et
liste_valeurs la ou les valeurs à affecter à ces colonnes. Les colonnes et les valeurs
doivent être indiquées dans le même ordre et séparées par des virgules.
Lorsque vous insérez des chaînes de caractères, des dates ou des heures, les valeurs
doivent être placées entre guillemets. Pour des valeurs numériques, n'utilisez pas de
guillemets.
Si vous exécutez le script du Listing 4.2, vous pouvez vous assurer que le nouveau
produit sera ajouté à la table produits dans Access. Lancez Access, ouvrez la base
de données shopDB double-cliquez sur la table Produits. Vous devriez voir
s'afficher à l'écran l’enregistrement avec les valeurs prévues au Listing 4.2.
Utilisation de variables
La variable sqlString utilisant une chaîne de caractères comme valeur, celle-ci peut
être créée de manière dynamique. Le script du Listing 4.3 effectue exactement la
même opération que le précédent, à ceci près que la chaîne y est créée à partir de
variables pour les valeurs des colonnes.
LISTING 4.3 Insertion d'un nouvel enregistrement a l'aide de variables

ASP JSP PHP


01. <% 01. <% Driver 01. <?
02. Set conn = mysql_driver = 02. $conn =
Server.CreateObject("AD 02. (Driver)Class.forName("or mysql_pconnect('localhost
ODB.Connection") g.gjt.mm.mysql.Driver").ne ', 'root', '')
03. conn.Open "accessDSN" wInstance(); 03. $nomproduit = “Panier
04. nomproduit = “Panier 03. Connection conn = cadeau”
cadeau” DriverManager.getConnec 04. $prixproduit = “149.50”
05. prixproduit = “149.50” tion("jdbc:mysql://localhost 05.
06. sqlString = "INSERT INTO :3306/shopDB",”root”,””); 06. $sqlString = "INSERT
produits (nom, prix ) 04. String nomproduit = INTO produits (nom, prix
values ( '" & nomproduit & “Panier cadeau” ) values ( '". $nomproduit.
"', '" & prixproduit & "')" 05. String prixproduit = ”',” . $prixproduit . ”)"
07. Con.Execute sqlString “149.50” 07.
08. Con.close 06. String sqlString = 08.
09. %> "INSERT INTO produits 09. mysql_query($sqlString ,
(nom, prix ) "values ( '"+ $conn);
nomproduit +"', '" + 10. ?>
prixproduit + "')"
07. PreparedStatement
statement =
conn.prepareStatement(s
qlString);
08.
09.
statement.executeUpdate(
);
10. conn.close();
Analyse ASP, JSP et PHP
Ce script, comme le précédent, insère un nouveau produit dans la table
Produits. Cependant, deux variables, nomproduit et prixproduit, servent à
stocker les valeurs qui seront ajoutées à la base de données. Ligne 7, la
variable sqlString reçoit une chaîne construite avec des variables nomproduit
et prixproduit. Ligne 9, enfin, la chaîne sqlString est exécutée, et un nouveau
produit est ajoute à la base de données.
Vous avez peut-être remarqué que les valeurs affectées à la colonne nom
sont mises entre apostrophes, ce qui n’est pas le cas pour les valeurs
affectées a la colonne prix. Access utilise les apostrophes de la même
manière que le VBScript ou le HTML utilisent les guillemets. Ils permettent
d'indiquer le début et la fin d’une chaîne. Nom étant une colonne de texte,
vous devez utiliser des apostrophes pour affecter tine valeur a cette colonne.

Création d’une application catalogue produits avec


Dreamweaver
L’application catalogue produits devra exécuter les taches suivantes
• Permettre l’administration du catalogue
• Assurer la présentation du catalogue dans des formats multiples
L’administration du catalogue doit permettre :
• L’ajout de nouveaux produits et
• La mise à jours des informations sur des produits déjà présents dans le
catalogue
La présentation pourrait se faire sous forme de :
• Collection de plusieurs produits sur une page de catalogue ou comme
• Fiches de produits où chaque produit occupera une page du catalogue
Toutes les tâches évoquées font partie des tâches les plus fréquentes dans les
applications liées à des bases de données et qui pour cette raison sont déjà
automatisées dans des logiciels de création d’application web comme
Dreamweaver.
Dans Dreamweaver on peut insérer ce que l’on appèle des "objets d’application"
qui créent des pages serveur adaptée à chacune des tâches évoquées. Les "objets"
disponibles à partir du menu Insérer sont présentées dans la Figure 4.7
FIGURE 4.7 – Objets d’application disponibles en Dreamweaver

Création d’une application pour ajouter des


produits au catalogue
Présentation
Dans cette section, nous verrons comment créer un formulaire qui vous permettra
d'ajouter facilement des produits a votre magasin en ligne.
La page nommée addProduits.xxx2 sera créée. Elle contiendra un formulaire HTML
permettant de saisir les informations concernant le produit et ajoute le nouveau
produit a la base de données.
Démarche à suivre
Vous pouvez insérer les éléments de base d'une page d'insertion en une seule
opération à l'aide de l'objet dynamique Formulaire d'insertion d'enregistrement. Cet
objet insère dans la page un formulaire HTML et un comportement de serveur
Insérer l'enregistrement.
Vous avez également la possibilité d'insérer ces éléments séparément à l'aide des
outils de formulaire et du panneau Comportements de serveur.
Après avoir placé les éléments sur la page, vous pouvez personnaliser le formulaire
à votre convenance à l'aide des outils de conception de Dreamweaver ou modifier
le comportement Insérer l'enregistrement à l'aide du panneau Comportements de
serveur.
Pour créer la page d'insertion à l'aide de l'objet dynamique Formulaire
d'insertion d'enregistrement :
1. Ouvrez la page en mode Création, puis choisissez Insertion > Objets
d'application > Formulaire d'insertion d'enregistrement.La boîte de
dialogue Insérer le formulaire d'insertion d'enregistrement s'affiche.

2
L’extention .xxx signifie asp, jsp ou php.
2. Complétez les options de la boîte de dialogue et cliquez sur OK (les figures
sont dans la prochaine page).
Résultats
Dreamweaver insère dans la page un formulaire HTML et un comportement de
serveur Insérer l'enregistrement. Les objets de formulaire sont disposés sur la page
sous forme de tableau simple, que vous pouvez ensuite aisément personnaliser à
l'aide des outils de conception de page de Dreamweaver (assurez-vous qu'aucun
objet de formulaire ne dépasse les limites du formulaire).
Pour modifier le comportement de serveur, ouvrez le panneau Comportements de
serveur (Fenêtre > Comportements de serveur) et double-cliquez sur le
comportement Insérer un enregistrement.
La page addProduits.asp qui résulte comprend un formulaire HTML normal avec
des champs correspondant aux colonnes de la table Produits.
FIGURE 4.8 – Boite de dialogue pour configurer une page d’insertion à l’aide de
l'objet dynamique Formulaire d'insertion d'enregistrement
FIGURE 4.9 – Page d’insertion des produits au catalogue

Création d’une application pour mettre à jour


les produits d’un catalogue
Présentation
Dans cette section, nous verrons comment créer un formulaire qui vous permettra
de mettre à jour facilement les produits de votre magasin en ligne.
La page nommée updateProduits.xxx sera créée. Elle contiendra un formulaire
HTML permettant de modifier les informations concernant le produit qui à le
numéro d’identification (référence) indiqué dans la chaîne de requête.
Démarche à suivre3
l'objet dynamique Formulaire de mise à jour des enregistrements. Cet objet insère
dans la page un formulaire HTML et un comportement de serveur Mettre à jour
l'enregistrement.
Pour que vous puissiez utiliser l'objet dynamique, il faut que votre application Web
soit capable d'identifier l'enregistrement à mettre à jour et que votre page de mise à
jour soit en mesure de le récupérer.
Vous avez également la possibilité d'insérer séparément le formulaire HTML et le
comportement de serveur Mettre à jour l'enregistrement dans la page à l'aide des
outils de formulaire et du panneau Comportements de serveur.
Après avoir placé les objets dynamiques sur la page, vous pouvez utiliser les outils
de conception de Dreamweaver pour personnaliser le formulaire ou le panneau
Comportements de serveur pour modifier le comportement de serveur Mettre à jour
l'enregistrement.

3
adapté du système d’aide de Dreamweaver.
Pour créer la page de mise à jour à l'aide de l'objet dynamique Formulaire de
mise à jour des enregistrements :
1. Ouvrez la page en mode Création, puis choisissez Insertion > Objets
d'application > Formulaire de mise à jour des enregistrements. La boîte de
dialogue Insérer le formulaire de mise à jour des enregistrements s'affiche.
2. Complétez les options de la boîte de dialogue et cliquez OK (les figures
sont dans la prochaine page).
Résultats
Cet objet insère dans votre page un formulaire HTML et un comportement de
serveur Mettre à jour l'enregistrement. Les objets de formulaire sont disposés sur la
page sous forme d'un tableau simple, que vous pouvez ensuite personnaliser à l'aide
des outils de conception de page de Dreamweaver (assurez-vous qu'aucun objet de
formulaire ne dépasse les limites du formulaire).
1. Pour modifier le comportement de serveur, ouvrez le panneau Comportements
de serveur (Fenêtre > Comportements de serveur) et double-cliquez sur le
comportement Mettre à jour l'enregistrement.
La page updateProduits.asp qui résulte comprend un formulaire HTML normal
avec des champs correspondant aux colonnes de la table Produits.
FIGURE 4.10 – Boite de dialogue pour configurer une page de mise à jour à l'aide
de l'objet dynamique Formulaire de mise à jour des enregistrements
FIGURE 4.11 – Page de mise à jour des produits au catalogue

Présentation du catalogue en ligne


Présentation
La présentation à l’aide de pages web dynamiques (ou pages serveur) des produits
enregistrés dans une table de la base de données peut prendre des formes multiples.
Ici on montre deux qui semblent être les plus fréquentes. Il s’agit de la collection
de plusieurs produits sur une page de catalogue ou de fiches de produits ou chaque
produit occupera une page de la présentation en ligne.
Démarche à suivre pour obtenir un tableau dynamique4
Pour arriver à obtenir ces présentations il existe en Dreamweaver qui objet serveur
nomé tableau dynamique qui offre un format unique de présentation, qui peut
ensuite être modifié afin d’obtenir des présentation variées.
L'objet de serveur Tableau dynamique permet de créer un tableau renfermant un
contenu dynamique et d'appliquer le comportement Région répétée à partir d'une
seule boîte de dialogue. Cet objet de serveur est particulièrement utile, car il insère
le contenu dynamique d'un jeu d'enregistrements dans le tableau et applique
simultanément le comportement de serveur Région répétée.

4
adapté du système d’aide de Dreamweaver.
Pour créer un tableau dynamique :

1. Choisissez Insertion > Objets d'application > Tableau dynamique. La boîte


de dialogue Tableau dynamique s'affiche.

FIGURE 5.12 - boîte de dialogue pour configurer un Tableau dynamique

2. Dans le menu déroulant Jeu d'enregistrements, sélectionnez le jeu


d'enregistrements à utiliser.
3. Sélectionnez le nombre d'enregistrements à afficher sur chaque page (un
enregistrement à la fois permet à obtenir des fiches avec un enregistrement
par page).
4. A ce stade, vous pouvez taper les valeurs des bordures du tableau, de la
marge intérieure des cellules et de l'espacement entre les cellules.

La boîte de dialogue Tableau dynamique mémorise les valeurs spécifiées pour les
bordures du tableau, la marge intérieure des cellules et l'espacement entre les
cellules. Dans le cas de projets qui requièrent plusieurs tableaux dynamiques
d'aspect semblable, vous pouvez taper les valeurs de mise en forme du tableau pour
simplifier le développement des pages. Une fois le tableau inséré, vous pouvez
toutefois ajuster ces valeurs à l'aide de l'inspecteur de propriétés du tableau.

5. Cliquez sur OK.

Résultats
Un tableau et des espaces réservés destinés au contenu dynamique défini dans le
jeu d'enregistrements associé s'insèrent sur la page. Le nom de chaque élément
d'enregistrement se place dans la ligne de titre du tableau. Vous pouvez remplacer
les titres par tout texte descriptif ou image pertinente.
La deuxième ligne intégrée à une Région répétée contient les champs du jeu
d’enregistrements. La région répétée est le comportement serveur qui permet
d’afficher dans une page plusieurs enregistrements à fois en provenance du jeu
d’enregistrements selon le nombre indiqué dans la boite de dialogue qui défini le
Tableau dynamique.
FIGURE 4.13 – Vue (en mode édition de Dreamweaver) d’une page qui contient un
tableau dynamique

Démarche à suivre pour obtenir une barre de navigation du jeu


d'enregistrements5
Vous pouvez créer en une seule opération une barre de navigation de jeu
d'enregistrements à l'aide du comportement de serveur correspondant. Elle permet
de naviguer parmi les pages du catalogue en ligne.
Cet objet de serveur ajoute les éléments suivants à la page :
• Un tableau HTML comportant des liens texte ou image.
• Un jeu de comportements de serveur « Déplacer vers ».
• Un jeu de comportements de serveur « Afficher la région ».
La version texte de la barre de navigation du jeu d'enregistrements ressemble à
ceci :

La version image de la barre de navigation du jeu d'enregistrements ressemble à


ceci :

5
adapté du système d’aide de Dreamweaver.
Avant de placer la barre de navigation dans la page, assurez-vous que la page
contient un jeu d'enregistrements dans lequel naviguer et une mise en forme pour
afficher les enregistrements.
Après avoir placé la barre de navigation sur la page, vous pouvez utiliser les outils
de conception de Dreamweaver pour la personnaliser à votre convenance. Vous
pouvez également modifier les comportements de serveur « Déplacer vers » et
« Afficher la région » en double-cliquant dessus dans le panneau Comportements
de serveur.
Pour créer la barre de navigation de jeu d'enregistrements à l'aide de l'objet
de serveur :
1. En mode Création, placez le point d'insertion à l'endroit de la page où vous
souhaitez que la barre de navigation apparaisse.
2. Ouvrez la boîte de dialogue Barre de navigation du jeu d'enregistrements
(Insertion > Objets d'application > Barre de navigation du jeu
d'enregistrements). La boîte de dialogue Barre de navigation du jeu
d'enregistrements s'affiche.
3. Dans le menu déroulant Jeu d'enregistrements, sélectionnez le jeu
d'enregistrements dans lequel naviguer.
4. Dans la section Afficher à l'aide de, sélectionnez le format d'affichage des
liens de navigation sur la page. L'option Texte place des liens texte sur la
page, tandis que l'option Images permet d'utiliser des images graphiques.
Dans la version image de la barre de navigation, Dreamweaver utilise ses propres
fichiers d'image. Une fois que la barre se trouve sur la page, vous pouvez
néanmoins les remplacer par les vôtres.
5. Cliquez sur OK.
Le tableau qui se crée contient des liens texte ou image permettant à l'utilisateur,
lorsqu'il clique dessus, de se déplacer dans le jeu d'enregistrements sélectionné.
Lorsque le premier enregistrement du jeu s'affiche, les liens ou images « Premier »
et « Précédent » sont masqués. Lorsque le dernier enregistrement du jeu s'affiche,
les liens ou images « Suivant » et « Dernier » sont masqués.
Résultats
Vous pouvez personnaliser la mise en forme de la barre de navigation à l'aide des
outils de conception de Dreamweaver.
A l’aide d’un tableau dynamique et d’un barre de navigation du jeu
d’enregistrement, en modifiant la mise en forme, on obtient des présentations
variées pour les pages d’un catalogue en ligne.
Quand on choisit un tableau dynamique qui affiche plusieurs enregistrements à la
fois on obtient une page de catalogue qui présente une collection de plusieurs
produits comme dans la figure suivante:
FIGURE 4.14 – Page catalogue où le tableau dynamique affiche plusieurs
enregistrements à la fois

Quand le tableau dynamique choisit prévoit un seul enregistrement à la fois on


obtient des fiches de produits où chaque produit occupera une page de la
présentation en ligne. Voici un exemple :
FIGURE 4.15 – Page catalogue où tableau dynamique affiche un seul
enregistrement à la fois
En résumé
Présentation
Dans ce chapitre, vous avez vu comment interagir avec une base de données 1'aide
de scripts serveur. Vous avez d'abord appris comment créer une nouvelle base de
données et comment établir une connexion avec celle-ci.
Ensuite, vous avez vu comment ajouter des produits à votre magasin en ligne via
des pages ASP en faisant appel a' l'instruction SQL INSERT INTO pour ajouter de
nouvelles lignes à la table de la base de données. Pour finir, vous avez créé des
pages serveur permettant de mettre à jour des informations de produit existantes en
utilisant l’instruction SQL UPDATE.

Questions/ Réponses
Q Lors de la connexion à une base de données à partir d'une page serveur,
j'obtiens l'erreur "Source de données non trouvée et nom de pilote non spécifié.
D'ou provient cette erreur?
R Vous verrez s'afficher cette erreur si votre DSN n'est pas correctement
configuré. A partir de l'icône Sources de données ODBC du panneau de
configuration, vérifiez que vous avez bien crée un DSN. Assurez-vous ensuite que
vous n avez pas fait de faute de frappe en saisissant le nom du DSN dans le script.
Q Y a-t-il une limite au nombre de produits qu’il est possible de proposer dans
mon magasin en ligne?
R Une table de base de données peut contenir des milliards de lignes. Par
conséquent, en théorie, il est possible d'ajouter des milliards de produits à la table
Produits.
Q Pourquoi Access ne peut-il être utilisé pour un site Web dont le nombre de
visiteurs est très important?
R Access est une base de données individuelle, et non une base de données
client-serveur De ce fait, il ne peut gérer qu'un nombre limite de connexions
simultanées. Si vous prévoyez que le nombre d'utilisateurs se connectant
simultanément A votre base de données dépasse 30, vous devriez sérieusement
envisager de passer à SQL Server ou à MySQL etc.

Atelier
Les questions et les exercices ci-dessous sont destines à tester vos connaissances
concernant les informations traitées dans ce chapitre. Vous trouverez les réponses
dans l'Annexe A "Réponses aux questions".
Testez vos connaissances
1. Si vous déplacez votre base de données Access, quelles mesures devez-
vous prendre pour faire en sorte que vos scripts ASP trouvent la base de
données à son nouveau emplacement?
2. Ou se trouve I'erreur dans l'instruction SQL ci-dessous ?
INSERT INTO Products ( productname ) VALUES ( Panier cadeau)

3. Pourquoi les apostrophes posent-elles problème lors de l'ajout ou de la


modification des enregistrements d'une base de données?
4. Pourquoi les guillemets posent-ils problème lors de l'affichage d'une
variable A l'aide dc l'attribut VALUE dans un formulaire HTML?

Exercice
Comment faire pour ajouter des informations supplémentaires A votre magasin en
ligne Supposons par exemple que vous souhaitiez ajouter un champ pour le numéro
de référence d'un produit. Comment modifierez-vous la table de base de données et
les pages serveur de ce chapitre pour y inclure ce nouveau champ?
Epilog
Dacă aţi încercat să vă acomodaţi cât de cât cu idiosincraziile acestor limbaje Java,
VBScript, PHP şi SQL, atunci suntem siguri că veţi fi în largul dumneavoastră
când veţi avea parte de un pachet precum : Macromedia Dreamweaver sau
Microsoft Visual Studio sau, una din cele două suite de instrumente de mai jos.
Ar fi cazul ca în calitate de manageri de sit electronic să puneţi la dispoziţia celor
care se vor ocupa de construcţia şi întreţinerea sitului dumneavoastră una dintre
suitele la care ne referim acum.
Mulţimea serverelor Microsoft pentru comerţul electornic
Microsoft nu putea să stea impasibilă faţă de concurenţă (IBM, Oracle, BEA,
Allaire, Intershop etc.)
A realizat vreo 11 servere 20001 care au la bază strategia Microsoft DNA 2000,
adică arhitectura distribuită (într-un mediu de reţea), Distributed Network
Architecture.
De pildă să ne uităm la Microsoft Commerce Server 2000. Suita este continuarea
mai vechiului Microsoft Site Server 3.0 Commerce Edition (SSCE). Este aliniat la
standardul XML şi vine cu multe îmbunătăţiri.
Arhitectura este organizată pe trei nivele. La nivelul (stratul) de jos găsim
instrumente orientate spre XML, care permit definirea schemelor de date şi accesul
facil la ele. La nivelul intermediar nu puteau lipsi componente COM, care
fundamentează conceptul de groupware, deci de punere în comun la punct a unui
document (am explicat pe larg acest concept în cartea « Birotica şi Internet la
cumpăna mileniilor », D., Somnea şi M., Calciu, ed. Lucman, dec. 2000, lucrare în
prezent epuizată, când am tratat suita Microsoft Office 2000).
În fine, la nivelul suprafeţei grafice există complexul de obiecte Visio pentru
realizarea aspectuoasă a sitului comercial. Evident, produsul … ştie ASP, deci
Visual Basic şi, PRESUPUNE că ştiţi şi dumneavoastră ! Se pot crea profile şi
gestiona clienţii şi partenerii de afaceri.
BizTalk permite construirea unei infrastructuri de comerţ electronic. Editorul său
XML permite crearea rapidă a schemelor de documente financiar-contabile,
considerând structura organizată ca grup de articole de formular, sau altfel.
Oferă un instrument orientat pe suprafaţă grafică pentru elaborarea de documente.
Se vorbesc două limbi ! Cea pentru profesionistul din domeniul tehnologiei

1
Windows, SQL, Application Center, Commerce, BizTalk, Contents Management, Exchange, Host
Integration, Internet Security & Acceleration, Mobile Information şi SharePoint Portal.
informaţiei (IT), care e obligat să ştie ASP, SQL şi cea pentru administratorul
sitului B2B, B2C, care bine ar fi să aibă idee despre VBScript şi SQL.
Transformarea documentelor tip BizTalk se face cu ajutorul limbajului XSLT,
eXtensible Stylesheet Language Transformations (pentru scurte explicaţii ciţiţi încă
o dată capitolul 1 din limba română din această carte).
Se oferă şi un tandem de protocoale pentru mărirea siguranţei transportului
documentelor prin reţea între partenerii de afaceri. Dacă traficul este încărcat, deci
apar erori, se abandonează primul protocol şi se trece automat la cel de rezervă.
Dacă şi acum eşuează transportul documentului, el este adăugat automat la o coadă
de aşteptare pentru prelucrarea manuală.
Pentru definirea profilelor de clienţi stă la baza venerabilele Lightweight Directory
Application Protocol, LDAP şi Active Directory, reluate sub denumirea de
Microsoft MemberShip Directory, cel folosit în pachetul de origină Microsoft
SCCE (vezi referinţa /4/). Cu ele se permite un acces securizat pe bază de certificat
de autentificare la datele sitului.
Regulile de asociere la profile şi date au la bază un constructor de expresii, aşa
numitul expression builder. La rîndu-i el « musteşte » de XML. Nu putea lipsi o
bogată bibliotecă de pagini ASP, pentru elaborarea a tot felul de documente
specifice comerţului electronic, în toate felurile, gestionarea mesajelor electronice
ce vor fi adresate vizitatorilor şi cumpărătorilor.
Există evident şi un strat (shell) care uşurează completarea părţilor comenzilor
SQL, deci se face totul ca să evitaţi acest limbaj ! Se pot crea şi întreţine un arsenal
de cataloage de produse, clasificate după fel de fel de criterii.
Biztalk permite prin instrumente de tip agent electronic (wizards, vrăjitori, cum le
spun voioşii noştri tineri pasionaţi de „computere”) să creaţi ordine de plată etc., să
realizaţi tot felul de calcule de taxe.
Şi … IBM WebSphere
Pachetul IBM WebSphere este alcătuit dintr-o suită de componente , toate
îmbrăţişează tehnologia JSP la nivelul EJB, Entreprise Java Bean şi evident este
total orientat spre XML.
Are două variante: standard şi profesional. Realizează totul ca şi cele 10 servere de
mai sus, folosind avantajul tehnologiei JSP, anume construirea unor servleturi
rapide bazate pe cod de octeţi.
Cred că dacă aţi parcurs cartea aţi putu urmări ceea ce am spus mai sus.
Ca să vă faceţi o idee asupra interesului pentru construcţia de situri B2B, B2C,
statisticile indicau o cifră de afaceri pe anul 2000 de vreo 86 miliarde de dolari
pentru suita WebSphere, faţă de 26 miliarde pentru suita Microsoft Commerce !
Pentru amănunte vizitaţi şi portalurile :
www.duckhead.com,
www.arn.net,
www.schwin.com şi bineînţeles,
www.ibm.com (cuvinte cheie websphere, ejb, servlet, jsp).
În Acatistul Maicii Domnului pentru cei necăjiţi se spune explicit că:
« Bine este a nu iubi bunătăţile acestei lumi deşarte şi trecătoare ! »
Tâlcul : nu ne trebuie neapărat aceste « super-produse » software ci, şi acelea mai
modeste ca preţ, dar care cer efort mult mai mare de realizare.
Chiar şi aceste instrumente software sunt periculos a fi mânuite fără a poseda
minime cunoştinţe de programare !
Anexa A. Iniţiere în HTML, DHTML şi
XHTML
HTML, pas cu pas!
Acest limbaj nu este unul de programare ci unul pentru marcaje. Nici nu trebuie
învăţat ci doar să ajungeţi în faza de recunoaştere, ca să vă descurcaţi fără sprijinul
vreunui pachet pentru publicarea pe Web, atunci când doriţi să faceţi mici adăugiri
de aspect şi chiar de conţinut la un sit deja publicat. De pildă, trudiţi şi realizaţi în
sfârşit secvenţe animate cu vreunul din editoarele mai răsărite gen: GIMP, Flash
sau SwiFT etc.
Limbajul a evoluat până la versiunea 4.01 şi aici s-a oprit. A fost completat ulterior
cu HTML dinamic, DHTML. Din păcate ceea ce a adăugat Microsoft în materie de
balize, atribute, nu este recunoscut de clanul AOL+Netscape, Mosaic sau Mozilla,
deci numai de către Internet Explorer ! HTML a derivat din limbajul SGML,
limbajul părinte al tuturor limbajelor cu marcaje.
Aşadar acest HTML este un limbaj simplu pentru pagini de casă afişate cu
programul de vizitare „client browser”. Cel mai uzitat program este Microsoft
Internet Explorer, MSIE, dar într-o măsură suficient de mare este şi Netscape
Communicator.
Mai multe documente tip html adică pagini de casă, alcătuiesc un sit Web. Pagina
de bază, cea din care pleacă toate referinţele spre alte pagini situate mai jos pe
ierarhia sitului, este notată prin convenţie fie index.html sau index.htm (Netscape,
Mosaic, Hotjava, Mozilla etc.), default.htm sau .html (Internet Explorer). Desigur
denumirea aceasta nu este obligatorie, dar în acest caz trebuie menţionată şi
denumirea paginii primare în şirul de tip URL.
HTML are o serie de marcaje. Un marcaj este alcătuit dintr-o pereche de balize
(tags), răspândite prin textul documentului. De pildă, delimitarea întregului
document se face cu perechea de balize una pentru început <HTML> şi cealaltă
pentru sfârşit, </HTML>. Între cele două balize există text şi tot felul de alte
marcaje.
Un document tip .htm este alcătuit dintr-un antet şi dintr-un corp.
Fiecare nume de baliză poate conţine litere mari sau mici. Oricum, literele mici
sunt transformate în litere mari.
Antetul este delimitat de perechea <HEAD> şi </HEAD>. Deci:
marcaj_antet ::= <HEAD> … </HEAD>
Corpul documentului este definit ca:
marcaj_corp ::= <BODY> şi </BODY>.
Textul este alcătuit din blocuri şi paragrafe. Blocurile sunt delimitate de marcajul
div, deci prin balizele <DIV> şi </DIV>. Paragrafele sunt delimitate de perechea
de balize <P> şi </P>. Între cuvinte se lasă un spaţiu. Programele de vizitare ignoră
mai mult de un caracter blanc, cod 0x20, între cuvinte şi, de asemeni şi caracterele
de avans la linie nouă, cod 0x0d, cod 0x0a, introduse prin folosirea tastei ENTER.
Iată un prim exemplu de document html:
LISTA A-1. Primul pas în HTML
<HTML>
<TITLE>Primul document</TITLE><HEAD>Preambul</HEAD>
<BODY>
<H1>Antet de nivelul 1</H1><H2>Antet de nivelul 2</H2>
<H3>Antet de nivelul 3</H3><H4>Antet de nivelul 4</H4>
<H5>Antet de nivelul 5</H5><H6>Antet de nivelul 6</H6>
</BODY>
</HTML>

FIGURA A-1. Aspectul ferestrei documentului


Vedem apariţia unui marcaj nou şi anume marcajul html, care încadrează
documentul în sine: <HTML>...</HTML>. Sesizăm faptul că se admit antete pe
şase nivele. Nu trebuie să confundăm antetul de nivelul întâi cu titlul ferestrei şi cu
cuvintele înscrise în marcajul <HEAD>...</HEAD>. Fiecare are un rost bine
definit. Astfel, dacă marcajul html defineşte din punct de vedere logic documentul,
tot astfel marcajele head şi body îl divizează în cele două părţi ale sale, preambulul
şi corpul propriu-zis.
Diferenţa dintre cele şase marcaje pentru antete o constituie mărimea şi stilul ales.
Acestea nu sunt imuabile, când recurgeţi la serviciile unui program din clasa
browser, deci şi la Netscape Navigator. Ele pot fi desigur redefinite de după
dorinţă.
Sesizaţi că denumirea Preambul a apărut în fereastra aplicaţiei, separat de cuvintele
încadrate între balizele marcajului h1. Totodată denumirea „Primul document”,
înscrisă în bareta de sus a ferestrei principale, este informaţia aflată în marcajul
title. Desigur că în multe documente sunt folosite aceleaşi cuvinte atât în marcajul
title cât şi în h1. Sunt însă situaţii unde acestea trebuie să difere. În acest caz,
marcajul h1 se va referi de exemplu la titlul capitolului sau secţiunii, în timp ce
marcajul title va păstra titlul sitului Web.
Paragrafele sunt acceptate în documentul de tip html. Spre deosebire de
procesoarele de texte unde caracterele de sfârşit de paragraf (marcaje de paragraf,
paragraph marks, în terminologia Winword) sunt luate în consideraţie, aici codul
înscris într-un document prin apăsarea tastei ENTER nu are aceiaşi semnificaţie.
Pentru a realiza un salt la un paragraf nou (nu un rând nou) veţi recurge la baliza
<P>, iar pentru un salt la un rând nou la baliza <BR>. Iată grupul de cuvinte pentru
primul paragraf:
Acesta este primul paragraf<P>
Ceea ce am scris mai sus este echivalent cu:
<P>Acesta este primul paragraf</P>.
Numărul rândurilor goale este egal cu cel al balizelor <BR> folosite. Între
paragrafe s-au prevăzut mai multe linii libere la momentul vizualizării
documentului sau la imprimarea sa. Să modificăm puţin lista de mai sus.
LISTA A-2. Documentul din primul exemplu, docA.htm
<HTML>
<TITLE>Primul document</TITLE>
<HEAD>Preambul</HEAD>
<BODY>
<H1>Antet de nivelul 1</H1>
<P align=center>
Acesta este un grup de cuvinte centrat.
</P>
<P align=right>Expeditor...</P>
<A HREF="http://gommit.webconn.com/java/JavaScript/intro/index.htm">
Introducere in JavaScript</A>
<H2>Antet de nivelul 2</H2>
<A HREF="docB.htm#aici">punctati aici ca sa vedeti documentul B</A>
<H3>Antet de nivelul 3</H3>
<H4>Antet de nivelul 4</H4>
<H5>Antet de nivelul 5</H5>
<H6>Antet de nivelul 6</H6>
</BODY>
</HTML>
Aspectul documentului se schimbă (vezi figura A-2).

FIGURA A-2. Textul centrat şi punctarea unei adrese din spaţiul Web
Legăturile între documente
Acum să învăţăm cum să adresăm alte documente din spaţiul Web. Deci ne referim
la legături de tip „hypertext”. Un astfel de marcaj are următoarele părţi componente
(atribute):
<A HREF=”unde-anume”>cuvinte-cheie</A>
Litera A este iniţiala cuvântului anchor, ancoră. HREF înseamnă hypertext
reference, referinţă de tip „hypertext”. Unii traduc acest termen prin hipertext! Nu
există aşa ceva în DEX. Prin cuvintele ”unde-anume” înţelegem adresa în stilul
URL al locului din spaţiul Web. Urmează un cuvânt cheie (pot fi şi mai multe) care
se afişează cu o altă culoare şi subliniat. Când ajungeţi cu indicatorul mausului pe
această legătură indicatorul va căpăta forma unei mânuţe. Este legătura de tip
„hypertext” prin care, dacă se efectuează clic, se ajunge în acel document aflat
undeva la antipozi, sau în acelaşi fişier, depinde unde aţi ales să puncteze.
Înainte de a folosi mausul, veţi observa, când ajungeţi pe aceste cuvinte, cum în
linia de stare va apare adresa acelui document punctat. În sfârşit, baliza de
terminare este </A> şi nu </A HREF>. În figură am ales adresa unui documentaţii
de iniţiere în limbajul JavaScript, afllată la situl gommit.web.com în directorul
intro, fiul directorului JavaScript la rându-i, fiu al directorului java. Pagina de bază
se cheamă index.html. Documentul din lista A-2 poartă denumirea docA.htm.
Putem puncta chiar în cadrul aceluiaşi document sau în alt document din acelaşi
director sau alt director, altă partiţie, alt disc, altă staţie etc. Observaţi în cuprinsul
documentului docA.htm din lista A-2, locul de includere al literalului, chiar
deasupra textului pentru antetul de nivel doi:
<A HREF="http://gommit.webconn.com/java/JavaScript/intro/index.htm">
Introducere in JavaScript</A>
Iată acum al doilea document denumit docB.htm. El va conţine textul următor:

Lista A-3. docB.htm


<P>Anchors can also be used to move to a particular section inside a document, not
only to its starting point.
<P>Suppose you wish to set a link from docA and a specific section in docB.
<P>First you need to set up a named anchor in docB. For instance <A NAME =
"aici"> here</A>. Now when you create the link in docA, include not only the
filename, but also the named anchor, separated by a hash mark.
Ancorele pot fi utilizate chiar în cadrul unei secţiuni a documentului, deci nu numai la
începutul său. În lista de mai sus observaţi marcajul name:
<A NAME = "aici"> here</A>
Este destinaţia legăturii începută prin:
<A HREF = "docB.htm#aici">punctati aici ca sa vedeti documentul B</A>.
Acest literal se află în docA.htm şi punctează docB.htm nu la început ci undeva în cuprinsul
său, chiar acolo unde apare literalul <A NAME. Când textul documentului ar fi destul de
voluminos, atunci s-ar afişa porţiunea de text imediat după <A NAME "aici"></a>.În figura A-
3 este redat integral documentul docB.htm. Din docB putem sări înapoi în docA sau spre alt
document.
Observaţie: de aici înainte nu vom mai prezenta în mod sistematic în denumirile fişierelor şi
sufixul.
FIGURA A-3. Conţinutul docB vizualizat după saltul efectuat în cadrul acestuia
Legătura de tip „hypertext” este un arc de graf care pleacă din dreptul balizei <A
HREF...> şi care se termină în documentul receptor printr-o baliză <A NAME...>.
Nu mai efectuăm un atare exerciţiu. Mai simplă este sintaxa marcajului, când saltul
se efectuează în cadrul aceluiaşi document. Am avea în acest caz de exemplu în
docA o baliză de început de genul acesta: <A HREF = "#sectiunea_1"> vezi
sectiunea a întâia</A> şi, la începutul acestei secţiuni, care aici lipseşte în docA, o
baliză <A NAME = "sectiunea_1">.
Observaţie: de regulă documentul principal este bine să îl denumiţi index. Nu este
obligatorie această denumire, dar avantajul este următorul : în adresa tip URL nu
mai menţionăm şi denumirea paginii de bază ci numai specificaţia de cale, adică
traseul prin ierarhia de directoare spre această pagină de casă.
Liste
HTML manevrează trei tipuri de liste: nenumerotate (unordered, UL),
numerotate (OL), sortate crescător (ordered) şi pentru definiţii (defined, DL).
Sintaxa marcajelor pentru fiecare caz în parte este după cum urmează:
LISTA A-4. Un exemplu de liste nenumerotate
<UL> respectiv <OL><LI>element_1<LI>element_2</UL> respectiv </OL>
<DL><DT>nume-definitie_1<DD>definitia în sine, oricate paragrafe
<DT>nume-definitie_2<DD>definitia în sine, idem
</DL>
Nu sunt necesare alte explicaţii.

LISTA A-5. Alt tip de liste


<HTML>
<BODY>
<UL>
<LI>Relief
<UL>
<LI>munti<LI>dealuri<LI>campii
</UL>
<LI>Ape
<OL>
<LI>Lacuri naturale
<LI>Lacuri artificiale
<LI>Cursuri de apa
</OL>
</UL>
<DL><DT>URL<DD>Universe Resource Locator<P>Punct in spatiul Web unde se
afla cel putin un document.<P>Mai se intalneste sub initialelel URN sau URI.
<DT>Web<DD>Denumirea prescurtata a sistemului World Wide Web.<P>Sistem
aparut mai intai in Elvetia, la CERN, laboratoarele de fizica particulei.<P>O interfatã
unica, prietenoasa pentru necunoscatorii serviciilor clasice TCP/IP si care ofera
acces la servicii de genul:
<UL>
<LI>http<LI>gopher<LI>WAIS><LI>ftp<LI>news<LI>file<LI>telnet<LI>etc.
</UL>
</DL>
</BODY></HTML>
Tabele

Lista A-6. Tabel cu diferite opţiuni, inclusiv poză animată


<HTML>
<HEAD><TITLE>Tabel cu diverse optiuni</TITLE></HEAD>
<BODY>
<! Tabel cu chenar de 5 pixeli>
<! 2 pixeli intre celule, si alti 2 pixeli lasati liberi de marginea textului>
<! la chenarul celulei >
<TABLE BORDER=5 CELLPADDING=2 CELLSPACING=3>
<! Titlul tabelului, scris deasupra>
<CAPTION ALIGN=TOP>Tabel cu text si imagini animate</CAPTION>
<! Ce scrie in antetele fiecarei coloane>
<TH>Coloana a 1-a</TH><TH>Coloana a 2-a</TH><TH>Coloana a 3-
a</TH>
<!Prima linie. Textul va fi scris coform optiunii VALIGN, Vezi celulele>
<!Se recurge si la culori de fundal, bgcolor>
<!Celula 3 nu are nimic>
<TR>
<TD HEIGHT="60" VALIGN=TOP>Fara fundal, si in partea de
sus a celulei
</TD>
<TD HEIGHT="60" VALIGN=MIDDLE BGCOLOR="orange">In
centru si fundal portocoaliu
</TD>
<TD HEIGHT="60" VALIGN=BOTTOM BGCOLOR="yellow">In
partea de jos a celulei
si fundal galben
</TD>
</TR>
<! Linia 2. In celula din stanga un glob pamantesc care se roteste>
<! In celula din mijloc un text in care se explica adresarea URL in sens
relativ>
<TR>
<TD><IMG SRC="../../my pictures/image.gif"></td>
<TD>Imaginea globului care se invarteste, are structura gif'89.
se afla in directorul My Pictures. Directorul curent al acestui document este
learningHTML. El este fiu al directorului My Webs. Atat My Webs cat si My Pictures
sunt fii ai directorului Personal. Pentru a ajunge din learningHTML in My Pictures,
urcam o data in sus la My Webs, apoi inca o data in directorul Personal, coboram pe
ramura My Pictures si am ajuns!</TD>
</TR>
</TABLE>
</BODY></HTML>
Aspectul îl puteţi vedea în figură. Remarcaţi şi explicaţii în însuşi conţinutul listei de mai sus.

FIGURA A-4. Tabel cu diverse opţiuni

LISTA A-7. Tabel cu căsuţe unite pe verticală şi orizontală


<! Tabel cu chenar de un pixel care ocupa 70% din latimea ferestrei documentului >
<!textul din dreptul celulei anunta intentia balizei >
<table border=1 align=”center” width=”70%”>
<! Linia 1>
<tr><td colspan=”4” >4 celule unite pe linie</td></tr>
<! Linia 2 >
<tr>
<td rowspan=”4”>3 celule unite pe coloana</td>
<td>col 2, lin 2</td>
<td>col 3, lin 2</td>
<td>col 4, lin 2</td>
</tr>
<! Linia 3 >
<tr>
<td>col2, lin 3</td>
<td colspan=”2”Celule alaturate unite pe linia 3</td>
</tr>
<! Linia 4 >
<tr>
<td>col2, lin 4</td>
<td colspan=”2”Celule alaturate unite pe linia 4</td>
</tr>
</table>
Caracterele speciale şi cele diacritice

V-aţi pus probabil problema cum să folosiţi chiar caracterele "<" şi ">" ca de altfel şi
altele în textul dvs. Într-adevăr, aţi sesizat că aceste caractere au semnificaţie aparte.
Sunt caracterele speciale. Fiecare caracter special va fi descris printr-un grup de litere
terminat cu punctul şi virgula sau printr-un grup de cifre, caz în care se spune că e vorba
de secvenţe escape numerice. O astfel de secvenţă cuprinde şirul &#nnn; unde nnn este
un grup de trei cifre zecimale.
Exemple: &#33; este semnul exclamării (”!”), &#10; este avansul la linie nouă, line
feed, &#09; este tabulatorul orizontal, tab etc.
Şi caracterele speciale care au definite secvenţe de tip caracter au secvenţe echivalente
de tip numeric. De pildă, &#34; corespunde ghilimelelor (””") etc. Există şi varianta de
secvenţă escape hexazecimală. Ea are forma &#xhhh;. De pildă secvenţa numerică
pentru litera a mic este &065; şi cea hexazecimală, &#x041; .
Pagina de cod ISO-Latin-1 nu conţine decât o parte din diacriticele româneşti. Nu are şi
literele (mici şi mari) următoare: ş, ţ, şi ă, ci doar pe î şi Î. Problema este rezolvată dacă
adaptaţi browserul pe UNICODE, acel sistem de codificare cu doi octeţi pe caracter.
Singurul acest cod conţine toate diacriticile majorităţii limbilor.

FIGURA A-5 Aspectul exemplului lista7.htm

Definirea formularelor

S-a introdus marcajul form definit ca: <FORM>...</FORM>. Cu el creăm un formular.


În cadrul său pot fi incluse tot felul de elemente grafice: câmpuri de tip text de diferite
forme, butoane, casete de bifare (check boxes), butoane radio (radio buttons), casete de
tip listă (list boxes) sau, de tip listă derulantă (drop down list boxes).
Sintaxa (parţială) a marcajului este aceasta:
<FORM ACTION="adresã_de_tip_url" METHOD=”servlet sau program CGI”
ENCRYPT=”metoda de criptare”>...</FORM>

Atributul ACTION conduce la transmiterea cererii vizitatorului la programul tip CGI


sau serlvet aflat la serverul Web indicat de adresa respectivă. În lipsa acestui atribut,
cererea va fi dirijată spre serverul curent, cel care afişează pagina de casă respectivă. În
cadrul balizei <FORM> mai pot apărea atributele următoare: METHOD şi ENCTYPE.
Atributul METHOD precizează metoda care va prelucra informaţiile introduse de către
dvs. de la tastatură sau cu ajutorul mausului. Există mai multe metode. Cea mai uzitată
este însă POST.
Atributul ENCTYPE precizează metoda de criptare folosită în vederea transmiterii
securizate a informaţiilor formularului respectiv.
Marcajul form este însoţit de marcajele următoare (nu obligatoriu toate prezente în
acelaşi formular): input, select şi textarea.
Cu marcajul input specificăm o serie de atribute care le asociem rubricilor, câmpurilor
formularului. În cele ce urmează le vom spune elemente, unde vor fi colectate mesajele
de intrare (de la tastatură sau prin acţionarea mausului). Iată atributele semnificative:
• TYPE, care poate avea una din proprietăţile:
• Text - câmp de intrare de tip şir de caractere; se admit şi semnele speciale care încep cu
caracterul ampersand, &.
• Hidden (ascuns) - adică o intrare ce nu va fi afişată dar care graţie valorii precizate în atributul
VALUE, va constitui valoarea iniţială asumată a atributului cerut, în caz că vizitatorul nu va preciza
o altă valoare în mod interactiv.
• Password (parola) - câmp cu regim de parolă de acces; ceea ce tastaţi nu apare decât sub forma
unui caracter de umplere.
Toate acestea trei sunt câmpuri de tipul text. Dar într-un formular, sub aceeaşi baliză
<INPUT>, pot apare şi alte elemente de genul acestora:
• Caseta de bifare (checkbox), un pătrăţel în care apare un semn de bifare, când va fi selectat cu
mausul.
• Butonul radio (radio button), un cerculeţ în care apare un punct, dacă l-aţi selectat cu mausul.
• Butonul de validare (submit, echivalent butonului OK din contextul familiei sistemelor Windows);
dacă efectuaţi un clic pe el, toate informaţiile introduse de dvs. vor pleca la serverul http sub forma
unui şir.
• Butonul de iniţializare (reset) care va servi pentru anularea conţinutului câmpurilor acelui formular.
Trebuie doar să efectuaţi un clic pe el ca să vedeţi dispariţia informaţiilor, respectiv a eventualelor
selecţii efectuate de dvs. până atunci.
• NAME, este denumirea internă a resursei grafice respective (câmp, casetă de bifare etc.), folosite
de creatorul paginii de casă;
• VALUE, ce valoare asumată să aibă acea resursă; este textul care apare pe unele dintre resurse.
• CHECKED, folosit în contextul casetelor sau radio butoanelor. Acele resurse vor fi bifate;
• SIZE, mărimea câmpului; se asumă 20 caractere; dacă aici apar două valori numerice, a doua se
referă la numărul rândurilor;
• MAXLENGTH, numărul maxim de caractere care vor fi acceptate de către câmpurile de tip text.
Combinând aceste ultime două atribute puteţi face să apară liste derulante cu barete de defilare.
Iată un formular cu patru câmpuri. Vizitatorul va vedea pe ecran în dreptul câmpurilor
respective marcate cu claritate texte descriptive explicative:
LISTA A-8. Primul formular cu patru câmpuri
<!-- exista un server http local care stie limbajul perl -->
<FORM METHOD="POST">
Introduceti numele: <INPUT NAME="nume1">
Si aici prenumele: <INPUT NAME="nume2"></P>
Iar aici varsta: <INPUT NAME="nume3">
Adresa dvs:<INPUT NAME="nume4"></P>
</FORM>

Remarcaţi apariţia separatorului pentru avansul la o linie nouă <P>. Primele două
câmpuri, botezate intern cu denumirile nume1 şi nume2, apar pe prima linie a
formularului. Ele vor avea fiecare o lungime asumată de 20 caractere. Mai departe,
cititorul poate urmări uşor celelalte două câmpuri.
La formularul de mai sus să facem să apară şi obiecte grafice: butoane, butoane radio,
casete de bifare. În plus, programul va prelucra valorile câmpurilor. El se află la serverul
cu adresa hoohoo.ncs.uiuc.edu în directorul htbin-post şi se numeşte post-query.
Secvenţa HTML este cea din lista următoare:
LISTA A-9. Un exemplu mai complet de formular
<FORM METHOD="POST" ACTION="http://hoohoo.ncsa.uiuc.edu/htbin-post/post-
query">
Precizati datele dvs.(optional):</P>
<P> Numele:<INPUT NAME="nume1"> Prenumele:<INPUT NAME="nume2"></P>
<P> Ocupatia:<INPUT NAME="nume3"> Profesia:<INPUT NAME="nume4"></P>
<P> Orasul:<INPUT NAME="nume5"> Tara:<INPUT NAME="nume6"></P>
<P> V-a placut pagina noastra?</P>
<DL>
<DD><INPUT TYPE="radio" NAME="nume7" Value="Da"><I>Da,yes,ja,oui</I>
</DD>
<DD><INPUT TYPE="radio" NAME="nume8" Value="Nu"><I>Nu, no, nein,
non</I></DD>
<P> Daca nu, aveti sugestii de imbunatatire a paginii noastre (max 1000
litere)?:
<INPUT NAME="name9" SIZE="40" MAXLENGTH="1000"> </P>
<P><INPUT TYPE="submit" VALUE="Send"><INPUT TYPE="reset" VALUE="Clear
fields">
<INPUT TYPE="submit" VALUE="Cancel"></FORM></P>
<P>VA MULTUMIM! Clicati <A HREF="#A0">aici</A> ca sa reveniti la inceput.</P>

Textul „V-a placut pagina noastră” apare pe un rând izolat (vezi şi figura A-4). Urmează
o listă de tip DD, care specifică două butoane radio. Denumirile lor interne sunt nume7
şi respectiv nume8. Cele două butoane nu apar selectate pe ecran (adică fără punctuleţe
în interiorul cerculeţelor). Prin executarea unui clic pe oricare din ele are loc selecţia. În
speţă, va apare punctuleţul şi la folosirea butonului Send, se va transmite conţinutul
câmpului, nu ceea ce se vede de fapt pe ecran. Desigur că am fi putut face să apară
selectat orice buton. Pentru acesta era de ajuns să scriem în secvenţa HTML atributul
CHECKED. Câmpul nume9 este unul de tipul lung. El este însoţit de două atribute
SIZE şi MAXLENGTH. În acest caz, el nu va mai avea doar 20 caractere ci 1000.
Echivalentul butonului prin care realizaţi funcţia de efectuare a acţiuni, deci de validare
(cum este OK din Windows) are aici tipul submit. Butonul va avea afişat în cadrul său
eticheta Send (transmite) nu OK, deoarece aşa am dorit.
Mai apar două butoane: unul de tip reset, pe care scrie Clear fields şi celălalt de tip
submit, pe care scrie Cancel. Un singur clic efectuat pe butonul de tip reset, va face să
dispară conţinutul câmpurilor formularului. Are loc deci o iniţializare a formularului.

FIGURA A-6. Aspectul formularului

Prin executarea unui clic pe butonul Send, va fi transmis la server un şir de caractere cu
valorile din câmpurile, în ordinea aceea cum apar ele pe ecran. Deci dacă la nume aţi
precizat Ionescu, la prenume, Gheorghe etc., şirul va arăta astfel:

nume1=Ionescu&nume2=Gheorghe&nume3=... .

Acest şir de catene alipite vor fi prelucrate de către programul post_query.


În schimb, un clic pe butonul Cancel va echivala cu renunţarea la transmiterea acestui
şir de catene.
Marcajul select ne permite să redăm o listă de câmpuri accesibile pentru un meniu
derulant sau mai multe astfel de meniuri. Ca sintaxă comanda se scrie astfel:

<SELECT NAME="acest_meniu">
<OPTION>optiunea_1<OPTION>optiunea_2>...</SELECT>

Meniul denumit acest_meniu are acces la câmpurile ale căror denumiri interne de mai
sus apar în atributele OPTION din descrierea sintactică. Alte atribute ce pot apărea în
cadrul marcajului select sunt:
• NAME, stabileşte denumirea internă a meniului, adică a elementului grafic din formularul
respectiv;
• MULTIPLE SIZE, precizează numărul opţiunilor afişate din totalul celor prezente. Dacă sunt mai
multe, apare evident bareta de defilare (scroll) şi, prin explorarea ei facem vizibile opţiunile
respective;
• SELECTED, specifică faptul că acea opţiune pe lângă care apare, va fi automat selectată.
Marcajul textarea are sintaxa următoare (vezi şi mai jos alt exemplu):
<TEXTAREA NAME="nume_intern" ROWS=valoare COLS=valoare> valoarea
asumatã </TEXTAREA>
Denumirea internă a obiectului figurează în atributul NAME şi, este denumirea dată de
dvs. Prin atributele ROWS şi COLS stabiliţi numărul de linii şi coloane ale câmpului de
captare.
Este echivalentul obiectului de tipul "input textarea" din Windows, unde se permite
înscrierea unui text captat de către aplicaţie.
În cazul acestui al treilea exemplu pe ecran vom găsi următoarele elemente:
LISTA A-10. Un alt formular
<HTML>
<HEAD><TITLE>...</TITLE></HEAD>
<BODY>
<P><FORM METHOD="POST" ACTION="http://hoohoo.ncsa.uiuc.edu/htbin-
post/post-query">
<FIELDSET>
<B><FONT SIZE=+1>Login:<INPUT NAME="numeSesiune"
VALUE="anonymous">
<BR></FONT>
<TT>Your password please:<INPUT TYPE="password" NAME="parola"
VALUE="guest"></TT></B>
</FIELDSET>
<FIELDSET>
<HR WIDTH="100%"></P><P><B><I>Please specify the preferred
platform:</I></B>
<SELECT NAME="platforma">
<OPTION SELECTED><FONT SIZE=+1>PC-Windows NT
<OPTION>PC-Windows95<OPTION>PC-Windows3.x<OPTION>Unix-AIX
3.2.5.<OPTION>Macintosh-MacOS 7.x
</SELECT>
<HR WIDTH="100%"></FONT><I>And class of software product:</I>
<SELECT NAME="soft" MULTIPLE SIZE=3>
<OPTION>Database<OPTION>Spreadsheet<OPTION>Text
Processor<OPTION>Graphics Editor
<OPTION>Desktop accessories<OPTION>Utilities<OPTION>Integrated
Development Environment
<OPTION>Multimedia<OPTION>Contacting via Internet<OPTION>Games
</SELECT></P>
</FIELDSET>
<FIELDSET>
<TEXTAREA NAME="impresii" ROWS="5" COLS="55" WRAP="OFF">Impresiile
dumneavoastra:</TEXTAREA>
<P><INPUT TYPE="submit" VALUE="OK"><INPUT TYPE="submit"
VALUE="Cancel"></FORM></P>
</FIELDSET>
</BODY></HTML>
Se urmăreşte structura standard a unui document de tip html, compusă după cum
cunoaşteţi, din antet <HEAD>...</HEAD> şi din corpul propriu-zis
<BODY>...</BODY>. Nefigurând nimic în cadrul balizei <TITLE>, înseamnă că nu
am optat pentru o anume denumire de fereastră.
Corpul documentului se referă la un formular, care după cum se cunoaşte din celelalte
exemple, conţine o linie care începe cu baliza <FORM>. În cadrul ei se specifică
metoda de tratare a informaţiilor de intrare preluate de la vizitator. Tot ce apare în ea a
fost introdus într-o fereastră specială, după cum se va vedea. Deocamdată suntem la faza
de recunoaştere a părţilor secvenţei.
Formularul este divizat în parcele încadrate de chenare, fiecare chenar corespunde unui
marcaj fieldset, deci unei perechi de balize <FIELDSET> … </FIELDSET>.
Urmează câmpurile denumite intern prin numeSesiune şi parola, care fac parte din
prima parcelă. În numeSesiune cel precedat de Login: vom înscrie numele sesiunii
noastre care poate oricare. Am presupus că cel mai des va fi "anonymous", de aceea am
înscris de la început acest cuvânt în cuprinsul câmpului
Parola se cere prin câmpul următor. Când tastaţi ceva, apar atâtea steluţe câte litere
introduceţi. Şi aici am presupus o parolă formată din cinci litere, guest. De aceea se
afişează cinci steluţe. Ca să nu schimbăm conţinutul unui câmp cu valoare asumată,
vom folosi tasta TAB şi trecem la următorul câmp al formularului.

FIGURA A-7 Aspectul acestui formular

În parcela a doua sunt două câmpuri de tip select. Remarcaţi baliza <SELECT> care se
referă la câmpul platforma; este de fapt o casetă de tip listă (list box), unde apare doar
prima opţiune din cele cinci, aceea care are OPTION SELECTED. Acest câmp permite
vizitatorului, selectarea platformei.
Mai departe, se remarcă încă un câmp similar, ce specifică clase de produse soft, care
trebuie selectate de către vizitator; denumirea internă a resursei (câmpului) este soft.
Câmpul este de fapt o listă derulantă (drop down list box în sens Windows), din care se
afişează într-o mică fereastră doar primele trei opţiuni dintr-un total de zece.
În sfârşit, ne întâlnim şi cu marcajul textarea. Acesta este inclus alături de cele două
butoane în a treia parcelă. Resursa textarea are numele intern impresii. În această casetă
cel ce vizitează situl poate introduce un text. Caseta are fiziceşte 5 linii a câte 55 litere cu
talie normală. Faptul că am plasat la atributul HARD opţiunea WRAP, aceasta va
însemna alunecarea cuvântului pe rândul următor (word wrapping, vezi referinţa /1/).
Când aţi ajuns la limita fizică de 55 litere, respectiv 5 linii, bareta respectivă devine
activă; va apare un vernier (buton) care se deplasează de-a-lungul baretei de alunecare,
scroll bar. În felul acesta textul este permanent afişat. Facilitatea de alunecare a
cuvântului pe rândul următor, wordwrap, este activă pentru oricare din opţiunile
PHYSICAL, VIRTUAL sau SOFT, (vezi şi anexa B, marcajul textarea)
Evident, cele două butoane OK şi Cancel, pe care le-aţi întâlnit şi mai sus, sunt elemente
de tip submit.
Ce este HTML dinamic, DHTML?

Sunt extensii la limbajul pentru marcaje, menite să dea posibilitatea pregătirii unei
pagini de casă cu facilităţi mai elevate. Folosind numai balizele limbajului standard
HTML, această posibilitate este limitată. Una dintre extensiile DHTML este şi aceea a
definirii unor stiluri, style sheets. Ele conţin tot felul de elemente tipografice precum:
culoarea textului, marginile paginii logice, elemente de aliniere, familia de caractere,
mărimea corpului de literă etc.
Dar HTML dinamic mai înseamnă şi poziţionarea precisă în cadrul paginii. În
paragraful de faţă ne vom referi doar la descrierile de stiluri în cascadă. Nu dezvoltăm.
Orice browser suportă desigur ambele descrieri de stiluri, şi anume: cel care nu
comportă cunoaşterea limbajului JavaScript şi cel specific acestui limbaj. Evident, ne
referim doar la a prima modalitate.
Sintaxa este în schimb foarte rigidă. În cazul că greşiţi, nu are loc blocarea browserului,
ci, pur şi simplu întreaga construcţie de stil va fi ignorată.
CSS a ajuns între timp la versiunea a doua. Cu ce diferă prima de a doua versiune nu
trebuie să vă intereseze. Se definesc în faţa documentului sau în fişiere separate aşa-
zisele şabloane de stiluri pentru aşezarea în format a textului. Proiectantul sitului Web
defineşte aceste şabloane la început şi apoi le aplică fragmentelor din text. Fragmentul
poate fi o zonă întinsă din text, un alineat, un paragraf, un titlu, un cuvânt, chiar şi numai
o literă.
Aşezarea în format în corpul definiţiei se face prin mai multe modalităţi. Ne vom limita
doar la două din ele şi anume:
• Atribuirea unui stil fix unei balize (cazul primelor două exemple de mai jos).
• Atribuirea unei clase (vezi exemplul al treilea).
Stilurile au tot felul de atribute, proprietăţi. Atributele au valori. De pildă, se poate
preciza denumirea familiei de caractere, font, alinierea textului, culoarea cu care va fi
scris acesta, ce culoare să aibă fondul din preajma literelor. Valorile pot fi menţionate
unde este cazul în procente. Se pot menţiona o serie de atribute pentru imagini inserate
în document, chiar şi culorile punctelor unei enumerări. Când definim un stil, vom
declara tipul său ca tip text/css, fie ca text/JavaScript. În ultimul caz, trebuie să
cunoaşteţi limbajul JavaScript. De aceea, vom intra puţin în detalii doar pentru
alternativa tipului text/css. Ambele tipuri aparţin de standardul MIME.
Începem direct pe un exemplu mai simplu. Priviţi lista de mai jos.
LISTA A-11. Primul exemplu CSS
<html>
<style type="text/css">
<!--
P {font-size:10pt; font-family: "arial"; font-style: italic;}
H1 {color:green; font-size:24pt; font-family: "helvetica"; font-style: "bold";}
-->
</style>
<body>
<H1>Titlul scris cu litere verzi</H1>
<P>Primul paragraf</P><P>Al doilea paragraf</P>
</body>
</html>

FIGURA A-8. Cele două definiţii de stil

Aici sunt două definiţii de stil, una pentru paragrafe, vă amintiţi baliza <P>, şi alta
pentru antetul de nivelul întâi <H1>. Prima definiţie asociază tuturor paragrafelor unei
pagini de casă un corp de literă cu talia de zece puncte, familia de caractere Arial, cu
litere înclinate.
A doua definiţie cuprinde aceleaşi proprietăţi, atribute. În plus, se defineşte şi culoarea
corpului de literă ca fiind verde. De remarcat cele două definiţii încadrate de balizele:
<!-- respectiv --> .
Mai remarcaţi că fiecare proprietate este urmată de separatorul două puncte (”:”), apoi
de valoarea proprietăţii. Sunt mai multe perechi de proprietăţi-valoare. Ele sunt
delimitate prin punct şi virgulă (“;”).
Iată un al doilea exemplu puţin mai complex. Redăm mai întâi conţinutul documentului.
LISTA A-12. Al doilea exemplu de stylesheet
<HTML>
<HEAD><TITLE><STYLE TYPE="text/css"></TITLE></HEAD>
<STYLE TYPE="text/css">
P {textAlign:center; margin-left:20%; margin-right:20%;}
H4 {text-decoration:underline; color: green;}
H5 {text-transform:uppercase; color: red; border-width:4pt;
border-style:outset; background-color:yellow; padding: 4pt;
border-color:red;}
BLOCKQUOTE {color:blue; font-style:italic; line-height:1.5; text-indent:10%;}
</STYLE>
<BODY>
<H4>Antet de nivelul patru</H4>
Scris cu culoare verde si subliniat.
<H5>Antet de nivelul cinci</H5>
<Blockquote>
Antetul de nivel cinci a fost scris doar cu litere mari, uitati ce chenar are scos in
relief,desi broserul avea alte resurse tipografice definite pentru H5. Noi prin definitia
de stil nu am facut altceva decat le-am modiciat.
Acest text este cu marcajul <BLOCKQUOTE> E scris cu albastru si observati-i
alinierea pe verticala si intervalul dintre randuri
</blockquote>
</BODY>
</HTML>

FIGURA A-9. Aspectul documentului

Faptul că am scris toate balizele cu majuscule nu trebuie să vă deranjeze. Este indiferent


ce litere folosiţi.
Pentru baliza <P> se specifică acum şi marginile stângă şi dreaptă. Ele sunt date în
procente ceea ce este foarte bine, deoarece lăsăm browserul să îşi calculeze câţi pixeli va
aloca, în funcţie de mărimea în pixeli a ferestrei şi rezoluţia ecranului. Mai remarcaţi
faptul că textul va apare centrat. Toate elementele antetului de nivel cinci vor fi scrise cu
litere mari.
Antetele vor fi încadrate de un chenar roşu cu grosimea de patru pixeli. Chenarul va fi
unul tridimensional. Intervalul dintre text şi chenar va avea tot patru pixeli. Literele vor
fi scrise cu roşu, fondul va fi galben.
Toate elementele tip <BLOCKQUOTE> vor fi redate cu culoarea albastră înclinate. Se
va lăsa un interval care va fi de odată şi jumătate ori mai mare decât talia corpului de
literă. În sfârşit, prima linie va fi împinsă spre dreapta în interior cu 10%. Cum arată
pagina de casă cu MSIE puteţi vedea în figură.
Observaţii:
• Am lăsat în mod intenţionat două cuvinte greşit transcrise: ,,broser” şi ,,modiciat”.
• Din text lipsesc caracterele diacritice. Aceasta deoarece, programul de vizitare nu
era condiţionat pe pagina de cod corespunzătoare ci pe codul ISO-8859-1.
Urmează al treilea exemplu în care apar procedeul definirii de clase.
LISTA A-13. Ultimul exemplu de definiri de stiluri
<html><head><title>Stiluri definite prin clase</title>
<style type="text/css">
body {background: yellow;}
p {font-family: "Times Roman"; font-height: 20pt;}
.cursiv {font-style: italic}
.ingrosat {font-weight: bold}
</style>
</head>
<body>
<P>Primul paragraf, cu cuvinte cu litere normale.</P>
<P>Al doilea paragraf in care cuvantul MAMA e scris cu litere inclinate <span
class=cursiv>MAMA</span>.</P>
<P>Al treilea paragraf, unde cuvantul TATA e scris cu litere ingrosate: <span
class=ingrosat>TATA</span>.</P>
</body></html>
Să privim aspectul în figură.

FIGURA A-10. Apectul documentului

Secvenţele multimedia

Vom exemplifica o modalitate (nu unica) de redare a secvenţelor video. Deoarece am


posedat un program freeware în persoana programului de redare al secvenţelor video cu
extensia MPEG, denumit mpegply2.exe, am anunţat în prealabil browserul că vom
folosi ca program terţ (aşa-zisul helper application, în jargon Netscape), evident şi
directorul unde sălăşluieşte el. Faceţi asta deschizând meniul Options, General
Preferences, fila Helpers. Şi, în caseta de dialog respectivă după ce v-aţi poziţionat pe
extensia .mpeg, folosiţi butonul browse cu care ajungeţi în directorul gazdă al
programului mpegply2.exe. Fişierul video s-a numit film.mpg, iar fişierul document se
numeşte film.htm.
LISTA A-14. Inserţia unui film în pagina de casă
<HTML>
<HEAD>
<TITLE>Exemplu adhoc de redare a unui fisier cu extensia mpeg</TITLE>
</HEAD>
<BODY>
<H2>Movie Pictures Expert Group; format de secvente video</H2>
<A HREF="../../adhoc/film.mpg">Sa vedem filmul film.MPG</A> (Lungimea
secventei in KB)<BR>
</BODY>
</HTML>

În lista de mai sus cititorul sesizează o notaţie aparent specială în baliza HREF. De fapt,
fişierul film.mpg nu se află în acelaşi director cu fişierul film.htm (coincidenţa numelor
este pur întâmpătoare) ci, într-un alt director denumit adhoc, fiu al directorului rădăcină
c:\. Faţă de acesta din urmă, film.htm se afla în directorul c:\mydata\ JavaScript. De aici
cele două grupe de puncte din baliza HREF.
Nu sunt unicele programe pentru interpretarea secvenţelor video. Sunt o puzderie!
Alegeţi la început un produs freeware, nu shareware. De exemplu, un format video
popular este cel girat de aplicaţia terţă Quicktime. Extensia fişierelor este .qt.
Ce este XHTML?

Am adus vorba în introducere de XML, acest limbaj al unei descrieri enervant de


canonice a conţinutului unui document.
XHTML este o reformulare a HTML ca aplicaţie a XML. Este o încercare de
canonizare a HTML.
Iată un fragment de cod scris lejer în HTML:
LISTA A-15. Cod scris în HTML

<TITLE>Scriere lejera in HTML si canonica in XML</TITLE>


<H1>My Example</H1>
<P>Bla bla’s
<p>Aici includ o poza.
<div align=center><img src=”poza.jpg” width=300 height=200 alt=”[aici vine o poza]>
</div>
<br>
<table>
<tr><td>Celula R1 C1<td>Celula R1 C2
<tr><TD>Celula R2 C1<td>Celula R2 C2
</TABLE>

După ce veţi vedea transcrierea în XHTML vă veţi da seama şi singuri, dacă aveţi spirit
de observaţie, de lejerităţile HTML. Iată echivalentul XHTML al cayului de mai sus:
LISTA A-16. Cod scris canonic în XHTML

<?xml version=”1.0”>
<!DOCTYPE html PUBLIC „-//W3C//DTD XHTML 1.0 Strict/EN”
„http://www.w3.org/TR/xhtml1/DTD/strict.dtd>
<html xmlns=”http://www.w3.org/1999/sxhtml>
<head>
<title>Scriere lejera in HTML si canonica in XML</title>
</head>
<body>
<h1>My Example</h1>
<p>
Bla blas’s
</p>
<p>
Aici includ o poza.
</p>
<div align=”center”>
<img src=”poza.jpg” witdh=”300” height=”200”
alt=”[aici vine o poza]” />
</div>
<br />
<table>
<tr>
<td>Celula R1 C1</td>
<td>Celual R1 C2</td>
</tr>
<tr>
<td>Celula R2 C1</td>
<td>Celual R2 C2</td>
</tr>
</table>
</body>
</table>

Deci observaţi pe lângă o aliniere strictă, cum cerea specificaţia XML 0.91 sau 0.92 şi
nu mai se cere în versiunea XML 1.0, o serie de linii insipide.
XHTML face distinţie între literele mici şi cele mari. Tr nu este tot una cu tr, td nu este
tot una cu TD, table nu este tot una cu TABLE.
XHTML nu lasă o baliză fără baliza terminală. Observaţi cum apar terminalele.
Balize izolate ca hr, img sau br au un fel anume de scriere. Remarcaţi acel spaţiu urmat
de o bară înclinată.
Atributele nu merg decât cu litere mici, deci dacă scriem aşa: <table WIDTH="100%">
este greşit. Dar aşa <table width="100%"> este corect.
Nu se admite aşa ceva:
<BODY>
<P>Iata un paragraf. P este scris cu litera mare </P>
</BODY>

ci aşa ceva:
<BODY>
<p>Iata un paragraf. P este scris cu litera mica</p>
</BODY>

În loc de atributul name ca aici:


<img src="picture.gif" name="picture1" />
trebuie folosit atributul id:
<img src="picture.gif" id="picture1" />
Ca să meargă şi la vechile browsere trebuie scris aşa:
<img src="picture.gif" id="picture1" name="picture1" />
În XHTML nu se admit încrucişări de tipul <tr><td>text</tr></td>.
Aşa ar trebui să arate un şablon minim de document XHTML :
<!DOCTYPE Doctype goes here>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Aici vine titlul</title>
</head>
<body>
Iar aici este corpul documentului
</body>
</html>
Această scriere XHTML, fiind o aplicaţie a XML, este supusă unui document aşa-zis
DTD, Document Type Definition, care face verificarea sintactică a scrierii. Fişierul cu
regulile sintactice de descriere a XHTML se află la adresa indicată de acea resursă Web
din declaraţia DOCTYPE.
Vizitaţi situl /16/ pentru XHTML şi XML.
Pentru ca această scriere canonică s-au conceput şi scris aşa-zisele translatoare HTML-
XHTML.
Dave Radgett de la W3C are un sit de care se ocupă şi unde apar fel de fel de astfel de
translatoare, cum sunt programul Tidy (www.w3.org/People/Radgett/tidy).
James Clark a scris în Java un translator XML-HTML, (www.jclark.com/xml/xt.html).
Ambele au regim freeware! Se numeşte XT (vezi şi /14/) merge doar dacă aţi instalat
JDK2 şi JRE. Trebuie ca după instalarea sam să mutaţi biblioteca xt.jar în directorul
special al JRE, adică în: C:\Program Files\JavaSoft\JRE\nr_versiune\lib.
Anexa B. Sintaxa JSP1
Reguli de ţinut minte

Pagina JSP este conţinută de un fişier cu extensia .jsp. I se spune fişier JSP.
Paginile JSP ajung în final servleturi.
Limbajul JSP este alcătuit din: directive, scriptleturi şi etichete.
În denumirile referitoare la variabile, clase, obiecte se face diferenţa între literele mici şi
cele mari.
Directivele JSP se introduc între delimitatorii <%@ şi %>. Delimitatorii pentru
scriptleturi sunt <% şi %>. Delimitatorii pentru comentarii sunt: cei pentru comentariul
de tip „text plus evaluarea expresiilor JSP” <!-- text , expresii JSP -- > şi comentariul
„ascunde cod” cu forma: <%-- text -->.
În prima formă de cometariu se admite şi orice instrucţiune scrisă în limbajul Java.
Orice instrucţiune Java din scriptlet (şi din afara sa, cu acest caz nu ne-am întâlnit
întrucât am evitat să scriem fişiere cu cod pur Java) este un text terminat cu separatorul
punct şi virgula, de exemplu:
StringBuffer = new StringBuffer();
// aici se defineşte un obiect de tip StringBuffer al clasei cu acelşi nume

Directivele JSP au destule atribute. Toate sunt flancate de ghilimele sau apostrofi. De
exemplu:
<%@ page contentType=”plain/text” %>

Toate etichetele JSP încep cu prefixul „jsp:”. În cazul directivei taglib, prefixul este cel
fixat de noi.
Nu sunt admise spaţii (caractere blanc) înaintea şi după semnul egal.
Dacă în HTML spaţiile albe sunt nesemnificative (oricâte spaţii albe aţi tasta, tot un
singur spaţiu se va genera. Ca să se ştie de către HTML că vreţi spaţii albe, veţi recurge
la caracterul &nbsp; adică nonblanking space.
În JSP, toate spaţiile albe sunt luate în consideraţie, aşa cum le-aţi introdus.
Secvenţa escape pentru caracterul x se scrie astfel: \x . De exemplu \’ serveşte la
ignorarea apostrofului, sau, \’’ , la ignorarea ghilimelei de către analizorul sintactic al
JSP.
Alt exemplu: ca să ... orbim analizorul sintactic al JSP deci să sară peste caracterul >
vom scrie aşa: \>.

1
Doar o parte din JSP, exemplificat în această carte.
Specificatorii de adrese URL: Presupunem că pagina noastră se află într-un director
curent. Ea se numeşte x.jsp. Când ne referim din pagina x.jsp la paginaMea.jsp, motorul
servlet se caută paginaMea.jsp în directorul curent. Notaţia ../paginaMea.jsp, produce
căutarea în directorul părinte al directorului curent. Când scriem dir1/paginaMea.jsp, se
va căuta în directorul dir1, fiu al directorului curent. În sfârşit, o specificaţie de forma
/dir2/paginaMea.jsp, înseamnă că dir2 este frate cu directorul curent.
Directiva page

Are următoarea formă sintactică:


<%@ page atribut=”valoare” [ atribut=”valoare” …] %>

Pot fi mai multe atribute care sunt distanţate la un spaţiu unul de altul.
Cu excepţia atributelor extends, isThreadsafe şi info, iată celelalte atribute:
• import este o listă pentru importarea pachetelor în acea pagină. De exemplu import
“java.text.dateFormat, java.io.*”
• contentType defineşte tipul MIME şi pagina de cod (vezi referinţa /1/). Exemplu:
contentType=”text/html; charset=”unicode”, adică pagina va conţine text de tip document HTML scris în
codul care are16 biţi per caracter.
• language anunţă limbajul folosit pentru scrierea acelei pagini. Poate fi doar java sau javascript. Se
presupune java. Exemplu language=”javascript”.
• session specifică faptul că pagina JSP este accesată ca parte a unei sesiuni. De exemplu
session=”false”. O valoare ”false” semnifică faptul că pagina din care facem astfel referirea nu are
acces la obiectul implicit session. Orice referire la un astfel de obiect se va solda cu o eroare fatală de
către parserul JSP. O valoare ”true” va duce la iniţializarea obiectului sesiune pentru această pagină..
Se asumă ”true”.
• buffer de exemplu <%@ page buffer=”none” %> va conduce la dirijarea output-ului acelei pagini direct
spre ecranul clientului Web, fără stocarea sa prealabilă într-o zonă tampon la serverul Web care
găszduieşte servletul. Iată cum declarăm o zonă tampon de 16 kiloocteţi: <%@ page buffer=”16kb” %>
• autoFlush specifică felul cum se anunţă umplerea zonei tampon cu output-ul generat de pagina, ce
conţine acest atribut în directiva page. Dacă ”true”, tamponul se va goli în mod automat la umplerea sa.
Dacă ”false”, umplerea va conduce la setarea condiţiei de depăşire ”overflow”. Se asumă ”true”.
• isErrorPage dacă este ”true” aceasta înseamnă că pagina curentă va conţine obiectul exception. O
valoare ”false” (adică cea asumată) specifică faptul că obiectul exception nu este accesibil. Orice
referire la acest obiect exception se va solda cu o eroare fatală anunţată de către parserul JSP.
• errorPage specifică o adresă în sens URL spre pagina care se ocupă de tratarea erorilor servletului. În
acea pagină trebuie să existe neapărat atributul isErrorPage setat pe ”true”.
Directiva include

Are forma sintactică:


<%@ include=”specificator_fişier” %>

De exemplu scriem <%@ include=”/inc1/header.inc” %> şi în acest caz se caută în


directorul inc1 frate al directorului curent fişierul de tip text header.inc. Neapărat ca
fişierul inclus să nu fie o clasă ci un fişier de tip text. Specificatorul de fişier este în sens
URL şi în mod relativ, aşa cum am explicat mai sus prin acele exemple cu directorii.
Directiva taglib

Are forma sintactică:


<%@ taglib=”prefix care precede numele etichetei personalizate” url=”adresa relativă
sau absolută în sensul URL” %>

Şi defineşte o bibliotecă de etichete personalizate. Nu am tratat această facilitate în


cartea de faţă. Totuşi taglib este definit încă de la versiunea JSP 1.1.
Câteva etichete JSP (direct exemple)

TABELUL B.1
Denumirea Explicarea exemplului din Exemplul
etichetei coloana alăturată
<jsp:forward page=”page2.jsp” /> sau
forward Trimitem mai departe cererea din
<jsp:forward page=”page2.jsp> . . . </jsp:forward>
pagina page1.jsp la page2.jsp spre
a fi prelucrată.
<jsp:getProperty name=”it” property=”temp” />
getProperty Servletul are o clasă de tip Bean
sau
denumită TBean.class Una dintre
<jsp:getProperty name=”it” property=”temp”>
metodele acestei clase este
. . . </jsp:getProperty>
denumită getTemp. O solicităm ca
În interiorul clasei metoda este definită astfel:
să ne trimită valoarea temperaturii;
...
o apelăm din pagina curentă. Vezi
private String teta;
şi useBean

public String getTemp() { return teta; }
<jsp:setProperty name=”it” property=”temp”
setProperty Servletul are o clasă de tip Bean,
value=”38” />
TBean.class. Una dintre metodele
sau
acestei clase este denumită
<jsp:setProperty name=”it” property=”temp”>
setTemp. O solicităm ca să fixăm
. . . </jsp:setProperty>
valoarea temperaturii în variabila
În interiorul clasei metoda este definită astfel:
privată a clasei bean, denumită teta.
...
Cum? Vezi coloana alăturată şi
private String teta;
useBean.

public void setTemp(tVal) { teta=tVal; }
<jsp:include page=”dir1/mypag.jsp” />
include Include resursa mypag.jsp aflată în
sau
directorul dir1, fiu al directorului
<jsp:include page=”dir1/mypag.jsp”>
unde se află pagina din care se
. . . </jsp:include>
face referirea.
<jsp:useBean name=”it” class=”TBean” />
useBean Localizează şi instanţiază clasa
sau
TBean.class pentru a putea fi
<jsp:useBean name=”it” class=”TBean” > . . .
utilizată cu acţiunile setProperty şi
</jsp:useBean>
getProperty
Bibliografie
1. D., Somnea, M., Calciu, „Noile tehnologii informatice şi de comunicaţie, ed.
Lucman, 2002”, Bucureşti.

2. L., A., Philips, „XML”, trad. ed. Teora, 2001 după „Special Edition Using
XML”, ed. Que, 2000.

3. D., Somnea, “Iniţiere în JavaScript şi tehnologiile Netscape”, ed. Tehnică,


1998, Bucureşti.

4. Ben, Scott, ş.a., “Dezvoltarea aplicaţiilor JSP, traducere după JavaServer Pages
Application Development”, ed. SAMS, 2001, ed. Teora, 2001, Bucureşti.
Însoţit de CD cu pachete freeware şi shareware din anii 1999-2000, referitoare
la motoare.

5. O., Săulescu, “Creaţi uşor un Website dinamic cu PHP şi mySQL”, Revista:


Chip, număr dedicat proiectării unui sit, nr.2, 2003.

6. St., Walter, J., Levine, “Programarea în ASP pentru comerţul electronic”, trad.
Ed. Teora după „Teach Yourself E-Commerce Programming with ASP in 21
Days”, ed. SAMS Publishing, 2001.

7. * * * “Le Livre Blanc de Serveurs d’Applications“, OCTO Technology, Raport


datat martie 1999.

8. * * * “Ghidul Microsoft pentru produsele de tip server“, ediţia a doua,2000 sau


www.microsoft.com/romania/servere, 2001.

9. Benoit, Marchal, “XML by Example“, ed. QUE, 2000.

Adrese Web utile


10. http://java.sun.com/j2se/download.html, pentru preluarea kitului standard
SDK2 Standard Edition, toate versiunile.

11. http://java.sun.com/j2se/download.html, pentru preluarea kitului standard


SDK2, Entreprise Edition, toate versiunile.

12. http://www.xml.com/axml/testaxml.htm, Tim Bray’s Adnotated XML 1.0


Recomandation, un ghid XML mai … puţin hain, deci explicat mai clar !
13. http://www.chami.com/, program freeware care curăţă un fişier HTML
de ... scame şi îl transformă în document XML.

14. http://www.jclark.com/, un motor freeware denumit XT, scris în limbaj


Java, folosit pentru publicarea HTML a unui document tip XML,
pornind de la un fişier cu instrucţiuni XSL.

15. http://www.alphaworks.ibm.com/, câte un procesor freeware pentru


XSL şi XST.

16. http://www.w3schools.org/, un portal pentru şcolarizarea într-unul din


limbajele XML, XSL, ASP, HTML, XHTML, JavaScript etc., mai puţin
Java. Excelent!

17. http://www.lycos.com/main/?query=w3Schools, pointer spre referinţa


16 de la motorul de căutare lycos.

18. http://search.yahoo.com/search?p=w3schools, pointer spre referinţa 16


de la motorul de căutare yahoo.

19. http://search.excite.com/search.gw?search=W3Schools, pointer spre


referinţa 16 de la motorul de căutare excite.

20. http://www.altavista.com/cgi-bin/query?q=W3Schools, pointer spre


referinţa 16 de la motorul de căutare Altavista.

21. http://search.msn.com/results.asp?q=W3Schools, pointer spre referinţa


16 de la motorul de căutare Microsoft.

22. http://www.google.com/search?q=W3Schools, pointer spre referinţa 16


de la motorul de căutare adulat google şi,

23. http://www.amazon.com/exec/obidos/ASIN/059600026X/W3schools03
pointer spre referinţa 16 chiar şi de la portalul Amazon!

S-ar putea să vă placă și