limbajul HTML de descriere a hipertextelor;
protocolul HTTP de transmitere a hipertextelor;
un browser (Internet Explorer, Netscape, Opera etc.);
un server de Web (Tomcat, Java Web Server, IPlanet etc.).
O resursa pe Internet (în cazul cel mai simplu un fisier) este specificata printr-un URL (Uniform Resource Locator). Un URL contine în mod tipic urmatoarele informatii:
protocolul folosit;
adresa masinii pe care se afla resursa;
portul ales pentru conexiune;
calea catre resursa;
numele resursei.
În continuare vom folosi doar protocolul HTTP.
O cerere HTTP contine un URL, dar si alte informatii (de exemplu eventualii parametri ce sunt transmisi). Principalele tipuri de cereri HTTP sunt GET si POST. Despre efectul lor si diferenta dintre ele vom vorbi mai târziu.
O cerere HTTP este formata din:
antete (header request);
cererea propriu-zisa: comanda (de exemplu GET sau PUT), un URL si eventualii parametri ce trebuie transmisi serverului.
Antetele de cerere contin printre altele informatii despre:
browser si mediul de operare;
lungimea continutului (ContentLength);
dispunerea continutului (ContentDisposition); vezi capitolul referitor la transmiterea de fisiere;
tipul continutului (ContentType), conform protocolului MIME (Multipurpose Internet Mail Extension) utilizat; aceasta din urma poate fi de exemplu:
text/plain : pentru text ASCII;
text/html : pentru documente HTML;
text/vnd.latex-z;
application/octet-stream; application/postscript;
application/rtf; application/pdf;
application/zip; application/msword;
application/vnd.ms-excel;
application/vnd.ms-powerpoint;
application/x-java-serialized-object
application/x-www-form-urlencoded; (*)
multipart/form-data; (**)
image/gif; image/jpeg;
audio-basic;
video/mpeg; video/quicktime
cu precizarea ca (*) este implicit pentru Internet Explorer, iar (**) este folosit de exemplu pentru transmiterea de fisiere de la browser catre server si invers.
setul de caractere folosit (de exemplu US-ASCII
Cererea poate include ca sufix un sir de parametri (QueryString) sub forma de perechi (nume,valoare):
?nume1=val1&nume2=val2&...&numen=valn
Când accepta o conexiune de la un client, serverul primeste cererea HTTP, închide legatura cu acesta pe portul pe care este pornit si lanseaza un fir de executare care restabileste legatura pe un alt port. Eliberarea portului asociat serverului are ca scop ca serverul sa poata primi alte cereri de la clienti.
Serverul de Web Tomcat este de tipul HTTP si prin urmare este capabil sa primeasca si sa interpreteze comenzi HTTP.
Trecem la prezentarea modului de instalare a serverului HTTP.
Presupunem ca lucram sub WINDOWS, ca browserul implicit este Internet Explorer si ca Java apare în C:\java
Decomprimam cu winzip în C:\Tomcat3 produsul Tomcat3.zip download-at de pe: https://jakarta.apache.org/tomcat.
Mergem succesiv în:
My Computer | Control Panel | System | Advanced | Environment Variables
si în fereastra de jos:
dublu click pe path si introducem C:\java\bin
apoi new si completam:
Variable name: JAVA_HOME
Variable value: C:\java
Verificam ca instalarea a fost corecta astfel:
la pornirea serverul prin executarea comenzii:
C:\Tomcat3\jakarta-tomcat-3.3.2\bin\startup.bat
vor aparea, printre altele, informatiile:
. . . . .
. ContextManager : Adding DEFAULT:/admin
. ContextManager : Adding DEFAULT:/examples
. ContextManager : Adding DEFAULT:/ROOT
. . . . .
EmbededTomcat: Startup time xxx
deschidem Internet Explorer si specificam http://localhost:8080
trebuie sa apara pagina implicita a lui Tomcat (index.html
oprim serverul prin comanda :
C:\Tomcat3\jakarta-tomcat-3.3.2\bin\shutdown.bat
Explicatii:
Tomcat foloseste portul 8080;
este folosit un gestionar ContextManager care tine evidenta directoarelor în care se cauta fisierele specificate la cereri adresate serverului de Web; cele implicite sunt admin, examples si ROOT din:
C:\Tomcat3\jakarta-tomcat-3.3.2\webapps
prin cererea https://localhost:8080 este solicitat fisierul implicit index.html, aflat în directorul ROOT, recunoscut de catre ContextManager;
browser-ul afiseaza pagina Web respectiva.
Cream propriul nostru director de lucru User în :
C:\Tomcat3\jakarta-tomcat-3.3.2\webapps
Ca urmare, la pornirea serverului de Web Tomcat va aparea si:
. . ContextManager : Adding DEFAULT:/User
5.1.3. Clasa URL
Clasa URL este declarata în pachetul java.net prin:
public final class URL extends Object implements Serializable
Un obiect de tipul URL, numit si locatie URL, este o referinta la o resursa Web. Resursa poate fi un fisier, un director, dar si un obiect mai complex ca de exemplu o cerere catre o baza de date sau un motor de cautare; un caz special, studiat pe larg în continuare, este cel în care resursa este un servlet. Ca sintaxa, o astfel de referinta cuprinde 5 parti:
protocol adresa :port /cale /fisier
unde protocol desemneaza serviciul exportat de server sau cautat de client (vom utiliza numai http adresa este adresa simbolica sau numerica a serverului de Web, port este portul folosit pentru comunicare, cale indica spre unul dintre directoarele recunoscute de ContextManager, iar fisier identifica resursa.
Un exemplu este urmatorul:
https://www.ncsa.uiuc.edu:8080/demoweb/url-primer.html
în care protocolul este http, adresa este www.ncsa.uiuc.edu, portul este , iar cale este demoweb/url-primer.html
Sunt folosite si locatii URL partiale, ce specifica doar unele parti din forma completa a referintei; acest lucru este posibil în situatiile în care celelalte parti sunt implicite sau se deduc din context. De exemplu poate lipsi numele masinii gazda (daca facem referire la masina locala) sau portul (daca este folosit un port implicit).
Putem folosi unul dintre constructorii:
public URL(String s) throws MalformedURLException
unde s este referinta completa
public URL(String protocol, String adresa, int port,
String cale) throws MalformedURLException
Dintre metodele, toate publice, ale clasei URL mentionam urmatoarele:
public String getPath()
întoarce calea din locatia URL;
public int getPort()
întoarce numarul portului din locatia URL;
public String getProtocol()
întoarce protocolul din locatia URL;
public String getHost()
întoarce adresa masinii gazda din locatia URL;
public String getFile()
întoarce numele fisierului din locatia URL.
sirul de parametri poate fi regasit prin invocarea metodei:
public String getQuery()
Daca URL-ului îi este adaugat un sir de parametri, atunci rezultatul întors de getFile() este concatenarea rezultatelor întoarse de getPath() si getQuery(); în caz contrar getFile() si getPath() întorc acelasi rezultat.
Mai sunt importante metodele:
public URLConnection openConnection() throws IOException
realizeaza o conexiune la server si întoarce un obiect de tipul clasei URLConnection (despre care vom vorbi în continuare);
public final InputStream openStream() throws IOException
deschide un flux de intrare ce permite sa citim date din conexiune; aceasta metoda este echivalenta cu openConnection().getInputStream()
Sa observam ca nu exista o metoda care sa întoarca un flux de iesire.
Clasa abstracta URLConnection este declarata în pachetul java.net prin:
public abstract class URLConnection extends Object
Aceasta clasa este superclasa tuturor claselor ce reprezinta o legatura de comunicatie între o aplicatie si un URL. Obiectele de acest tip pot fi folosite pentru accesarea, atât pentru citire cât si pentru scriere, a resursei referite prin respectivul URL. Conectarea reprezinta de fapt o cerere catre resursa; în cazul folosirii protocolului HTTP, este vorba de o cerere HTTP.
Constructorul:
protected URLConnection(URL url)creaza o conexiune la URL-ul specificat, dar nu la resursa referita.
Câmpurile principale sunt:
protected boolean useCachesare ca rol
folosirea caching-ului daca valoarea sa este true
; în caz
contrar se încearca de fiecare data obtinerea unui obiect nou
precizeaza
daca dorim sa citim din conexiune; valoarea implicita este true
precizeaza
daca dorim sa scriem în conexiune; valoarea implicita este false
deschide o conexiune catre resura specificata în URL
public InputStream getInputStream() throws IOExceptionîntoarce un flux de intrare pentru a putea citi din conexiune
public OutputStream getOutputStream() throws IOExceptionîntoarce un flux de iesire pentru a putea scrie în conexiune
public void setDoInput(boolean input)permite setarea câmpului doOutput
public void setDoOutput(boolean output)permite setarea câmpului doOutput
public void setUseCaches(boolean usecaches)seteaza
valoarea câmpului useCaches
Aceasta clasa apare tot în pachetul java.net, este specificata prin:
public abstract class HttpURLConnection extends URLConnection
si este folosita de obicei pentru specificarea tipului de cerere HTTP. Mentionam doar constructorul:
protected HttpURLConnection(URL u)si metoda:
public void setRequestMethod(String metoda)prin care putem specifica tipul cererii (de exemplu GET sau POST).
Observatie. Pentru o cerere HTTP, tipul implicit este GET
5.1.6. Exemple
În cele ce urmeaza presupunem ca serverul de Web Tomcat este pornit.
Exemplul 1. Presupunem ca în directorul User de pe serverul de Web Tomcat este prezent urmatorul documentul A0.html cu continutul:
<html>
<body> O.K. </body>
</html>
Daca pornim browser-ul Internet Explorer si dam comanda:
https://adresa_server:8080/User/A0.html
atunci va fi afisata de catre browser pagina Web corespunzatoare, având drept continut numai:
O.K.
În exemplele care urmeaza presupunem ca:
în directorul User de pe server este prezent documentul A01.html cu continutul:
<html>
<body>
<applet code="A01.class" width=200 height=50> </applet>
</body>
</html>
precum si rezultatul compilarii applet-ului A01 urmator:
import java.awt.*;
import java.applet.Applet;
public class A01 extends Applet
pe client exista compilata clasa Conexiune
import java.io.*;
import java.net.*;
class Conexiune
catch(MalformedURLException mue)
catch(IOException ioe)
Exemplul 2. Executarea programului de mai sus de pe client prin comanda:
java Conexiune
produce la iesire linia:
/User/A01.html
urmata de continutul fisierului A01.html, deoarece:
prin crearea obiectului url de tipul URL s-a deschis o conexiune catre resursa A01.html aflata pe serverul de Web;
prin invocarea metodei openStream s-a creat un fisier de intrare din care s-a citit linie cu linie continutul resursei A01.html.
Exemplul 3. Daca pornim browser-ul Internet Explorer si dam comanda:
https://server:8080/User/A01.html
atunci va fi descarcat de pe server si afisat de catre browser applet-ul A01
Exemplul 4. Putem porni browser-ul si afisa applet-ul A01 si din cadrul unui program Java, dupa cum urmeaza:
public class cmd
Acelasi efect se obtine si daca din linia de comanda cerem:
C:\Progra~1\Intern~1\iexplore.exe https://server:8080/User/A01.html
Clasa URLEncoder, care apare în pachetul java.net
public class URLEncoder extends Object
pune la dispozitie metode pentru conversia,
conform unei scheme de codare, a sirurilor de caractere la formatul MIME application/x-www-form-urlencoded
Schema de codare recomandata pe majoritatea sistemelor este UTF-8. Ea este implicita, dar poate fi specificata explicit pentru siguranta.
Regulile de codare sunt urmatoarele:
caracterele alfanumerice (literele alfabetului englez si cifrele), precum si caracterele si se pastreaza;
blancul este convertit la
celelalte caractere sunt convertite la "%hh", unde numarul hexazecimal hh reprezinta numarul lor de ordine în setul de caractere.
Pentru conversie putem invoca una dintre urmatoarele metode statice:
public static String encode(String s)dintre care prima foloseste schema de codare a platformei gazda, iar a doua specifica explicit numele unei scheme de codare.
Servlet-urile sunt aplicatii Java aflate pe server si executate de catre acesta. Serverul de Web, la executarea servlet-ului, trimite înapoi browser-ului un fisier HTML, pe care acesta îl afiseaza corespunzator; în particular, browser-ul nu trebuie sa stie nici macar ce înseamna un servlet.
În modalitatea clasica, serverul de Web primeste - de exemplu - o cerere de tipul:
GET nume_fisier
si întoarce fisierul respectiv. Aici nume_fisier este numele unei clase (servlet) a carei executare întoarce browser-ului un fisier HTML pe care browser-ul îl afiseaza clientului. Acesta poate completa unele informatii si retrimite o cerere noua serverului de Web, care prelucreaza informatiile primite si retrimite rezultatul din nou sub forma unui document HTML. Procesul se poate repeta de oricâte ori. Un pas al acestui proces poarta numele de tranzactie. Precizam ca serverul nu pastreaza datele de la o tranzactie la alta decât (fireste) daca le stocheaza explicit (de exemplu într-un fisier sau într-o baza de date).
Partea din serverul de Web care asteapta cereri (în cazul nostru cereri de executare a unui servlet) este numita demon HTTP, deoarece are caracteristicile unui fir de executare demon. Serverul poate efectua "simultan" tranzactii cu mai multi clienti, pornind pentru fiecare un fir de executare.
Mai mentionam ca schimbul de informatii între server si fiecare client se face în esenta prin socket-uri, dar la un nivel superior si în mod transparent pentru utilizator.
Servlet-urile nu sunt subiectul unor restrictii, asa cum se întâmpla de exemplu cu applet-urile. Ele creaza documente HTML dinamice prin succesiunea de tranzactii descrise mai sus. Independenta de platforma a limbajului Java se extinde în mod natural si logic asupra servlet-urilor (spre deosebire de script-urile CGI care sunt dependente de platforma si care sunt în plus mai lente).
Pentru lucrul cu servlet-uri, vom crea în directorul nostru de lucru User din:
C:\Tomcat3\jakarta-tomcat-3.3.2\webapps
urmatoarea structura de directoare:
User
WEB-INF (*)
classes (**)
si vom copia în ( fisierul web.xml din
C:\Tomcat3\jakarta-tomcat-3.3.2\webapps\examples\WEB-INF
Aplicatiile noastre (servlet-urile) vor fi plasate în
Mai sunt necesare urmatoarele:
Înainte de compilarea servlet-urilor facem setarea:
set classpath=
C:\Tomcat3\jakarta-tomcat-3.3.2\lib\common\servlet.jar;.
Varianta: adaugam calea de mai sus în comanda set classpath din autoexec.bat.
Daca vrem sa executam C.class obtinuta prin compilarea unui servlet aflat în directorul classes, deschidem de pe client Internet Explorer si specificam:
https://server:8080/User/servlet/C (***)
cu observatia ca servlet nu este director, ci informatie ca lucram cu servlet-uri; clasa C va fi cautata în ...\User\WEB_INF\classes
Daca în cream un pachet P având în interiorul sau clasele publice A (principala), B si C, atunci:
clasele A, B, C vor începe cu: package P;
din interiorul pachetului P la setarea de mai sus adaugam sufixul:
si compilam normal clasa A;
devine: https://localhost:8080/User/servlet/P.A
Prezentam în continuare un prim exemplu, cu câteva explicatii necesare, urmând ca unele interfete, clasele si metode referitoare la servlet-uri sa fie descrise în continuare în detaliu.
Consideram urmatorul servlet:
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class Salut extends HttpServlet
care va fi invocat din browser prin:
https://server:8080/User/servlet/Salut?nume=Vasile&val=20
prin care se cere executarea servlet-ului Salut cu precizarea a doi parametri (siruri de caractere): nume cu valoarea Vasile si val cu valoarea În mod implicit, cererea este de tipul GET; corespunzator, va fi invocata metoda doGet a servlet-ului.
Browser-ul va afisa:
Furnizam în continuare informatiile necesare:
Salut este un servlet deoarece extinde clasa HTTPServlet
Pentru lucrul cu servlet-uri trebuie incluse declararile:
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
Servlet-ul Salut contine metoda doGet care este invocata la o cerere HTTP de tipul GET
Variabilele resp si req sunt obiecte de tipul indicat, care corespund cererii primite de la client, respectiv raspunsului care va fi transmis clientului.
Prin invocarea metodei setContentType se precizeaza ca tipul MIME al raspunsului întors clientului este un document HTML.
Prin invocarea metodei getWriter obiectul resp creeaza un flux de iesire out în care va fi introdus documentul HTML.
Obiectul req invoca metoda getParameter pentru a capta în variabilele locale nume si val valorile parametrilor din cererea HTTP care au numele nume si val
Variabila html de tip String primeste ca valoare sirul de caractere ce reprezinta documentul HTML ce va fi transmis clientului.
html este înscris în out
sirul de caractere "O.K." este afisat în fereastra deschisa de Tomcat.
Observatie. Sa presupunem ca dupa invocarea servlet-ului de catre client, pe server modificam acest servlet si îl compilam. Nu se garanteaza ca, la o noua invocare a servlet-ului de catre client, va fi folosita noua forma! În schimb, noua forma a servlet-ului va deveni sigur efectiva dupa oprirea si repornirea serverului.
Trimiterea de date catre server
Reamintim ca marcajul form are forma:
<form method=metoda action=clasa>
Exista doua modalitati de trimitere (corespunzatoare celor doua tipuri de cereri HTTP), dupa cum metoda este:
GET datele din formular sunt adaugate în URL-ul trimis, sub forma de perechi
(nume,valoare). Ele vor fi accesibile servlet-ului prin metodele:
getQueryString getParameter si getParameterValues
POST : datele sunt înglobate în antetele cererii. Ele vor fi accesibile servlet-ului prin
metoda getParameterValues sau prin citire din ServletInputStream
În functie de metoda aleasa, servlet-ul specificat prin clasa va executa metoda doGet sau metoda doPost. Alte detalii despre cele doua tipuri de cereri HTML, respectiv despre metodele doGet si doPost, vor fi furnizate ulterior.
Exemplu. Dorim sa trimitem siruri de caractere catre server.
Vom folosi un formular care contine doar un câmp de text si un buton submit. La completarea câmpului de text si apasarea butonului, va fi întors mesajul transmis.
import java.io.*;
import javax.servlet.*; import javax.servlet.http.*;
public class TF extends HttpServlet
Observatie. O alternativa la executarea servlet-ului TF în modul precizat este de folosi urmatorul document HTML:
<html>
<head><title>Camp de text</title>
</head>
<body>
<form method=GET
action=https://localhost:8080/User/servlet/TF>
<p><input type=text name=tf maxlength=20>
<p><input type=submit name=Buton value=Apasa>
</form>
</body>
</html>
Reamintim ca acest document (fie TF.html numele sau) va fi plasat în mod tipic pe serverul de Web în directorul User, iar el va fi cerut de client prin:
https://server:8080/User/TF.html
|