Documente online.
Zona de administrare documente. Fisierele tale
Am uitat parola x Creaza cont nou
 HomeExploreaza
upload
Upload




Despre servlet-uri

Informatica


Despre servlet-uri

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 în 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 independente de platforma si care sunt în plus mult mai lente).

Gestionarea servlet-urilor

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 ( am copiat 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

Un prim exemplu

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.

Formulare în HTML

În exemplul de mai sus, clientul a trimis (prin intermediul browser-ului) o cerere severului de Web, care a raspuns cu un document HTML, pagina Web respectiva fiind afisata de browser.

Dorim însa mai mult si anume sa realizam un dialog "continuu" între client si server. O posibilitate consta în a folosi formularele din HTML, varianta studiata în acest paragraf. O alta posibilitate, dezvoltata într-un paragraf ulterior, consta în a folosi applet-uri pe partea de client.

Formulare

Formularele stau la baza crearii, cu ajutorul servlet-urilor, a paginilor HTML dinamice si a procesarii de catre server a datelor transmise de client prin intermediul lor. Pot fi create formulare multiple, dar independente. Ele au forma:

<form method=metoda action=clasa>

elemente de control

</form>

Despre metoda si clasa vom vorbi mai târziu.

Principalele elemente de control sunt:

câmpurile de text:

<input name=nume type=text value=val maxlength=n >

ariile de text:

< textarea name=nume cols=m rows=n >

butoanele de validare:

<input name=nume type=checkbox value=val checked >

permit alegerea multipla (a mai multor optiuni), care sunt siruri de caractere. Toate optiunile trebuie sa aiba acelasi nume nume si pentru fiecare poate fi precizat, prin prezenta lui checked, daca este selectat.

butoanele radio:

<input name=nume type=radio value=val checked >

difera de butoanele de validare prin aceea ca exact o optiune poate fi aleasa.

meniuri (liste derulante):

<select>

<option value=val selected> text </option>

<option value=val selected> text </option>

</select>

unde optiunile initial selectate sunt precizate prin selected.

butoanele de comanda:

<input name=nume type=tip value=val >

unde tip poate fi:

reset : câmpurile formularului revin la valorile initiale;

submit : câmpurile formularului sunt trimise catre server prin sirul de parametri;

push : este întreprinsa actiunea definita de autorul formularului.

nume de fisier:

<input type=file name=nume >

unde nume este numele unui fisier care este transmis; va aparea si un buton Browse a carui actionare va permite selectarea fisierului prin navigare în structura de directoare.

Exemplu. Sa consideram urmatorul document HTML cu numele form.html

<html>

<head> <title> Formular </title> </head>

<body>

<form method=GET action=???>

<p> Numele <input type=text name="Nume">

<p>

Ai studiat Informatica in liceu?

<input type=radio name="radio" value="Da" checked>

Da &nbsp &nbsp

<input type=radio name="radio" value="Nu"> Nu

<p>

Selecteaza cursurile favorite <br>

<input type=checkbox value="1"> Programare <br>

<input type=checkbox value="2" checked> Algoritmi <br>

<input type=checkbox value="3" checked>

Baze de date <br>

<p>

Forma de invatamant:

<Select name="valuta">

<option value="Inf"> Informatica </option>

<option selected value="MI"> Mat-Inf </option>

<option value="Col"> Colegiu </option>

</Select>

<p> Fisier catre server:<br>

<input type=file value="fisier" >

<p>

Butoane:<br>

<input type=reset name="Exit" value="Iesire">

<input type=submit name="Cerere" value="Cerere">

</form>

</body>

</html>

în care despre valoarea câmpului action din tag-ul form vom vorbi ulterior.

Browser-ul va afisa:

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

Clase si interfete folosite în lucrul cu servlet-uri

Clasele si interfetele pe care le-am ales pentru a fi prezentate apar în urmatoarele doua pachete:

Pachetul javax.servlet

Interfete:

public interface Servlet

public interface ServletRequest

public interface ServletResponse

Clase:

public abstract class ServletInputStream

public abstract class ServletOutputStream

public abstract class GenericServlet

implements Servlet, Serializable

Pachetul javax.servlet.http

Interfete:

public interface HttpServletRequest

extends ServletRequest

public interface HttpServletResponse

extends ServletResponse

Clase:

public abstract class HttpServlet
extends GenericServlet

Prezentarea va fi facuta tratând separat clasele/interfetele referitoare la: servlet-uri, cereri, raspuns, fluxuri.

Servlet-uri

Ne vom ocupa în principal de clasa HTTPServlet, care extinde GenericServlet, care la rândul sau implementeaza interfata Servlet

Precizam ca GenericServlet defineste un servlet independent de protocol, iar HttpServlet este specifica protocolului HTTP.

Restrângem prezentarea la doua metode de serviciu ale servlet-urilor:

protected void doGet(HttpServletRequest req,

HttpServletResponse resp)

throws ServletException, IOException

Aceasta metoda este invocata de server în momentul în care primeste o comanda HTTP de tip GET. În mod tipic, metoda trebuie ca, folosind informatia din parametrul req, sa întreprinda actiunile corespunzatoare si sa plaseze rezultatele în fluxul de iesire creat pe baza parametrului resp

protected void doPost(HttpServletRequest req,

HttpServletResponse resp)

throws ServletException, IOException

Aceasta metoda difera de doGet prin aceea ca este invocata de server în momentul în care primeste o comanda HTTP de tip POST. Alte diferente vor fi prezentate în continuare.

Ciclul de viata al unui servlet

Servlet-ul este un program Java care ruleaza în cadrul unui server de Web. De fapt serverul de Web creaza un container în cadrul caruia este executat servlet-ul. Pentru simplificare, vom considera ca acest container este chiar serverul de Web.

În literatura de specialitate apare afirmatia "servlet-ul este un applet pe partea de server". Afirmatia se bazeaza pe analogia între ciclul de viata al unui applet si ciclul de viata al unui servlet.

Principalele metode care guverneaza lucrul cu servlet-uri sunt:

Metoda init()

este declarata în clasa GenericServlet prin:

public void init() throws ServletException

Metoda este invocata numai la crearea servlet-ului. Un servlet este creat prima data când un utilizator invoca URL-ul corespunzator servlet-ului. În concluzie, la invocari ulterioare metoda init() nu mai intra în actiune.

Prin aceasta metoda putem face diverse initializari, ca de exemplu stabilirea unei conexiuni la o baza de date.

Metoda service()

este declarata în clasa GenericServlet prin:

public abstract void service(ServletRequest req,
ServletResponse resp)
throws ServletException, java.io.IOException

De fiecare data când serverul de Web primeste o cerere pentru un servlet, lanseaza un nou fir de executare si invoca metoda service Metoda detecteaza tipul cererii HTTP si invoca în mod corespunzator una dintre metodele de serviciu doGet si doPost.

Putem evita metoda service furnizând implementari pentru metodele doGet si doPost, asa cum vom proceda de obicei în continuare. Totusi metoda service îsi gaseste utilitatea în situatia existentei unei conditii în functie de care se invoca doGet sau doPost.

Daca dorim ca ambele tipuri de cerere sa fie tratate identic, specificam în doGet actiunea corespunzatoare si folosim metoda doPost urmatoare:

public void doPost(HttpServletRequest req,

HttpServletResponse resp)

throws ServletException, IOException

Metoda destroy()

este declarata în clasa GenericServlet prin:

public void destroy()

Aceasta metoda este invocata de serverul de Web la cererea administratorului sau în cazul în care servlet-ul nu primeste cereri o perioada îndelungata de timp. În metoda sunt precizate de obicei eliberari de resurse alocate prin init(), ca de exemplu întreruperea unei conexiuni cu o baza de date. Instanta servlet creata prin init() este distrusa.

Recapitulând, ciclul de viata al unui servlet poate fi figurat astfel:


Este important de retinut ca cereri adresate unui servlet de catre mai multi clienti au ca efect crearea pentru fiecare client a unui fir de executare care invoca metoda service a unicei instante a servlet-ului. În consecinta câmpurile servlet-ului sunt comune tuturor firelor, chiar daca nu sunt declarate cu modificatorul static. Rezolvarea problemelor de concurenta ce pot aparea prin folosirea de catre mai multe fire a unor resurse comune (câmpurile servlet-ului) cade în sarcina programatorului.

Exemplificam cele de mai sus prin prezentarea unui servlet care numara de câte ori a fost invocat.

import java.io.*;

import javax.servlet.*; import javax.servlet.http.*;

public class Accese extends HttpServlet

La fiecare cerere, atât în fereastra Tomcat-ului cât si pe fiecare client apare numarul total de invocari ale servlet-ului.

Într-un capitol urmator vom arata cum putem tine evidenta numarului de cereri pentru fiecare client.

Cereri

Prezentam în continuare câteva metode ale interfetei HTTPServletRequest, precizând care dintre ele este mostenita de la interfata ServletRequest

Interfata HTTPServletRequest defineste un obiect care permite servlet-ului sa identifice informatia trimisa de client. Containerul servlet creaza un obiect de acest tip, continând cererea catre servlet, pe care îl transmite ca argument metodelor de serviciu. Sunt incluse aici numele si valorile parametrilor din cerere, atribute si fluxul de intrare.

public String getMethod()

întoarce numele metodei continuta în cerere;

public String getQueryString()

întoarce sirul de parametri ce urmeaza caii din URL. Daca nu apar parametri, metoda întoarce null. Cum de obicei prima tranzactie se face fara parametri, metoda poate fi folosita pentru a identifica aceasta prima tranzactie;

public String getRequestURI()

întoarce portiunea din cerere dintre numele protocolului si querystring

public String getContextPath()

întoarce portiunea din URI care precizeaza contextul cererii;

public String getServletPath()

întoarce portiunea din URI care invoca servlet-ul.

Urmatoarele metode sunt mostenite de la interfata ServletRequest

public String getRemoteAddr()

întoarce adresa IP numerica a clientului;

public String getServerName()

întoarce adresa IP simbolica a serverului;

int getServerPort()

întoarce portul prin care comunica serverul;

public String getContentType()

întoarce tipul MIME al cererii sau null (daca acest tip nu a fost precizat). Pentru anumite tipuri MIME, sirul de caractere întors contine si alte informatii; de exemplu pentru tipul "multipart/form-data" mai este inclus si sirul de carcatere ce constituie linia separatoare (vezi paragraful referitor la transmiterea de fisere între client si server).

Metoda getInputStream va fi prezentata atunci când vom vorbi despre fluxuri.

Urmatoarele doua metode permit accesarea parametrilor din sirul de parametri adaugati comenzii HTTP, de exemplu prin actionarea unui buton de tip submit

public String getParameter(String nume)

întoarce valoarea parametrului-cerere nume, sau null daca acesta nu exista. În cazul în care parametrului-cerere îi sunt asociate mai multe valori (caz în care de fapt trebuie folosita metoda getParameterValues), metoda întoarce prima informatie întoarsa de metoda getParameterValues.

public String[] getParameterValues(String nume)

întoarce un tablou cu valorile asociate parametrului-cerere nume. Metoda este folosita atunci când parametrul-cerere are mai multe valori (de exemplu cele selectate în cadrul unui meniu). Daca nume nu exista, este întors null

Exemplu. Consideram urmatorul servlet:

import java.io.*;

import javax.servlet.*;

import javax.servlet.http.*;

public class Ex1 extends HttpServlet

La executare, browser-ul va afisa:

RemoteAddr : 127.0.0.1
Method : GET
ServerName : localhost
ServerPort : 8080
RequestURI : /User/servlet/Ex1
ContextPath : /User
ServletPath : /servlet/Ex1

ContentType : null

Raspuns

Interfetele:

public interface ServletResponse

public interface HttpServletResponse extends ServletResponse

definesc un obiect prin intermediul caruia servlet-ul transmite un raspuns clientului, raspuns dirijat catre fluxul de iesire atasat acestui obiect. HttpServletResponse furnizeaza în plus functionalitate HTTP.

Dintre metode mentionam doar urmatoarele:

public void setContentType(String tip)

în care tip precizeaza versiunea protocolului MIME (de exemplu "text/html" folosit la transmiterea raspunsului;

public void addHeader(String s1, String s2)

prin care se adauga antetul (header-ul) cu numele s1 si cu valoarea s2 Un exemplu va fi prezentat în capitolul referitor la transmiterea de fisiere.

Fluxuri

Pentru fluxurile de intrare este folosita clasa:

public abstract class ServletInputStream extends InputStream.

Un flux de intrare poate citi date la nivel de octet, furnizând în plus metoda readLine pentru citirea de linii:

public int readLine(byte[] octeti, int depl, int nr)

citeste în octeti câte o linie din fluxul de intrare, plecând de la pozitia curenta, cu deplasarea depl. Metoda se termina fie la detectarea sfârsitului de linie dupa citirea a maximum nr octeti (caz în care rezultatul întors este numarul de octeti cititi), fie la citirea a nr octeti fara detectarea sfârsitului de linie (caz în care întoarce valoarea -1).

Pentru un obiect-cerere (de unul dintre tipurile ServletRequest sau HttpServletRequest) putem regasi fluxul de intrare prin invocarea urmatoarei metode a clasei ServletRequest

public ServletInputStream getInputStream()

Pentru fluxurile de iesire este folosita clasa:

public abstract class ServletOutputStream extends OutputStream

Pentru un obiect-raspuns (de unul dintre tipurile ServletResponse sau HttpServletResponse) putem regasi fluxul de iesire prin invocarea uneia dintre metodele urmatoare, ambele folosite daca dorim ca transmiterea sa se faca la nivel de octet:

public ServletOutputStream getOutputStream()

din interfata ServletResponse

public PrintWriter getWriter()

din interfata HttpServletResponse. Invocarea metodei flush() încheie acest raspuns. Setarea versiunii MIME (prin setContentType) trebuie facuta înainte de a folosi acest flux de iesire.

Exemplu. Dorim sa trimitem serverului un nume de fisier, folosind metoda POST. Servletul va folosi fluxul sau de intrare pentru a citi din el numele fisierului.

Clientul va cere prin intermediul browser-ului fisierul File.html urmator:

<html>

<head> <title> Formular </title> </head>

<body>

<form method=POST

action=https://adresa_server:8080/User/servlet/File>

<p> Fisier catre server:<br>

<input type=file name=fisier >

<p> Buton:<br>

<input type=submit name=Buton value=Apasa>

</form>

</body>

</html>

În fereastra browser-ului vor aparea un câmp de text, un buton cu eticheta Browse si un al doilea buton cu eticheta Apasa

Actionarea butonului Browse permite alegerea unui fisier al carui nume (cu calea completa) este înscris în câmpul de text. Actionarea butonului Apasa transmite serverului aceste informatii, care le prelucreaza prin urmatorul servlet:

import java.io.*; import java.util.*;

import javax.servlet.*;

import javax.servlet.http.*;

public class File extends HttpServlet

Sunt necesare câteva explicatii.

S-a citit în s informatia din fluxul de intrare. Aceata informatie este prelucrata cu StringTokenizer, pentru care am prevazut delimitatorul '&'

Presupunând ca am ales sa trimitem numele de fisier autoexec.bat din C:, informatia afisata de server în fereastra Tomcat va avea forma:

fisier=C%3A%5CAUTOEXEC.BAT

Buton=Apasa

deoarece, la transmiterea informatiei, caracterul este înlocuit prin sirul de caractere "%3A", iar caracterul este înlocuit prin sirul de caractere "%5C", conform schemei de codare implicite.


Document Info


Accesari: 4198
Apreciat: hand-up

Comenteaza documentul:

Nu esti inregistrat
Trebuie sa fii utilizator inregistrat pentru a putea comenta


Creaza cont nou

A fost util?

Daca documentul a fost util si crezi ca merita
sa adaugi un link catre el la tine in site


in pagina web a site-ului tau.




eCoduri.com - coduri postale, contabile, CAEN sau bancare

Politica de confidentialitate | Termenii si conditii de utilizare




Copyright © Contact (SCRIGROUP Int. 2024 )