Documente Academic
Documente Profesional
Documente Cultură
Ghidul Managerului Pentru Noile Tehnologii Informatice Si de Comunicatie
Ghidul Managerului Pentru Noile Tehnologii Informatice Si de Comunicatie
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>
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)
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)
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)
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!
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.
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.
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)
<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
<<BEST>> products!</FONT>
</CENTER>
</body>
</html>
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 <<BEST>> 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
<<BEST>> 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: < , > ).
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 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);
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 <<BEST>> 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
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
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
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
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().
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>
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.
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.
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
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.
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.
<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.
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” />
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
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.
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
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
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
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
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
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.
<HTML>
<HEAD>
<TITLE>mypisi.com - Versiunea cu cadre</TITLE>
</HEAD>
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'>
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
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()) ) {
// 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()) ) {
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).
<%!
// 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, "" );
}
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" );
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
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”.
FIGURA 5.1 Modelul de acces la baze de date tip JDBC:ODBC (după referinţa /4/)
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
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
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.
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
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
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
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
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
Î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
package jsp;
public class AusterBean {
// variabilele clasei sunt totdeauna intangibile din exterior
private String meckerel;
// 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;
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.
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.
<!--
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>
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
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);
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>
ş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>
ş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())) %>
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>
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" );
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
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!
<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):
Î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:
<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>
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 "
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
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.
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).
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ă”)
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
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.
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
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"
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
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
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!
<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
31. <html>
32. <head><title>Administrare Produse</title></head>
33. <body bgcolor="gray">
34. <%
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
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 )
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
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")
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. %>
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).
01. <%
02. ' In variabila prodRS formez tabelul cu produse pentru acea categorie, cat
03. Set prodRS = Server.CreateObject("ADODB.Recordset")
04. prodRS.ActiveConnection = Con
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"> </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
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!
01. <%
02. ' Resetez generatorul aleator
03. Randomize
04. ' Declar o constanta
05. CONST numVitrina= 3
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.!
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)
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
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.
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") )
12. <html>
13. <head><title>Inregistrare</title></head>
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!
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
03. <%
04. numeclient = TRIM( Request( "numeclient" ) )
05. parola = TRIM( Request( "parola" ) )
06. inreg = TRIM( Request( "inreg" ) )
07. ' response.write "verficclient.asp: inreg = " & inreg & "<BR>"
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)
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.
01. <%
02. FUNCTION apostrof12(Sirul)
03. apostrof12 = REPLACE(Sirul, "'", "''")
04. END FUNCTION
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
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
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
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
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. <%
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.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
06. ' response.write "completarecomanda.asp: nume client = " & numeclient &
"<BR>"
07. ' response.write "completarecomanda.asp: parola sa = " & parola & "<BR>"
08. ' response.end
03. <%
04. ' Regasesc informatiile de inregistrare
05. sqlString = "SELECT * FROM clienti " &_
06. "WHERE id_client=" & idClient
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
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>
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’
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
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.
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?
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è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
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.
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é.
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
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>
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.
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
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
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
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îne</TITLE></HEAD>
03. <BODY>
04. <%
05. Response.Write Server.HTMLEncode(">>N'hésitez pas à 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
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é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élimiteurs de sortie</TITLE></HEAD>
03. <BODY>
04. <br>Nous sommes le <%=DATE()%>
05. <br>et il est <%=TIME()%> heures.
06. </BODY>
07. </HTML>
01. <HTML>
02. <HEAD><TITLE>Arrêt de 1'exé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.
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
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
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
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
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
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
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.
01. <HTML>
02. <HEAD><TITLE>Saisie du
prénom<ITITLE></HEAD>
03. <BODY>
04. Veuillez entrer votre pré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
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éter les
champs ci-dessous :</b>
05. <FORM METHOD="POST"
ACTION="page2f.xxx">
06. <p>Nom
07. <br><INPUT name="client"
SIZE="30">
08. <p>Numé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éter les champs ci-dessous :</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é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>
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.
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>
• 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
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).
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.
(avec phpMyAdmin )
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.
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.
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
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
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
4
adapté du système d’aide de Dreamweaver.
Pour créer un tableau dynamique :
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.
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
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
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)
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-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:
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: ! este semnul exclamării (”!”), este avansul la linie nouă, line
feed, 	 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ă, " 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ă, A .
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.
Definirea formularelor
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.
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=... .
<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.
Î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>
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>
Secvenţele multimedia
Î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?
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>
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 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
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
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.
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.
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.
23. http://www.amazon.com/exec/obidos/ASIN/059600026X/W3schools03
pointer spre referinţa 16 chiar şi de la portalul Amazon!