Componente Web
3.1. Introducere
In prezent cea mai populara aplicatie Internet este, fara indoiala, World Wide Web, pe scurt WWW. Aceasta permite utilizatorilor din intreaga lume sa colaboreze utilizand o serie de documente aflate intr-o continua schimbare. In WWW exista o distinctie clara intre partea de client si partea de server a aplicatiei. Un server WWW gestioneaza o serie de documente si le trimite la cerere clientilor. Browserul Web (clientul) are facilitati care permit utilizatorilor sa solicite documente stocate pe un server Web, afisandu-le pe monitor intr-un format corespunzator, in mod grafic. Protocolul utilizat pentru realizarea comunicatiei client – server este numit HyperText Transfer Protocol. Fiecare actiune in cadrul acestui protocol consta dintr-o cerere emisa de client in format ASCII si un raspuns elaborat de server, conform conventiilor MIME.
Componentele Web respecta tehnologia platformelor Java pentru constructia aplicatiilor care contin pagini Web dinamice, cum ar fi HTML, DHTML, XHTML si XML. Tehnologiile Java Server Pages sau Java Servlets, extind capacitatile serverelor Web, oferind o serie intreaga de avantaje, cum ar fi faptul ca pot rula pe orice platforma indiferent pe care a fost creat programul, accentueaza refolosirea componentelor JavaBeans sau Enterprise JavaBeans. Ele formeaza asa – numitul container web, parte integranta din Java 2 Enterprise Edition, ceea ce ii confera multe facilitati pentru aplicatiile Web.
Procesarea form-urilor HTML folosind Servleti sau JSP, este una dintre cele mai intalnite operatii executate pe Web in acest moment lucru ce se va observa si in exemplele capitolului de fata. De asemenea, acest capitol se vrea a fi o scurta, dar indrazneata prezentare a conceptelor de baza intalnite in utilizarea tehnologiilor bazate pe limbajul Java care au ca rol fundamental dezvoltarea aplicatiilor web.
3.2. Java Servlets
Java Servlets sunt programe Java, independente de platforma, utilizate pentru a extinde capacitatile serverelor web. Se poate face o paralela intre ceea ce reprezinta servletii pentru serverul web si ceea ce reprezinta applet – urile pentru client. Ambele sunt programe Java compilate (bytecode) care pot fi incarcate dinamic si extind capacitatile masinii. Totusi, appletul este o componenta client – side, care ruleaza intr-un browser web, in interiorul unei pagini web sau a unei interfete grafice, iar servletii fac parte din asa – numitele componente server – side, interactionand cu motorul servletului, suportat de catre serverul web, avand la baza conceptul de comunicatie cerere – raspuns (bazat la randul lui pe protocolul HTTP).
Aplicatia client, de exemplu web browser, acceseaza serverul web si trimite o cerere. Aceasta cerere este procesata de catre motorul servletului, instalat pe server – ul web. Acesta returneaza un raspuns servletului iar servletul returneaza la randul lui raspuns HTTP clientului.
Servletii folosesc clase din pachetele javax.servlet (pachetul Servlet principal) si javax.servlet.http (extensie a pachetului principal, pentru servlet-uri care raspund cererilor HTTP).
Caracteristic serveletilor HTTP avem:
procesarea si/sau stocarea unor date trimise de un form HTML
asigura un continut dinamic, de exemplu, returnarea unor date dintr-o baza de date
administrarea mai multor cereri HTTP
3.2.1. Comparatia cu CGI
Modul traditional de a adauga unele noi functii unui server web este cunoscutul model Common Gateway Interface (CGI). Acesta poate astfel permite server-ului pornirea unui proces extern ce preia informatii privind o anume cerere, prin intermediul unor variabile de mediu si care trimite datele de raspuns printate. Fiecare cerere este administrata intr-un proces de o instanta separata a programului (script-ului) CGI.
Avantajele servletilor fata de CGI:
Servlet-ul nu ruleaza intr-un proces separat, acesta elimina posibilitatea crearii de noi procese pentru fiecare cerere
Servletul este incarcat in memorie si ramane acolo intre cereri. Un program CGI este incarcat pentru fiecare cerere CGI. Exista o singura instanta care raspunde cerereilor simultane, acesta duce la salvarea de memorie si permite servletilor o administare mai usoara a datelor.
Servlet-ul poate fi rulat de motorul servletului (Servlet Engine) intr-o zona restrictiva (Sandbox), fapt care permite folosirea sigura a potentialelor.
3.2.2. Arhitectura principala a Servlet-ului 15673djd96rxv1o
Toti servletii implementeaza interfata Servlet sau, de cele mai multe ori, extind clasa HttpServlet care implementeaza interfata Servlet.
Interfata Servlet defineste metode pentru a initializa un servlet si de a comunica cu clientii.
Cand un servlet acepta o cerere de la un client, el primeste doua obiecte:
ServletRequest
ServletResponse
Ambele incapsuleaza comunicarea client – server.
Interfata ServletRequest permite servletului accesul la unele informatii cum ar fi numele parametrilor trimisi (pasati) de client, protocolul (http, https, ftp) folosit de client, numele clientului.
De asemenea ofera o clasa ServletInputStream prin care servletul primeste date de la clientii care folosesc protocolul HTTP prin metode ca POST si PUT. Subclasele lui ServletRequest permit serverului recuperarea de date specifice protocolului. De exemplu, clasa HttpServletRequest contine metode care pot accesa informatii specifice din antetul HTTP.
Interfata ServletResponse ofera metode pentru a raspunde clientului. Permite servletului setarea ContentLength (lungimea campului de date) precum si setarea tipului de date returnat MIME type oferind un ouput stream prin intermediul metodei getWriter(), sau a clasei ServletOutputStream.
Subclasele lui ServletResponse, ofera servletului mai multe capabilitati specifice protocolului. De exemplu HttpServletResponse contine metode care permit servletului manipularea de campuri specifice protocolului HTTP.
3.2.3. Ciclul de viata al unui Servlet
Cilclul de viata al unui servlet defineste modul in care servletul este incarcat si initializat, modul in care el primeste si raspunde cererilor, precum si modul de terminare a actiunii lui.
Incarcarea si instantierea – motorul servletului este cel care realizeaza aceste taskuri, cand acesta isi incepe activitatea, cand acesta trebuie sa raspunda unor cereri venite de la client. Motorul servletului foloseste facilitatile de incarcare ale claselor Java, putand realiza incarcarea fie de pe un sistem local de fisiere, fie de pe unul aflat la distanta, sau chiar de pe o sursa de retea.
Initializarea – dupa incarcare, motorul servletului trebuie sa initializeze servletul. Initializarea este utilizata in special pentru citirea datelor persistente, ce pot fi stocate, pentru initializarea conexiunii la o baza de date, precum si pentru stabilirea referintelor la alte resurse. Cea care furnizeaza servletului informatii de initializare este metoda init() a interfetei javax.servlet.Servlet, astfel ca servletul este pregatit pentru autoconfigurare. Obiectul de configurare, de tip ServletConfig, este transmis ca si parametru metodei init(). Acesta este implementat in motorul servletului, permitand servletului sa acceseze parametrii pereche nume – valoare din informatia de configurare. De asemenea, furnizeaza acces la obiectul de tip ServletContext.
Tratarea cererilor – dupa ce este initializat servletul este gata pentru a raspunde cererilor clientilor, reprezentate ca obiect de tip ServletRequest. Servletul raspunde cererii printr-un obiect de tip ServletResponse. Cand un client executa o cerere, motorul servletului trimite servletului ambele obiecte, atat response cat si request ca si parametrii metodei service(), definita de interfata Service, implementata de catre servlet.
Distrugere unui servlet – motorul serverului nu este obligat pentru a mentine in viata un servlet pe toata perioada de rulare a serverului. In cazul in care motorul servletului doreste eliberarea unor resurse, sau oprirea sa, se va apela metoda destroy(), implementata de servlet, respectand in prealabil un anumit interval de timp dupa executia ultimului apel al metodei service().
Definirea obiectului de tip ServletContext - prin utilizarea acestui tip de obiect servletul poate trata evenimente, poate obtine resurse si obiecte de la motorul servletului, de exemplu, obiect de tip RequestDispatcher. Un servlet poate rula intr-un singur context de servlet, dar servleti diferiti pot avea vizualizari diferite asupra motorului servletului.
Sesiuni HTTP. Pentru a realiza o aplicatie web, trebuie sa se asigure identificarea unor serii de cereri unice trimise de clientul aflat la distanta. Java Servlet API furnizeaza o interfata simpla care sa permita motorului servletului utilizarea unui numar de tehnici de tratare a sesiunii dedicata unui utilizator.
3.2.4. Scrierea unui servlet
Servletii implementeaza interfata javax.servlet.Servlet. Astfel:
Se pot scrie servleti care implementeaza direct aceasta interfata dar de obicei acest lucru nu este necesar, deoarece de obicei servletii sunt folositi cu protocolul HTTP, utilizand o clasa mai specializata javax.servlet.http.HttpServlet
Clasa HttpServlet implementeaza interfata Servlet prin extinderea clasei de baza GenericServlet si ofera un mod de lucru pentru manipularea protocolului HTTP. Ea poate suporta mai multe fire de executie simultane ruland mai multe metode service(). In cazurile in care se doreste ca un singur serviciu sa ruleze la un moment dat, aditional se implementeaza si interfata SingleThreadModel. Aceasta nu impune scrierea unor alte metode, ajunge doar implementarea intrefetei.
3.2.5. Interactiunea cu clientii jx673d5196rxxv
Clasa HttpServlet este o clasa abstracta, iar clasa care o extinde trebuie sa suprascrie unele metode proiectate pentru a manevra cereri HTTP. Aceste metode sunt :
doGet pentru a manevra cereri de tip GET si HEAD
doPost pentru cereri de tip POST
doPut pentru cereri de tip PUT
doDelete pentru cereri de tip DELETE
Implicit aceste metode returneaza mesaj de BAD_REQUEST (400).
Ca si avantaje ale servleturilor putem aminti comunicatia inter-servlet. Pe un server exista mai multe servleturi. Prin apelarea metodei getServletNames(), se returneaza lista cu ceilalti servleti. Comunicarea insa este putin mai complicata deoarece trebuie sa se aiba in vedere ca servletii sunt incarcti de ClassLoader. Pentru a putea face o comunicare trebuie definita o interfata care este incarcata de de SystemLoader si prin care se poate face comunicarea (cu ajutorul obiectelor).
3.2.6. Comunicarea cu resursele serverului
Servletul poate face o cerere spre server la fel ca orice client. Poate accesa resursele pasive ale serverului cum sunt fisierele HTML prin metoda getResouce() din clasa ServletContext. De asemenea mai poate executa:
3.2.7. Exemple
Accesarea unei baze de date prin intermediul unui servlet
DBHandler.java |
import javax.servlet.*;
import javax.servlet.http.*;
import java.util.*;
import myPackage.myBean;
public class DBHandler extends HttpServlet {
public void doPost (HttpServletRequest req, HttpServletResponse res){
try {
myBean bean = (myBean) req.getAttribute(“formHendler”);
boolean userExists = false;
// obtinerea conexiunii la baza de date
// executia unei interogari a bazei de date
// asigurarea ca nu exista un utilizator cu acelasi identificator
// setarea flagului userExists la “true” daca exista user cu acelasi id
if(userExists){
bean.setErrors(“userName”, “Duplicate User”);
getServletConfig().getServletContext().getRequestDispatcher( “/jsp/myforms/retry.jsp” ).forward(req, res);
}
else{
//citirea propritatilor beanului si stocarea lor in baza de date
getServletConfig().getServletContext().getRequestDispatcher( “/jsp/myforms/success.jsp” ).forward(req, res);
}
}
catch (Exception e){
e.printStackTrace();
}
}
} |
Afisarea continutului unui form HTML intr – o pagina HTML generata dinamic de catre un Servlet.
Form2.java |
package myPackage;
import java.io.PrintWriter;
import java.io.IOException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.ServletException;
public class Form2 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
response.setContentType("text/html");
File htmlFile = new File("E:/…../com/javapal/CellQuotes/CQForm.htm");
PrintWriter responseWriter = response.getWriter();
BufferedReader fileReader = new BufferedReader(new FileReader(htmlFile));
String line;
while((line = fileReader.readLine()) != null)
{
responseWriter.println(line);
responseWriter.flush();
}
fileReader.close();
responseWriter.close();
……………………..
}
|
Citirea a trei imagini de la un URL clar stabilit, a 5 String-uri dintr-o baza de date si afisarea lor in interiorul unei pagini HTML dinamice alaturi de 5 componente grafice de tip .
Form1.java |
package myPackage;
import java.io.PrintWriter;
import java.io.IOException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.ServletException;
public class Form1 extends HttpServlet {
Conect con = new Conect();
int id=0;
public void service (HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException
{
response.setContentType("text/html");
// out e stream-ul de lucru
PrintWriter out = response.getWriter();
//continutul intrebarii citit din DB
String continutIntrebare = " ";
String rasp = " ";
// strTab tabloul pt stocare String-uri citite din DB
String [] strTab = new String[5];
try{
//metoda getStringDB citeste String din baza de date
continutIntrebare = con.getStringDB("cont", 1, "2");
for (int i=1; i<6; i++)
{
strTab[i-1] = con.getStringDB("R"+i, 1, "2");
}
}
catch (Exception e){
}
out.println("<html>" +
"<head><title>First Form</title></head>" +
"<body bgcolor=\"#FFFFFF\">" +
"<center>" +
"<hr> <br> " +
"<h1>" +
"<font size=\"+3\" color=\"blue\">Connected to </font>" +
"<font size=\"+3\" color=\"blue\">The Testing System </font>" +
"</h1>" +
"</center>" +
"<br> <hr> <br> ");
for(int i=1;i<=strTab.length;i++){
out.println("<FORM METHOD=POST>"+
continutIntrebare+
"<P><INPUT TYPE=\"checkbox\" NAME=\"R1\">"+strTab[0]+
"<BR><INPUT TYPE=\"checkbox\" NAME=\"R2\">"+strTab[1]+
"<BR><INPUT TYPE=\"checkbox\" NAME=\"R3\">"+strTab[2]+
"<BR><INPUT TYPE=\"checkbox\" NAME=\"R4\">"+strTab[3]+
"<BR><INPUT TYPE=\"checkbox\" NAME=\"R5\">"+strTab[4]+
"</FORM>"+
"<IMG SRC=\"https://icar.utcluj.ro/~cporumb/AulaDomsa.jpg\" LOWSRC=\"https://icar.utcluj.ro/~cporumb/AulaDomsa.jpg\" HEIGHT=180 WIDTH=250 ALT=\"violets\">"+
"<IMG SRC=\"https://icar.utcluj.ro/~cporumb/Picture1.jpg\" LOWSRC=\"https://icar.utcluj.ro/~cporumb/Picture1.jpg\" HEIGHT=180 WIDTH=250 ALT=\"violets\">"+
"<IMG SRC=\"https://icar.utcluj.ro/~cporumb/Picture2.jpg\" LOWSRC=\"https://icar.utcluj.ro/~cporumb/Picture2.jpg\" HEIGHT=180 WIDTH=250 ALT=\"violets\">"+
"<br> <hr> <br> ");
}
out.println("<Form Method=Post>"+
"<br> <hr> <br> "+
"<input type=\"submit\" value=\"Submit\">"+
"<br> <hr> <br> ");
out.close();
}
} |
3.3. Tehnologia JSP
Java Server Pages este o simpla dar puternica tehnologie folosita pe partea de server pentru a genera continut HTML dinamic. JSP este o extensie directa a Java Servlets si furnizeaza o modalitate de a separa partea de procesare de cea de prezentare. Motorul JSP este doar un alt Servlet, mapat la extensia *.jsp.
O pagina JSP este un document bazat pe text care descrie cum se va procesa o cerere (request) pentru a crea un raspuns (response). Sunt amestecate date sablon (template data) cu anumite actiuni dinamice si mecanisme din cadrul platformei Java. In continuare se prezinta un fisier simplu JSP:
|
<HTML>
<BODY>
<% out.println(“HELLO JSP WORLD”); %>
</BODY>
</HTML> |
Paginile JSP sunt create sa suporte mai multe tipuri de documente structurate, indeosebi HTML si XML. In general, JSP-urile folosesc anumite informatii pe care le trimit la server intr-o cerere HTTP care interactioneaza cu datele existente pe acesta si creaza dinamic un raspuns organizat intr-un format standard (HTML, DHTML, XML, etc.) sau intr-un format text sau neorganizat ce va fi trimis inapoi clientului. O aplicatie Web are la baza:
Java Runtime Environment, ce va rula obligatoriu pe server
JSP page, care preia cererile si genereaza un continut dinamic
Java Servlets, cu acelasi rol ca si JSP
JavaBeans, componenta server-side care incapsuleaza comportamente si stari
pagini statice HTML, XML, DHTML,…
Java Applets sau JavaBeans, componente client-side si eventual alte fisiere Java de tip class
Java Runtime Environment care sa ruleze pe client si care sa poata fi incarcate prin plug-in
Java Server Pages mostenesc de la Servlets concepte despre Applications, ServletContexts, Sessions, Requests si Responses.
Paginile JSP sunt unice prin faptul ca ele pot contine atat continut cat si cod de reprezentare. Astfel ofera o multitudine de optiuni in proiectarea de aplicatii usor de intretinut si extins. Optiunile disponibile pentru intreteserea continutului cu codul, includ componente JavaBeans, tag-uri personalizate si scriplets.
3.3.1. Directive
Directivele sunt elemente JSP care furnizeaza informatii globale despre pagina JSP. Ele au urmatoarea sintaxa:
|
<%@ directive {attribute=“value”} %> |
In exemplul de mai sus se specifica asignarea valorii value ca si atribut. O directiva poate contine n optiuni ale perechilor atribut/valoare. La momentul potrivit veti observa utilitatea acestor directive. Exista trei directive, diferite de specificatiile JSP: page, include si taglib.
3.3.1.1. Directiva page
Aceasta directiva defineste informatii disponibile global pentru JSP. In cele ce urmeaza vom aminti cateva setari care vor afecta direct compilarea unei pagini JSP :
-language=“scriptingLanguage” – atribut care spune serverului ce limbaj sa foloseasca la compilare.
-extends=“className” – atribut care defineste clasa de baza a serverului generat.
-import=“importList” – atribut care defineste o lista de pachete disponibile JSP-ului.
-session=“true|false” – atribut care defineste disponibilitatea datelor de sesiune in cadrul paginii.
-buffer=“none|size in kb” – determina daca stream-ul de scriere (OutputStream) este sub forma de buffer.
-autoFlush=“true|false” – determina daca stream-ul amintit mai sus va fi golit automat.
-isThreadSafe=“true|false” – specifica daca motorul JSP poate raspunde la mai mult de o cerere la un moment dat.
- info=“text” – specifica daca pagina JSP poate fi accesata de metoda getServlet a servletului generat.
-errorPage=“error_url” – URL-ul relativ catre pagina JSP care prinde exceptiile.
-isErrorPage=“true|false” – specifica daca pagina JSP este o pagina de eroare.
-contentType=“ctinfo” – reprezinta tipul MIME si setul de caractere de raspuns.
3.3.1.2. Directiva include
Directiva include este folosita pentru inserare de cod si text . Are urmatoarea sintaxa:
|
<%@ include file=“relativeURLspec” %> |
De obicei fisierul spre care se face referire este fie un fisier text, fie unul HTML, dar nu este exclus sa fie chiar o sursa JSP.
3.3.1.3. Directiva taglib
JSP prezinta un mecanism de extindere a setului curent de tag-uri JSP care se realizeaza prin crearea unei bilbioteci de tag-uri, taglib.
Se specifica astfel faptul ca o pagina foloseste tag-uri particularizate, unice prin nume si asociaza prefixul tag pentru distingerea lor in utilizare. Sintaxa arata astfel:
|
<%@ taglib uri=“tagLibraryURI” prefix=“tagPrefix” %> |
uri: referentiaza un URI care in mod unic numeste un set de taguri.
prefix: defineste prefixul folosit pentru a distinge o instanta a tag-ului particularizat.
3.3.1.4. Actiuni
Actiunile furnizeaza o abstractizare folosita usor pentru a incapsula diferite task-uri. Ele creaza obiecte de tip JavaBeans si actioneaza asupra lor. Tehnologia JSP suporta cateva actiuni standard:
<jsp:useBean> instantiaza un obiect de tip JavaBean avand un scop dat si un id
<jsp:setProperty> seteaza valoarea unei proprietati a Bean-ului
<jsp:getProperty> preia valoarea proprietatii unei instante a unui Bean, o converteste intr-un String pregatind-o pentru afisare
<jsp:include> furnizeaza un mecanism pentru a include resurse statice si dinamice in pagina JSP curenta. Are sintaxa:
|
<jsp:include page=“urlSpec” flush=“true” /> |
sau
|
<jsp:include page=“urlSpec” flush=“true”>
{ jsp:param ... /> }
</jsp:include> |
<jsp:forward> permite ca un motor JSP sa comunice runtime, cererea curenta catre o resursa statica, Servlet sau alt JSP. Actiunea se termina efectiv cand se termina executia paginii curente. Are sintaxa:
|
<jsp:forward page=“relativeURLspec” /> |
sau
|
<jsp:forward page=relativeURLspec”>
{ <jsp:param .../> }
</jsp:forward> |
<jsp:plugin> face posibila generarea unei pagini HTML care contine constructii dependente de browser, de exemplu, OBJECT sau EMBED, care va rezulta in download-ul unui plug-in Java si in executia subsecventiala a appletului specificat sau a componentei JavaBeans. Exista posibilitatea inlocuirii tag-ului <jsp:plugin> de un tag <object> sau <embed>, in functie de cerere, si noul tag este trimis ca raspuns. Atributele actiunii <jsp:plugin> furnizeaza date de configurare pentru prezentarea elementului. Are sintaxa:
|
<jsp:plugin type=“pluginType”
code=“classFile”
codebase=“relativeURLpath”>
<jsp:params>
...
</jsp:params>
</jsp:plugin>
|
Un exemplu simplu de pagina JSP care combina Script HTML si Beans este cel de mai jos, care afiseaza numele de login al clientului cand acesta solicita o pagina prin intermediul unui form HTML:
Pagina contine comenzi sablon, intalnite in orice pagina HTML si cateva elemente JSP, subliniate. Raspunsul este creat pe baza comenzilor HTML. Cand s-a ajuns la primul element JSP este creat un obiect server-side Bean cu numele ‘login’ de tip ‘Profi.Login’. Acest obiect va putea fi folosit si utilizat mai tirziu in pagina. Urmatoarele doua elemente JSP acceseaza proprietatile obiectului si insereaza aceste valori in pagina response ca String.
3.3.2. Semantica JSP
3.3.2.1. Interpretarea si executia paginilor JSP
O pagina JSP este executata intr-un container JSP (JSP container), instalat pe un server Web. Acesta preia cererile de la client si le livreaza paginii JSP, returnand rezultatele. Structura semantica a JSP-ului este aceeasi ca si la servleti, prin descrierea modului de creare a obiectul raspuns pornind de la un obiect cerere, pentru un anumit protocol dat, cu posibilitatea folosirii unor alte obiecte deja create. Toate containerele JSP trebuie sa suporte protocolul HTTP, ca si protocol cerere/raspuns. Un container JSP poate sa suporte si alte protocoale. Obiecte cerere/raspuns implicite sunt de tip HttpServletRequest si HttpServletResponse. De asemenea o pagina poate sa indice cum se trateaza anumite evenimente, de exemplu, JSP 1.1 poate doar sa initializeze si sa distruga un event. O pagina JSP este reprezentata de o JSP page implementation class care implementeaza interfata javax.servlet.Servlet. De multe ori paginile JSP sunt implementate folosind JSP translation phase care se poate utiliza o singura data, urmata de un request processing phase, care se foloseste o singura data pe cerere.
O pagina va contine cateva declaratii, comenzi standard (fixed template), actiuni (action instances) cel mai frecvent incuibarite si elemente script. Cand o cerere este livrata paginii, toate aceste elemente sunt folosite ca sa creeze obiectul raspuns ce se returneaza clientului. O pagina JSP descrie etapele de creare a unui obiect reponse pe baza unui obiect request pentru un protocol dat, cu posibilitatea crearii si/sau utilizarii altor obiecte. O pagina JSP este executata de un container JSP; cererile trimise paginii sunt livrate de catre container unei JSP page implementation care este o subclasa de Servlet.
O aplicatie Web este o colectie de resurse disponibile prin in