Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
laboratoare:laborator04 [2015/11/13 03:44]
Andrei Roșu-Cojocaru [Ciclul de viață al unui Java Servlet]
laboratoare:laborator04 [2015/11/20 03:05] (current)
Andrei Roșu-Cojocaru
Line 53: Line 53:
 Un servlet reprezintă o clasă implementată în limbajul de programare Java, utilizată pentru a extinde capabilităţile unui server care găzduieşte aplicaţii accesate conform **modelului cerere-răspuns**. Cea mai frecvent întâlnită funcţionalitate în legătură cu un servlet este legată de aplicaţiile web, cu toate că acesta poate răspunde oricărui tip de cereri. Prin urmare tehnologia Java Servlet defineşte clase servlet adaptate protocolului HTTP. Un servlet reprezintă o clasă implementată în limbajul de programare Java, utilizată pentru a extinde capabilităţile unui server care găzduieşte aplicaţii accesate conform **modelului cerere-răspuns**. Cea mai frecvent întâlnită funcţionalitate în legătură cu un servlet este legată de aplicaţiile web, cu toate că acesta poate răspunde oricărui tip de cereri. Prin urmare tehnologia Java Servlet defineşte clase servlet adaptate protocolului HTTP.
   
-Pachetele ''​javax.servlet''​ şi ''​javax.servlet.http''​ oferă interfeţe şi clase pentru scrierea de Java Servlets. Orice servlet trebuie să implementeze interfaţa ​''​Servlet'' ​care defineşte metodele ce caracterizează ciclul de viaţă al unui astfel de obiect. Când este implementat un serviciu generic, se poate folosi (sau extinde) clasa ''​GenericServlet''​. Clasa ''​HttpServlet'' ​oferă metode precum ''​doGet()''​ şi ''​doPost()''​ pentru a trata servicii specifice protocolului HTTP.+Pachetele ''​javax.servlet''​ şi ''​javax.servlet.http''​ oferă interfeţe şi clase pentru scrierea de Java Servlets. Orice servlet trebuie să implementeze interfaţa ​[[http://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​Servlet.html|javax.servlet.Servlet]] care defineşte metodele ce caracterizează ciclul de viaţă al unui astfel de obiect. Când este implementat un serviciu generic, se poate folosi (sau extinde) clasa [[http://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​GenericServlet.html|javax.servlet.GenericServlet]]. Clasa [[http://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​http/​HttpServlet.html|javax.servlet.http.HttpServlet]] oferă metode precum ''​doGet()''​ şi ''​doPost()''​ pentru a trata servicii specifice protocolului HTTP.
  
 {{ :​laboratoare:​laborator04:​02javaservlets_classhierarchy.png?​nolink&​200 }} {{ :​laboratoare:​laborator04:​02javaservlets_classhierarchy.png?​nolink&​200 }}
Line 151: Line 151:
  
 Prin urmare, orice clasă derivată din ''​HttpServlet''​ trebuie să implementeze cel puţin una dintre metodele: Prin urmare, orice clasă derivată din ''​HttpServlet''​ trebuie să implementeze cel puţin una dintre metodele:
-  * ''​doGet()''​, dacă servlet-ul tratează cereri ''​HTTP GET'';​ +  * [[http://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​http/​HttpServlet.html#​doGet-javax.servlet.http.HttpServletRequest-javax.servlet.http.HttpServletResponse-|doGet()]], dacă servlet-ul tratează cereri ''​HTTP GET'';​ 
-  * ''​doPost()''​, dacă servlet-ul tratează cereri ''​HTTP POST'';​ +  * [[http://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​http/​HttpServlet.html#​doPost-javax.servlet.http.HttpServletRequest-javax.servlet.http.HttpServletResponse-|doPost()]], dacă servlet-ul tratează cereri ''​HTTP POST'';​ 
-  * ''​doPut()''​, dacă servlet-ul tratează cereri ''​HTTP PUT'';​ +  * [[http://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​http/​HttpServlet.html#​doPut-javax.servlet.http.HttpServletRequest-javax.servlet.http.HttpServletResponse-|doPut()]], dacă servlet-ul tratează cereri ''​HTTP PUT'';​ 
-  * ''​doDelete()''​, dacă servlet-ul tratează cereri ''​HTTP DELETE'';​+  * [[http://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​http/​HttpServlet.html#​doDelete-javax.servlet.http.HttpServletRequest-javax.servlet.http.HttpServletResponse-|doDelete()]], dacă servlet-ul tratează cereri ''​HTTP DELETE'';​
  
-De regulă, metodele ​''​doOptions()'' ​şi ''​doTrace()'' ​sunt mai puţin utilizate.+De regulă, metodele ​[[http://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​http/​HttpServlet.html#​doOptions-javax.servlet.http.HttpServletRequest-javax.servlet.http.HttpServletResponse-|doOptions()]] şi [[http://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​http/​HttpServlet.html#​doTrace-javax.servlet.http.HttpServletRequest-javax.servlet.http.HttpServletResponse-|doTrace()]] sunt mai puţin utilizate.
  
 Totodată, este recomandat să se implementeze şi metodele: Totodată, este recomandat să se implementeze şi metodele:
Line 163: Line 163:
 <​note>​În general, în metodele ''​init()''​ şi ''​destroy()''​ sunt alocate şi dezalocate resurse partajate cum ar fi conexiunea la baza de date sau accesul la fişiere.</​note>​ <​note>​În general, în metodele ''​init()''​ şi ''​destroy()''​ sunt alocate şi dezalocate resurse partajate cum ar fi conexiunea la baza de date sau accesul la fişiere.</​note>​
  
-  * ''​getServletInfo()''​, folosit de servlet pentru a oferi informaţii despre el.+  * [[http://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​GenericServlet.html#​getServletInfo--|getServletInfo()]], folosit de servlet pentru a oferi informaţii despre el.
  
 {{ :​laboratoare:​laborator04:​04javaservlets_methods.png.png?​nolink&​400 }} {{ :​laboratoare:​laborator04:​04javaservlets_methods.png.png?​nolink&​400 }}
  
-O cerere conţine datele transmise de la client către servlet şi trebuie să implementeze interfaţa ​''​ServletRequest''​, unde sunt definite metode pentru accesarea de: +O cerere conţine datele transmise de la client către servlet şi trebuie să implementeze interfaţa ​[[http://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​ServletRequest.html|javax.servlet.ServletRequest]], unde sunt definite metode pentru accesarea de: 
   * parametri (pentru comunicarea de informaţii între clienţi / servleţi);   * parametri (pentru comunicarea de informaţii între clienţi / servleţi);
   * atribute – instanţe ale unor obiecte (folosite la comunicarea dintre un container al unui servlet şi servlet sau pentru comunicarea între mai mulţi servleţi);   * atribute – instanţe ale unor obiecte (folosite la comunicarea dintre un container al unui servlet şi servlet sau pentru comunicarea între mai mulţi servleţi);
Line 174: Line 174:
     * locaţie. ​     * locaţie. ​
  
-<note tip>​Aceste date pot fi analizate manual (parsarea unui flux de date) folosind un obiect ''​BufferedReader''​ creat dintr-un obiect ​''​ServletInputStream'' ​întors de metoda ​''​getInputStream()''​.</​note>​+<note tip>​Aceste date pot fi analizate manual (parsarea unui flux de date) folosind un obiect ''​BufferedReader''​ creat dintr-un obiect ​[[http://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​ServletInputStream.html|ServletInputStream]] ​întors de metoda ​[[http://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​ServletRequest.html#​getInputStream--|getInputStream()]].</​note>​
  
-Obiectul ​''​HttpServletRequest'' ​transmis prin cerere conţine URL-ul cererii, antetele HTTP şi interogarea formată din perechi de parametri şi valori.+Obiectul ​[[http://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​http/​HttpServletRequest.html|javax.servlet.http.HttpServletRequest]] ​transmis prin cerere conţine URL-ul cererii, antetele HTTP şi interogarea formată din perechi de parametri şi valori.
  
-<​note>​URL-ul cererii are forma %%http://​[adresa]:​[port]/​[cale]?​[interogare]%%,​ unde ''​cale''​ conţine, la rândul ei, calea contextuală (contexul aplicaţiei web în care rulează servlet-ul),​ calea către servlet (care indică componenta care procesează cererea) precum şi alte informaţii. Acestea pot fi obţinute apelând metodele: ​''​getContextPath()''​, ''​getServletPath()'' ​şi ''​getPathInfo()''​. Interogarea este compusă dintr-un set de parametrii ​şi valori ce pot fi obţinuţi ​ din obiectul cerere folosind metodele ​''​getParameterNames()'' ​şi ''​getParameter()''​. Interogările pot să apară explicit în URL-ul cererii, fiind anexat acesteia când se foloseşte metoda ''​HTTP GET''​ sau poate fi conţinut în pagina Internet.</​note>​+<​note>​URL-ul cererii are forma %%http://​[adresa]:​[port]/​[cale]?​[interogare]%%,​ unde ''​cale''​ conţine, la rândul ei, calea contextuală (contexul aplicaţiei web în care rulează servlet-ul),​ calea către servlet (care indică componenta care procesează cererea) precum şi alte informaţii. Acestea pot fi obţinute apelând metodele: ​[[http://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​http/​HttpServletRequest.html#​getContextPath--|getContextPath()]], [[http://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​http/​HttpServletRequest.html#​getServletPath--|getServletPath()]] şi [[http://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​http/​HttpServletRequest.html#​getPathInfo--|getPathInfo()]]. Interogarea este compusă dintr-un set de parametri ​şi valori ce pot fi obţinuţi ​ din obiectul cerere folosind metodele ​[[http://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​ServletRequest.html#​getParameterNames--|getParameterNames()]] şi [[http://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​ServletRequest.html#​getParameter-java.lang.String-|getParameter()]]. Interogările pot să apară explicit în URL-ul cererii, fiind anexat acesteia când se foloseşte metoda ''​HTTP GET''​ sau poate fi conţinut în pagina Internet.</​note>​
  
 Obiectul ''​HttpServletRequest''​ conţine atât denumirile parametrilor transmişi (metoda ''​getParameterNames()''​) cât şi valoarea lor (metoda ''​getParameter()''​ ce primeşte ca argument identificatorul acestuia). Obiectul ''​HttpServletRequest''​ conţine atât denumirile parametrilor transmişi (metoda ''​getParameterNames()''​) cât şi valoarea lor (metoda ''​getParameter()''​ ce primeşte ca argument identificatorul acestuia).
  
-Metodele mai folosite ale clasei ''​HttpServletRequest''​ sunt moștenite din clasa ''​ServletRequest'': ​''​getContentType()''​, ''​getInputStream()''​, ''​getParameter()''​, ''​getParameterNames()''​, dar și proprii: ​''​getCookies()''​, ''​getHeaderNames()''​, ''​getHeaders()''​, ''​getSession()''​, ''​getMethod()''​.+Metodele mai folosite ale clasei ''​HttpServletRequest''​ sunt moștenite din clasa ''​ServletRequest'': ​[[http://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​ServletRequest.html#​getContentType--|getContentType()]], [[http://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​ServletRequest.html#​getInputStream--|getInputStream()]], [[http://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​ServletRequest.html#​getParameter-java.lang.String-|getParameter()]], [[http://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​ServletRequest.html#​getParameterNames--|getParameterNames()]], dar și proprii: ​[[http://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​http/​HttpServletRequest.html#​getCookies--|getCookies()]], [[http://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​http/​HttpServletRequest.html#​getHeaderNames--|getHeaderNames()]], [[http://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​http/​HttpServletRequest.html#​getHeaders-java.lang.String-|getHeaders()]], [[http://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​http/​HttpServletRequest.html#​getSession--|getSession()]], [[http://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​http/​HttpServletRequest.html#​getMethod--|getMethod()]].
  
-Un răspuns conţine datele transmise de la servlet către client şi trebuie să implementeze interfaţa ​''​ServletResponse''​, unde sunt definite metode pentru obţinerea unui flux prin care se poate realiza comunicarea cu clientul, indicându-se tipul de conţinut (prin metoda ​''​setContentType()''​, al cărei parametru poate fi ''​text/​html''​),​ dacă se aloca o zonă de memorie (metoda ​''​setBufferSize(int)'' ​oferă ​ o perioadă timp înainte ca mesajul să fie transmis la client, permiţând ​ stabilirea unor coduri de stare sau a unor antete) şi informaţii despre locaţie. ​+Un răspuns conţine datele transmise de la servlet către client şi trebuie să implementeze interfaţa ​[[http://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​ServletResponse.html|javax.servlet.ServletResponse]], unde sunt definite metode pentru obţinerea unui flux prin care se poate realiza comunicarea cu clientul, indicându-se tipul de conţinut (prin metoda ​[[http://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​ServletResponse.html#​setContentType-java.lang.String-|setContentType()]], al cărei parametru poate fi ''​text/​html''​),​ dacă se aloca o zonă de memorie (metoda ​[[http://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​ServletResponse.html#​setBufferSize-int-|setBufferSize()]] oferă ​ o perioadă timp înainte ca mesajul să fie transmis la client, permiţând ​ stabilirea unor coduri de stare sau a unor antete) şi informaţii despre locaţie. ​
  
-<note tip>​Pentru transmiterea de date de tip caracter se foloseşte un obiect ​''​PrinterWriter'' ​întors de metoda ​''​getWriter()''​, în timp ce pentru transmiterea de date binare se foloseşte un obiect ​''​ServletOutputStream'' ​întors de metoda ​''​getOutputStream()''​.</​note>​+<note tip>​Pentru transmiterea de date de tip caracter se foloseşte un obiect ​[[http://​docs.oracle.com/​javase/​7/​docs/​api/​java/​io/​PrintWriter.html?​is-external=true|PrinterWriter]] întors de metoda ​[[http://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​ServletResponse.html#​getWriter--|getWriter()]], în timp ce pentru transmiterea de date binare se foloseşte un obiect ​[[http://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​ServletOutputStream.html|ServletOutputStream]] ​întors de metoda ​[[http://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​ServletResponse.html#​getOutputStream--|getOutputStream()]].</​note>​
  
 Obiectul ''​HttpServletResponse''​ are câmpuri care reprezintă antete HTTP ce conţin coduri de stare (pentru a indica motivele pentru care o cerere nu poate fi satisfăcută sau faptul că s-a realizat redirecţionarea către altă resursă) ca şi obiecte ce vor reţine informaţii specifice aplicaţiei (eventual, legate de sesiune) – //eng.// cookies, pe maşina clientului astfel încât persistenţa stării este realizată prin mecanisme implementate în afara serverului. Un astfel de mecanism este necesar datorită faptului că serverul nu dispune de alte posibilităţi pentru a identifica un client, în interacţiunea cu aplicaţia web pe care o găzduieşte. Obiectul ''​HttpServletResponse''​ are câmpuri care reprezintă antete HTTP ce conţin coduri de stare (pentru a indica motivele pentru care o cerere nu poate fi satisfăcută sau faptul că s-a realizat redirecţionarea către altă resursă) ca şi obiecte ce vor reţine informaţii specifice aplicaţiei (eventual, legate de sesiune) – //eng.// cookies, pe maşina clientului astfel încât persistenţa stării este realizată prin mecanisme implementate în afara serverului. Un astfel de mecanism este necesar datorită faptului că serverul nu dispune de alte posibilităţi pentru a identifica un client, în interacţiunea cu aplicaţia web pe care o găzduieşte.
  
-Obiectul ​''​HttpServletResponse'' ​este folosit pentru construirea documentului care va transmis de la server către client, într-un obiect de tip ''​PrintWriter''​.+Obiectul ​[[http://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​http/​HttpServletResponse.html|javax.servlet.http.HttpServletResponse]] ​este folosit pentru construirea documentului care va transmis de la server către client, într-un obiect de tip ''​PrintWriter''​.
  
-Metodele cele mai folosite din clasa ''​HttpServletResponse''​ sunt moştenite din clasa ''​ServletResponse'': ​''​flushBuffer()''​, ''​get/​setBufferSize()''​, ''​get/​setContentType()''​, ''​getOutputStream()''​, ''​setCharacterEncoding()''​, dar şi proprii: ​''​addCookie()''​, ''​get/​setHeader()''​, ''​get/​setStatus()''​.+Metodele cele mai folosite din clasa ''​HttpServletResponse''​ sunt moştenite din clasa ''​ServletResponse'': ​[[http://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​ServletResponse.html#​flushBuffer--|flushBuffer()]], [[http://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​ServletResponse.html#​getBufferSize--|getBufferSize()]],​ [[http://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​ServletResponse.html#​setBufferSize-int-|setBufferSize()]], [[http://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​ServletResponse.html#​getContentType--|getContentType()]],​ [[http://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​ServletResponse.html#​setContentType-java.lang.String-|setContentType()]], [[http://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​ServletResponse.html#​getOutputStream--|getOutputStream()]], [[http://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​ServletResponse.html#​setCharacterEncoding-java.lang.String-|setCharacterEncoding()]], dar şi proprii: ​[[http://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​http/​HttpServletResponse.html#​addCookie-javax.servlet.http.Cookie-|addCookie()]], [[http://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​http/​HttpServletResponse.html#​getHeader-java.lang.String-|getHeader()]],​ [[http://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​http/HttpServletResponse.html#​setHeader-java.lang.String-java.lang.String-|setHeader()]], [[http://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​http/​HttpServletResponse.html#​getStatus--|getStatus()]],​ [[http://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​http/​HttpServletResponse.html#​setStatus-int-|setStatus()]].
  
-Un servlet se găseşte de regulă pe un server capabil să ruleze mai multe fire de execuţie, astfel încât în condiţiile unor cereri simultane, trebuie sincronizat accesul la resurse partajate, cum ar fi date din memorie (variabile tip instanţă sau clase) sau obiecte externe (fişiere, conexiuni la baze de date sau conexiuni în reţea).+<note important>​Un servlet se găseşte de regulă pe un server capabil să ruleze mai multe fire de execuţie, astfel încât în condiţiile unor cereri simultane, trebuie sincronizat accesul la resurse partajate, cum ar fi date din memorie (variabile tip instanţă sau clase) sau obiecte externe (fişiere, conexiuni la baze de date sau conexiuni în reţea).</​note>​
  
 Un container ce conţine un servlet poate determina distrugerea acestuia (în cazul în care se realizează colectarea memoriei disponibile sau atunci când acesta se închide), apelându-se metoda ''​destroy()''​ din interfaţa ''​Servlet''​. Aici toate resursele utilizate de către servlet trebuie eliberate, asigurându-se şi persistenţa prin reţinerea informaţiilor necesare în baza de date. Toate metodele serviciu corespunzătoare unui servlet trebuie să fie terminate atunci când container-ul urmează să îl distrugă. Astfel, metoda ''​destroy()''​ este apelată doar după ce toate metodele serviciu s-au terminat sau după expirarea unei anumite perioade stabilită de server. Trebuie ca toate firele de execuţie pe care sunt realizate operaţii de către server să se termine atunci când este apelată metoda ''​destroy()''​. Un container ce conţine un servlet poate determina distrugerea acestuia (în cazul în care se realizează colectarea memoriei disponibile sau atunci când acesta se închide), apelându-se metoda ''​destroy()''​ din interfaţa ''​Servlet''​. Aici toate resursele utilizate de către servlet trebuie eliberate, asigurându-se şi persistenţa prin reţinerea informaţiilor necesare în baza de date. Toate metodele serviciu corespunzătoare unui servlet trebuie să fie terminate atunci când container-ul urmează să îl distrugă. Astfel, metoda ''​destroy()''​ este apelată doar după ce toate metodele serviciu s-au terminat sau după expirarea unei anumite perioade stabilită de server. Trebuie ca toate firele de execuţie pe care sunt realizate operaţii de către server să se termine atunci când este apelată metoda ''​destroy()''​.
Line 200: Line 200:
 <note tip>O soluţie ar fi contorizarea numărului de fire de execuţie care rulează şi invocarea ''​Thread.sleep()''​ cât timp acestea nu s-au terminat.</​note>​ <note tip>O soluţie ar fi contorizarea numărului de fire de execuţie care rulează şi invocarea ''​Thread.sleep()''​ cât timp acestea nu s-au terminat.</​note>​
  
-În exemplu, au fost preluaţi parametrii transmişi printr-un apel tip ''​POST''​ (presupunând că parametrii au fost specificaţi la crearea unui formular prin elemente de tip ''<​input>''​ - care nu au activat parametrul disabled, acestea nefiind transmise) şi reţinuţi în tabloul ''​values'',​ de unde pot fi prelucraţi. De asemenea, construirea răspunsului către client se face în metoda ''​displayForm()'',​ care primeşte un obiect de tip ''​PrinterWriter''​ în care se creează (prin apeluri ''​println()''​) pagina Internet care va fi afişată în browser.+În exemplu, au fost preluaţi parametrii transmişi printr-un apel tip ''​POST''​ (presupunând că parametrii au fost specificaţi la crearea unui formular prin elemente de tip ''<​input>''​ - care nu au activat parametrul disabled, acestea nefiind transmise) şi reţinuţi în tabloul ''​values'',​ de unde pot fi prelucraţi. De asemenea, construirea răspunsului către client se face în metoda ''​displayPage()'',​ care primeşte un obiect de tip ''​PrinterWriter''​ în care se creează (prin apeluri ''​println()''​) pagina Internet care va fi afişată în browser.
  
 ===== Implementarea unor funcționalități complexe ===== ===== Implementarea unor funcționalități complexe =====
Line 216: Line 216:
 De regulă, filtrele sunt folosite în procesul de autentificare,​ jurnalizare,​ conversie de imagini, compresie a datelor, criptare, parsarea fluxurilor de date, transformări XML. O resursă web poate fi filtrată printr-un lanţ ce conţine 0, 1 sau mai multe filtre într-o anumită ordine. De regulă, filtrele sunt folosite în procesul de autentificare,​ jurnalizare,​ conversie de imagini, compresie a datelor, criptare, parsarea fluxurilor de date, transformări XML. O resursă web poate fi filtrată printr-un lanţ ce conţine 0, 1 sau mai multe filtre într-o anumită ordine.
  
-În pachetul ''​javax.servlet'',​ filtrele sunt definite prin interfeţele ​''​Filter''​, ''​FilterChain'' ​şi ''​FilterConfig''​.+În pachetul ''​javax.servlet'',​ filtrele sunt definite prin interfeţele ​[[https://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​Filter.html|Filter]], [[https://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​FilterChain.html|FilterChain]] ​şi [[https://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​FilterConfig.html|FilterConfig]].
  
-Un filtru implementează interfaţa ''​javax.servlet.Filter''​ şi este adnotat cu însemnarea ​''​@WebFilter'' ​care trebuie să specifice cel puţin un URL (folosind atributele ​''​urlPatterns'' ​sau ''​value''​). Informaţiile cu privire la configurarea unui filtru sunt precizate prin atributul ​''​initParams al aceleiaşi adnotări''​. Metoda cea mai importantă a unui filtru este ''​doFilter()'' ​care primeşte cererea, răspunsul şi lanţul de filtre, în afară de ea trebuind implementate metodele ''​init()''​ şi ''​destroy()''​. Metoda ''​doFilter()''​ poate analiza antetele cererii şi răspunsului (doar după invocarea următorului filtru din lanţul de filtre), poate particulariza obiectele cerere şi răspuns în sensul modificării antetelor sau conţinutului,​ poate invoca următorul filtru din lanţul de filtre (prin apelarea metodei ''​doFilter()''​ a acestuia şi transmiterea cererii şi răspunsului primite sau prelucrate de el), respectiv blocarea comunicaţiei,​ generarea unei excepţii pentru a indica producerea unei erori în cadrul procesării.+Un filtru implementează interfaţa ''​javax.servlet.Filter''​ şi este adnotat cu însemnarea ​[[http://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​annotation/​WebFilter.html|@WebFilter]] care trebuie să specifice cel puţin un URL (folosind atributele ​[[http://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​annotation/​WebFilter.html#​urlPatterns--|urlPatterns]] ​sau [[http://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​annotation/​WebFilter.html#​value--|value]]. Informaţiile cu privire la configurarea unui filtru sunt precizate prin atributul ​[[http://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​annotation/​WebFilter.html#​initParams--|initParams]] al aceleiaşi adnotări. Metoda cea mai importantă a unui filtru este [[https://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​Filter.html#​doFilter-javax.servlet.ServletRequest-javax.servlet.ServletResponse-javax.servlet.FilterChain-|doFilter()]] care primeşte cererea, răspunsul şi lanţul de filtre, în afară de ea trebuind implementate metodele ''​init()''​ şi ''​destroy()''​. Metoda ''​doFilter()''​ poate analiza antetele cererii şi răspunsului (doar după invocarea următorului filtru din lanţul de filtre), poate particulariza obiectele cerere şi răspuns în sensul modificării antetelor sau conţinutului,​ poate invoca următorul filtru din lanţul de filtre (prin apelarea metodei ''​doFilter()''​ a acestuia şi transmiterea cererii şi răspunsului primite sau prelucrate de el), respectiv blocarea comunicaţiei,​ generarea unei excepţii pentru a indica producerea unei erori în cadrul procesării.
  
-Un filtru poate adăuga un atribut la cerere sau poate introduce informaţii în contextul unui răspuns. Pentru a suprascrie metodele cererii, obiectul de tip cerere va fi împachetat într-un obiect derivat din ''​ServletRequestWrapper'' ​sau ''​HttpServletRequestWrapper''​. Similar, pentru răspuns va fi folosit ​''​ServletResponseWrapper'' ​sau ''​HttpServletResponseWrapper''​.+Un filtru poate adăuga un atribut la cerere sau poate introduce informaţii în contextul unui răspuns. Pentru a suprascrie metodele cererii, obiectul de tip cerere va fi împachetat într-un obiect derivat din [[http://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​ServletRequestWrapper.html|ServletRequestWrapper]] sau [[http://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​http/​HttpServletRequestWrapper.html|HttpServletRequestWrapper]]. Similar, pentru răspuns va fi folosit ​[[http://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​ServletResponseWrapper.html|ServletResponseWrapper]] ​sau [[http://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​http/​HttpServletResponseWrapper.html|HttpServletResponseWrapper]].
  
 Un container foloseşte asocieri între filtre şi resurse web (prin nume sau prin URL) pentru a determina modul (precum şi ordinea) în care vor fi aplicate. În scopuri de jurnalizare,​ poate fi folosită masca ''​%%/​*%%'',​ aplicându-se tuturor evenimentelor ce implică comunicaţie între client şi server. Un filtru poate fi asociat mai multor resurse web şi o resursă web poate avea asociate mai multe filtre (un lanţ de filtre). Un container foloseşte asocieri între filtre şi resurse web (prin nume sau prin URL) pentru a determina modul (precum şi ordinea) în care vor fi aplicate. În scopuri de jurnalizare,​ poate fi folosită masca ''​%%/​*%%'',​ aplicându-se tuturor evenimentelor ce implică comunicaţie între client şi server. Un filtru poate fi asociat mai multor resurse web şi o resursă web poate avea asociate mai multe filtre (un lanţ de filtre).
Line 230: Line 230:
   * indirect, încorporând un URL care referă o altă componentă web în răspunsul transmis către client.   * indirect, încorporând un URL care referă o altă componentă web în răspunsul transmis către client.
  
-Pentru a invoca o resursă disponibilă pe serverul pe care rulează componenta web, trebuie obţinut un obiect ​''​RequestDispatcher'' ​folosindu-se metoda ​''​getRequestDispatcher()'' ​(ce primeşte ca parametru URL-ul resursei ce va fi invocată) aplicată fie pe obiectul cerere, fie pe contextul web. URL-ul resursei va fi o cale relativă, în situaţia în care se apelează din contextul cererii, respectiv o cale absolută, în cazul în care se apelează pe contextul web. În cazul în care resursa nu este disponibilă pe server sau serverul nu implementează un obiect ''​RequestDispatcher''​ pentru tipul respectiv de resursă, metoda ''​getRequestDispatcher()''​ va întoarce ''​null''​.+Pentru a invoca o resursă disponibilă pe serverul pe care rulează componenta web, trebuie obţinut un obiect ​[[https://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​RequestDispatcher.html|RequestDispatcher]] ​folosindu-se metoda ​[[https://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​ServletContext.html#​getRequestDispatcher-java.lang.String-|getRequestDispatcher()]] (ce primeşte ca parametru URL-ul resursei ce va fi invocată) aplicată fie pe obiectul cerere, fie pe contextul web. URL-ul resursei va fi o cale relativă, în situaţia în care se apelează din contextul cererii, respectiv o cale absolută, în cazul în care se apelează pe contextul web. În cazul în care resursa nu este disponibilă pe server sau serverul nu implementează un obiect ''​RequestDispatcher''​ pentru tipul respectiv de resursă, metoda ''​getRequestDispatcher()''​ va întoarce ''​null''​.
  
-Includerea unei alte resurse web (header, footer, informaţii de copyright, meniuri) în răspunsul construit de o componentă web se face folosind metoda ​''​include()'' ​a obiectului ''​RequestDispatcher''​. Dacă resursa este o componentă web, aceasta va fi executată (primind cererea) şi rezultatul acestei operaţii integrat în răspuns. Resursa web inclusă va avea acces la obiectul cerere, însă va fi limitată în privinţa obiectului răspuns în sensul că poate modifica conţinutul acestuia dar nu şi antetele sale (ca atare, nu poate apela metodele care modifică antetele obiectului răspuns).+Includerea unei alte resurse web (header, footer, informaţii de copyright, meniuri) în răspunsul construit de o componentă web se face folosind metoda ​[[https://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​RequestDispatcher.html#​include-javax.servlet.ServletRequest-javax.servlet.ServletResponse-|include()]] a obiectului ''​RequestDispatcher''​. Dacă resursa este o componentă web, aceasta va fi executată (primind cererea) şi rezultatul acestei operaţii integrat în răspuns. Resursa web inclusă va avea acces la obiectul cerere, însă va fi limitată în privinţa obiectului răspuns în sensul că poate modifica conţinutul acestuia dar nu şi antetele sale (ca atare, nu poate apela metodele care modifică antetele obiectului răspuns).
  
-Pentru transmiterea mai departe a cererii către o altă resursă pentru a realiza alte procesări şi a genera răspunsul, se foloseşte metoda ​''​forward()'' ​a obiectului ''​RequestDispatcher''​. URL-ul cererii va fi modificat la cel al paginii care va realiza prelucrarea ei. De asemenea, se reţine şi URI-ul original şi parţile sale componente ca atribute ale cererii. Responsabilitatea răspunsului îi revine resursei către care a fost transmis răspunsul. O astfel de funcţionalitate este însă limitată în cazul în care au fost folosite obiecte ''​ServletOutputStream''​ sau ''​PrintWriter''​ în cadrul servletului,​ generându-se în caz contrar excepţii de tipul ''​IllegalStateException''​.+Pentru transmiterea mai departe a cererii către o altă resursă pentru a realiza alte procesări şi a genera răspunsul, se foloseşte metoda ​[[https://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​RequestDispatcher.html#​forward-javax.servlet.ServletRequest-javax.servlet.ServletResponse-|forward()]] a obiectului ''​RequestDispatcher''​. URL-ul cererii va fi modificat la cel al paginii care va realiza prelucrarea ei. De asemenea, se reţine şi URI-ul original şi parţile sale componente ca atribute ale cererii. Responsabilitatea răspunsului îi revine resursei către care a fost transmis răspunsul. O astfel de funcţionalitate este însă limitată în cazul în care au fost folosite obiecte ''​ServletOutputStream''​ sau ''​PrintWriter''​ în cadrul servletului,​ generându-se în caz contrar excepţii de tipul ''​IllegalStateException''​.
  
 Transmiterea controlului către obiectele Java Servlet asociate tipurilor de utilizatori autentificate în sistem se poate realiza astfel: Transmiterea controlului către obiectele Java Servlet asociate tipurilor de utilizatori autentificate în sistem se poate realiza astfel:
Line 240: Line 240:
 <code java> <code java>
 RequestDispatcher dispatcher = null; RequestDispatcher dispatcher = null;
-switch(getUserType(userName,userPassword)) {+switch(getUserType(username, password)) {
   case Constants.USER_TYPE_ADMINISTRATOR:​   case Constants.USER_TYPE_ADMINISTRATOR:​
     dispatcher = getServletContext().getRequestDispatcher("/"​ + Constants.ADMINISTRATOR_SERVLET_CONTEXT);​     dispatcher = getServletContext().getRequestDispatcher("/"​ + Constants.ADMINISTRATOR_SERVLET_CONTEXT);​
Line 253: Line 253:
 </​code>​ </​code>​
  
-Accesarea contextului web în care sunt executate componentele se face prin metoda ''​getServletContext()''​ care întoarce un obiect de tipul ''​ServletContext''​, prin intermediul căruia pot fi accesaţi parametrii de iniţializare,​ resurse asociate cu contextul web, atribute având tipuri de obiecte asociate şi capabilităţi legate de jurnalizare.+Accesarea contextului web în care sunt executate componentele se face prin metoda ''​getServletContext()''​ care întoarce un obiect de tipul [[http://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​ServletContext.html|ServletContext]], prin intermediul căruia pot fi accesaţi parametrii de iniţializare,​ resurse asociate cu contextul web, atribute având tipuri de obiecte asociate şi capabilităţi legate de jurnalizare.
  
 ==== Încărcarea de fișiere ==== ==== Încărcarea de fișiere ====
  
-Una dintre funcţionalităţile cele mai frecvent implementate în cazul unei aplicaţii web o reprezintă încărcarea de fişiere. În acest scop, adnotarea ​''​javax.annotation.MultipartConfig'' ​este folosită pentru a indica faptul că servletul pentru care este declarată poate prelucra cereri folosind tipul MIME ''​multipart/​form-date'',​ componentele ​''​Part'' ​putând fi obţinute prin una din metodele ​''​request.getPart(String name)'' ​sau ''​request.getParts()''​.+Una dintre funcţionalităţile cele mai frecvent implementate în cazul unei aplicaţii web o reprezintă încărcarea de fişiere. În acest scop, adnotarea ​[[http://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​annotation/​MultipartConfig.html|@MultipartConfig]] este folosită pentru a indica faptul că servletul pentru care este declarată poate prelucra cereri folosind tipul MIME ''​multipart/​form-date'',​ componentele ​[[http://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​http/​Part.html|javax.servlet.Part]] ​putând fi obţinute prin una din metodele ​[[http://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​http/​HttpServletRequest.html#​getPart-java.lang.String-|request.getPart(String name)]] sau [[http://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​http/​HttpServletRequest.html#​getParts--|request.getParts()]].
 Adnotarea ''​@MultipartConfig''​ suportă mai multe atribute opţionale: Adnotarea ''​@MultipartConfig''​ suportă mai multe atribute opţionale:
-  * ''​location'' ​– reprezintă calea absolută spre un director din sistemul de fişiere; nu sunt suportate căi relative la contextul aplicaţiei web; de regulă, locaţia este folosită pentru a stoca fişiere temporare în timp ce părţile fişierului sunt procesate sau atunci când dimensiunea fişierului depăşeşte valoarea sprecificată de proprietatea ''​fieldSizeThreshold'';​ valoarea implicită este "";​ +  * [[http://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​annotation/​MultipartConfig.html#​location--|location]] ​– reprezintă calea absolută spre un director din sistemul de fişiere; nu sunt suportate căi relative la contextul aplicaţiei web; de regulă, locaţia este folosită pentru a stoca fişiere temporare în timp ce părţile fişierului sunt procesate sau atunci când dimensiunea fişierului depăşeşte valoarea sprecificată de proprietatea ''​fieldSizeThreshold'';​ valoarea implicită este "";​ 
-  * ''​fieldSizeThreshold'' ​– dimensiunea fişierului (în octeţi) după care acesta va fi stocat temporar pe disc; valoarea implicită este 0 octeţi; +  * [[http://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​annotation/​MultipartConfig.html#​fileSizeThreshold--|fieldSizeThreshold]] – dimensiunea fişierului (în octeţi) după care acesta va fi stocat temporar pe disc; valoarea implicită este 0 octeţi; 
-  * ''​maxFileSize'' ​– dimensiunea maximă permisă pentru încărcarea de fişiere, exprimată în octeţi; în situaţia în care se încearcă încărcarea de fişiere care depăşesc această valoare, se generează o excepţie de tipul ''​IllegalStateException'';​ valoarea implicită este nelimitată;​ +  * [[http://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​annotation/​MultipartConfig.html#​maxFileSize--|maxFileSize]] ​– dimensiunea maximă permisă pentru încărcarea de fişiere, exprimată în octeţi; în situaţia în care se încearcă încărcarea de fişiere care depăşesc această valoare, se generează o excepţie de tipul ''​IllegalStateException'';​ valoarea implicită este nelimitată;​ 
-  * ''​maxRequestSize'' ​– dimensiunea maximă pentru o cerere multipart/​form-date,​ exprimată în octeţi; containerul va genera o excepţie dacă valoarea totală a tuturor fişierelor încărcate depăşeşte acest prag; valoarea implicită este de asemenea nelimitată.+  * [[http://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​annotation/​MultipartConfig.html#​maxRequestSize--|maxRequestSize]] ​– dimensiunea maximă pentru o cerere ​''​multipart/​form-date''​, exprimată în octeţi; containerul va genera o excepţie dacă valoarea totală a tuturor fişierelor încărcate depăşeşte acest prag; valoarea implicită este de asemenea nelimitată.
  
 Alternativ, aceste proprietăţi pot fi specificate în fişierul de configurare ''​web.xml'',​ în cadrul secţiunii ''<​multipart-config>​ ... </​multipart-config>'',​ denumirile câmpurilor fiind identice cu cele ale proprietăţilor adnotării. Alternativ, aceste proprietăţi pot fi specificate în fişierul de configurare ''​web.xml'',​ în cadrul secţiunii ''<​multipart-config>​ ... </​multipart-config>'',​ denumirile câmpurilor fiind identice cu cele ale proprietăţilor adnotării.
Line 270: Line 270:
   * ''​Part getPart(String name)''​ – poate fi folosit pentru a obţine o parte identificată printr-un nume.   * ''​Part getPart(String name)''​ – poate fi folosit pentru a obţine o parte identificată printr-un nume.
  
-Interfaţa ''​javax.servlet.http.Part''​ oferă metode pentru analiza fiecărei părţi cu privire la nume, dimensiune, tipul de conţinut, procesarea antetelor transmise împreună cu partea respectivă,​ salvarea pe disc (prin intermediul metodei ​''​write(String filename)''​) sau ştergerea ei.+Interfaţa ''​javax.servlet.http.Part''​ oferă metode pentru analiza fiecărei părţi cu privire la nume, dimensiune, tipul de conţinut, procesarea antetelor transmise împreună cu partea respectivă,​ salvarea pe disc (prin intermediul metodei ​[[https://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​http/​Part.html#​write-java.lang.String-|write(String filename)]]) sau ştergerea ei.
  
 ==== Procesarea asincronă ==== ==== Procesarea asincronă ====
Line 278: Line 278:
 Dacă în procesul de tratare a unei cereri un servlet întâlneşte o operaţie care ar putea fi blocantă, aceasta poate fi delegată către un context de execuţie asincron cu eliberarea firului de execuţie ocupat către container, fără a se genera un răspuns. În momentul în care operaţia în cauză se termină, va putea fi generat şi răspunsul aferent cererii fie din contextul de execuţie asincron, fie din contextul altui servlet către care este transmis mai departe. Dacă în procesul de tratare a unei cereri un servlet întâlneşte o operaţie care ar putea fi blocantă, aceasta poate fi delegată către un context de execuţie asincron cu eliberarea firului de execuţie ocupat către container, fără a se genera un răspuns. În momentul în care operaţia în cauză se termină, va putea fi generat şi răspunsul aferent cererii fie din contextul de execuţie asincron, fie din contextul altui servlet către care este transmis mai departe.
  
-Pentru a permite procesarea asincronă a unui servlet, trebuie specificată proprietatea ''​asyncSupported=true''​ în cadrul adnotării ''​@WebServlet''​. Funcţionalitatea pentru a realiza aceste operaţii este oferită de clasa ''​javax.servlet.AsyncContext''​,  un obiect de acest tip putând fi obţinut în metoda ''​service()''​ din obiectul cerere:+Pentru a permite procesarea asincronă a unui servlet, trebuie specificată proprietatea ​[[http://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​annotation/​WebServlet.html#​asyncSupported--|asyncSupported]] avand valoarea ​''​true''​ în cadrul adnotării ''​@WebServlet''​. Funcţionalitatea pentru a realiza aceste operaţii este oferită de clasa [[https://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​AsyncContext.html|javax.servlet.AsyncContext]],  un obiect de acest tip putând fi obţinut în metoda ''​service()''​ din obiectul cerere:
  
 <code java> <code java>
Line 291: Line 291:
  
 Metodele definite de clasa ''​AsyncContext''​ sunt: Metodele definite de clasa ''​AsyncContext''​ sunt:
-  * ''​void start(Runnable run)'' ​– containerul oferă un alt fir de execuţie unde operaţia blocantă poate fi procesată; codul care tratează această prelucrare trebuie specificat în clasa care implementează interfaţa ''​Runnable'';​ o asfel de clasă poate fi definită ca internă atunci când se apelează metoda ''​start()''​ sau se poate folosi alt mecanism pentru a transmite clasei instanţa ''​AsyncContext'';​ +  * [[https://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​AsyncContext.html#​start-java.lang.Runnable-|void start(Runnable run)]] – containerul oferă un alt fir de execuţie unde operaţia blocantă poate fi procesată; codul care tratează această prelucrare trebuie specificat în clasa care implementează interfaţa ''​Runnable'';​ o asfel de clasă poate fi definită ca internă atunci când se apelează metoda ''​start()''​ sau se poate folosi alt mecanism pentru a transmite clasei instanţa ''​AsyncContext'';​ 
-  * ''​ServletRequest getRequest()'' ​– întoarce cererea folosită pentru a iniţializa contextul asincron; metoda poate fi folosită spre a obţine parametrii cererii în cadrul contextului asincron; +  * [[https://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​AsyncContext.html#​getRequest--|ServletRequest getRequest()]] – întoarce cererea folosită pentru a iniţializa contextul asincron; metoda poate fi folosită spre a obţine parametrii cererii în cadrul contextului asincron; 
-  * ''​ServletResponse getResponse()'' ​– întoarce răspunsul utilizat spre a iniţializa contextul asincron; metoda poate fi folosită pentru a construi un răspuns cu rezultatele operaţiei blocante; +  * [[https://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​AsyncContext.html#​getResponse--|ServletResponse getResponse()]] – întoarce răspunsul utilizat spre a iniţializa contextul asincron; metoda poate fi folosită pentru a construi un răspuns cu rezultatele operaţiei blocante; 
-  * ''​void complete()'' ​– termină operaţia asincronă şi transmite răspunsul asociat cu contextul asincron; poate fi apelată după constuirea răspunsului;​ +  * [[https://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​AsyncContext.html#​complete--|void complete()]] – termină operaţia asincronă şi transmite răspunsul asociat cu contextul asincron; poate fi apelată după constuirea răspunsului;​ 
-  * ''​void dispatch(String path)'' ​– transmite obiectele cerere şi răspuns către calea indicată; metoda este folosită pentru a delega altui servlet responsabilitatea cu privire la aceste obiecte, după terminarea operaţiei.+  * [[https://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​AsyncContext.html#​dispatch-java.lang.String-|void dispatch(String path)]] – transmite obiectele cerere şi răspuns către calea indicată; metoda este folosită pentru a delega altui servlet responsabilitatea cu privire la aceste obiecte, după terminarea operaţiei.
  
 Un exemplu de utilizare al acestei funcţionalităţi ar putea fi: Un exemplu de utilizare al acestei funcţionalităţi ar putea fi:
Line 325: Line 325:
 În situaţia în care operaţiile de intrare/​ieşire se desfăşoară mai rapid pe server decât pe client (datorită limitărilor introduse de comunicaţia prin reţeaua de calculatoare),​ se pot folosi **operaţii de intrare/​ieşire non-blocante** asociate cu procesarea asincronă pentru a se asigura eliminarea timpilor morţi din firele de execuţie. Astfel, fluxurilor de intrare/​ieşire li se vor asocia mai multe obiecte ascultător,​ iar operaţiile de citire/​scriere se vor realiza în metodele care tratează aceste evenimente. În situaţia în care operaţiile de intrare/​ieşire se desfăşoară mai rapid pe server decât pe client (datorită limitărilor introduse de comunicaţia prin reţeaua de calculatoare),​ se pot folosi **operaţii de intrare/​ieşire non-blocante** asociate cu procesarea asincronă pentru a se asigura eliminarea timpilor morţi din firele de execuţie. Astfel, fluxurilor de intrare/​ieşire li se vor asocia mai multe obiecte ascultător,​ iar operaţiile de citire/​scriere se vor realiza în metodele care tratează aceste evenimente.
  
-Clasa ''​javax.servlet.ServletInputStream'' ​suportă metoda ​''​void setReadListener(ReadListener rl)'' ​care asociază un obiect ascultător fluxului de intrare care conţine metode pentru a citi date asincron. Acesta este creat ca o clasă internă sau se foloseşte alt mecanism pentru a transmite fluxul de intrare obiectului ascultător.+Clasa [[http://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​ServletInputStream.html|javax.servlet.ServletInputStream]] suportă metoda ​[[http://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​ServletInputStream.html#​setReadListener-javax.servlet.ReadListener-|void setReadListener(ReadListener rl)]] care asociază un obiect ascultător fluxului de intrare care conţine metode pentru a citi date asincron. Acesta este creat ca o clasă internă sau se foloseşte alt mecanism pentru a transmite fluxul de intrare obiectului ascultător.
  
-Metodele de tratare a evenimentelor asociate unui obiect ​''​ReadListener'' ​sunt ''​void onDataAvailable()''​, ''​void onAllDataRead()''​, ''​void onError(Throwable t)''​. +Metodele de tratare a evenimentelor asociate unui obiect ​[[http://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​ReadListener.html|ReadListener]] ​sunt [[http://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​ReadListener.html#​onDataAvailable--|void onDataAvailable()]], [[http://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​ReadListener.html#​onAllDataRead--|void onAllDataRead()]], [[http://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​ReadListener.html#​onError-java.lang.Throwable-|void onError(Throwable t)]]. 
-  * ''​boolean isReady()'' ​– întoarce true dacă datele pot fi citite non-blocant;​ +  * [[http://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​ServletInputStream.html#​isReady--|boolean isReady()]] – întoarce ​''​true'' ​dacă datele pot fi citite non-blocant;​ 
-  * ''​boolean isFinished()'' ​– întoarce true când toate datele au fost citite.+  * [[http://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​ServletInputStream.html#​isFinished--|boolean isFinished()]] – întoarce ​''​true'' ​când toate datele au fost citite.
  
-Clasa ''​javax.servlet.ServletOutputStream'' ​suportă metodele: +Clasa [[http://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​ServletOutputStream.html|javax.servlet.ServletOutputStream]] suportă metodele: 
-  * ''​void setWriteListener(WriteListener wl)'' ​– asociază un obiect ascultător fluxului de ieşire care conţine metode pentru a scrie date asincron; acesta este creat ca o clasă internă sau se foloseşte alt mecanism pentru a transmite fluxul de intrare obiectului ascultător;​ +  * [[http://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​ServletOutputStream.html#​setWriteListener-javax.servlet.WriteListener-|void setWriteListener(WriteListener wl)]] – asociază un obiect ascultător fluxului de ieşire care conţine metode pentru a scrie date asincron; acesta este creat ca o clasă internă sau se foloseşte alt mecanism pentru a transmite fluxul de intrare obiectului ascultător;​ 
-  * ''​boolean isReady()'' ​– întoarce ''​true''​ dacă datele pot fi scrise non-blocant.+  * [[http://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​ServletOutputStream.html#​isReady--|boolean isReady()]] – întoarce ''​true''​ dacă datele pot fi scrise non-blocant.
  
-Metodele de tratare a evenimentelor asociate unui obiect ​''​WriteListener'' ​sunt ''​void onWritePossible()''​, ''​void onError(Throwable t)''​.+Metodele de tratare a evenimentelor asociate unui obiect ​[[http://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​WriteListener.html|WriteListener]] ​sunt [[http://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​WriteListener.html#​onWritePossible--|void onWritePossible()]], [[http://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​WriteListener.html#​onError-java.lang.Throwable-|void onError(Throwable t)]].
  
 ==== Integrarea Java Servlets cu sisteme de gestiune pentru baze de date ==== ==== Integrarea Java Servlets cu sisteme de gestiune pentru baze de date ====
Line 349: Line 349:
   Class.forName("​com.mysql.jdbc.Driver"​);​   Class.forName("​com.mysql.jdbc.Driver"​);​
 } catch(ClassNotFoundException exception) { } catch(ClassNotFoundException exception) {
-  System.out.println("​An exception has occurred: "​+exception.getMessage());​+  System.out.println("​An exception has occurred: " + exception.getMessage());​
   if(Constants.DEBUG) {   if(Constants.DEBUG) {
     exception.printStackTrace();​     exception.printStackTrace();​
Line 372: Line 372:
 === Utilizarea de câmpuri ascunse === === Utilizarea de câmpuri ascunse ===
  
-**Câmpurile ascunse** pot fi conţinute în formularele din paginile HTML (elemente de tip ''<​INPUT type="​hidden"​ ...>''​),​ dar au dezavantajul că pot fi identificate cu uşurinţă.+**Câmpurile ascunse** pot fi conţinute în formularele din paginile HTML (elemente de tip ''<​INPUT type="​hidden"​ ...>''​),​ dar au dezavantajul că pot fi identificate cu uşurinţă prin inspectarea codului sursă.
  
 === Rescrierea URL-urilor === === Rescrierea URL-urilor ===
Line 386: Line 386:
 **Cookie-urile** sunt fişiere care conţin perechi de tipul (cheie, valoare), fiind create de server şi incluse ca instrucţiuni în antetul mesajului HTTP transmis ca răspuns. **Cookie-urile** sunt fişiere care conţin perechi de tipul (cheie, valoare), fiind create de server şi incluse ca instrucţiuni în antetul mesajului HTTP transmis ca răspuns.
  
-În pachetul ''​javax.servlet.http''​ este definită clasa ''​Cookie''​:+În pachetul ''​javax.servlet.http''​ este definită clasa [[http://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​http/​Cookie.html|Cookie]]:
  
 <code java> <code java>
Line 394: Line 394:
 având un constructor care primeşte două şiruri de caractere reprezentând cheia, respectiv valoarea. având un constructor care primeşte două şiruri de caractere reprezentând cheia, respectiv valoarea.
  
-Pentru un obiect de tip ''​Cookie''​ se poate stabili ​denumirea ​şi valoarea (metodele ''​set/get''​ ''​Name''​ şi ''​Value''​), timpul de expirare, domeniul sau calea, ​acesta putând ​fi inclus într-un obiect de tip ''​HttpServletResponse'':​+Pentru un obiect de tip ''​Cookie''​ se pot gestiona ​denumirea ​([[http://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​http/​Cookie.html#​getName--|getName()]]), ​valoarea ([[http://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​http/​Cookie.html#​getValue--|getValue()]],​ [[http://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​http/​Cookie.html#​setValue-java.lang.String-|setValue()]]), timpul de expirare ​([[http://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​http/​Cookie.html#​getMaxAge--|getMaxAge()]],​ [[http://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​http/​Cookie.html#​setMaxAge-int-|setMaxAge()]]), domeniul ​([[http://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​http/​Cookie.html#​getDomain--|getDomain()]],​ [[http://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​http/​Cookie.html#​setDomain-java.lang.String-|setDomain()]]) ​sau calea ([[http://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​http/​Cookie.html#​getPath--|getPath()]], [[http://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​http/​Cookie.html#​setPath-java.lang.String-|setPath()]]). 
 + 
 +Obiectul cookie poate fi inclus într-un obiect de tip ''​HttpServletResponse''​, prin intermediul metodei [[http://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​http/​HttpServletResponse.html#​addCookie-javax.servlet.http.Cookie-|addCookie()]]:
  
 <code java> <code java>
Line 400: Line 402:
 </​code>​ </​code>​
  
-Cookie-urile pot fi obţinute prin metoda ​''​getCookies()'' ​implementată în clasa ''​HttpServletRequest''​.+Cookie-urile pot fi obţinute prin metoda ​[[http://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​http/​HttpServletRequest.html#​getCookies--|getCookies()]] implementată în clasa ''​HttpServletRequest''​.
  
 <code java> <code java>
Line 408: Line 410:
 === Folosirea unor instrumente de "​urmărire"​ a sesiunii === === Folosirea unor instrumente de "​urmărire"​ a sesiunii ===
  
-În pachetul ''​javax.servlet.http''​ este definită şi interfaţa ​''​HttpSession''​, care crează un singur obiect pentru o **sesiune**,​ putând stabili anumite valori pentru identificarea conexiunii dintre client şi server, legătura fiind realizată prin cookie (dacă sunt acceptate de client) sau rescrierea URL-urilor.+În pachetul ''​javax.servlet.http''​ este definită şi interfaţa ​[[https://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​http/​HttpSession.html|HttpSession]], care crează un singur obiect pentru o **sesiune**,​ putând stabili anumite valori pentru identificarea conexiunii dintre client şi server, legătura fiind realizată prin cookie (dacă sunt acceptate de client) sau rescrierea URL-urilor.
  
 <code java> <code java>
Line 414: Line 416:
 </​code>​ </​code>​
  
-Metoda ​''​getSession()'' ​întoarce sesiunea asociată unei cereri, sau dacă nu există o sesiune asociată cererii, aceasta este creată, dacă nu se specifică astfel. Metoda ''​getSession()''​ poate fi apelată şi fără parametri: ''​getSession() = getSession(true)''​.+Metoda ​[[http://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​http/​HttpServletRequest.html#​getSession--|getSession()]] întoarce sesiunea asociată unei cereri, sau dacă nu există o sesiune asociată cererii, aceasta este creată, dacă nu se specifică astfel. Metoda ''​getSession()''​ poate fi apelată şi fără parametri: ''​getSession() = getSession(true)''​.
  
-Atribute ​ ce pot reţine diferite obiecte sunt asociate unei sesiuni prin intermediul unei denumiri. Acestea sunt accesibile oricărei componente web care aparţine contextului respectiv şi tratează cereri care fac parte din aceeaşi sesiune. Ele pot fi notificate cu privire la producerea evenimentelor legate de asocierea lor cu o sesiune sau chiar de sesiunea in cauză. Astfel, clasele ascultător vor implementa interfaţa ​''​javax.servlet.http.HttpSessionBindingListenerInterface'' ​pentru a monitoriza asocierea sau disocierea unui obiect cu o sesiune, respectiv interfaţa ​''​javax.servlet.http.HttpSessionActivationListener'' ​spre a se detecta momentul când sesiunea este activată sau pasivizată (la transferul între maşini virtuale, respectiv la încărcarea / descărcarea dintr-un depozit persistent).+Atribute ce pot reţine diferite obiecte sunt asociate unei sesiuni prin intermediul unei denumiri. Acestea sunt accesibile oricărei componente web care aparţine contextului respectiv şi tratează cereri care fac parte din aceeaşi sesiune. Ele pot fi notificate cu privire la producerea evenimentelor legate de asocierea lor cu o sesiune sau chiar de sesiunea in cauză. Astfel, clasele ascultător vor implementa interfaţa ​[[https://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​http/​HttpSessionBindingListener.html|javax.servlet.http.HttpSessionBindingListenerInterface]] pentru a monitoriza asocierea sau disocierea unui obiect cu o sesiune, respectiv interfaţa ​[[https://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​http/​HttpSessionActivationListener.html|javax.servlet.http.HttpSessionActivationListener]] spre a se detecta momentul când sesiunea este activată sau pasivizată (la transferul între maşini virtuale, respectiv la încărcarea / descărcarea dintr-un depozit persistent).
  
-Obţinerea atributelor este realizată prin metodele ​''​getAttributeNames()''​, respectiv ​''​getAttribute(String)''​, iar stabilirea lor prin metoda ​''​setAttribute(String,​ Object)''​. Totodată, un atribut poate fi eliminat ​ prin metoda ​''​removeAttribute(String)''​. Alternativ, un atribut poate fi reiniţializat (având conţinut vid) şi retransmis sub această formă prin aceasta reţinându-se o anumită stare a aplicaţiei.+Obţinerea atributelor este realizată prin metodele ​[[http://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​ServletRequest.html#​getAttributeNames--|getAttributeNames()]], respectiv ​[[http://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​ServletRequest.html#​getAttribute-java.lang.String-|getAttribute(String)]], iar stabilirea lor prin metoda ​[[http://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​ServletRequest.html#​setAttribute-java.lang.String-java.lang.Object-|setAttribute(String,​ Object)]]. Totodată, un atribut poate fi eliminat ​ prin metoda ​[[http://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​ServletRequest.html#​removeAttribute-java.lang.String-|removeAttribute(String)]]. Alternativ, un atribut poate fi reiniţializat (având conţinut vid) şi retransmis sub această formă prin aceasta reţinându-se o anumită stare a aplicaţiei.
  
-Întrucât un client HTTP nu poate specifica momentul în care sesiunea nu mai este necesară, este asociat un timp de expirare (prin metodele ​''​set/get''​ ''​MaxInactiveInterval''​), astfel încât resursele utilizate de sesiune să poată fi refolosite. O sesiune nu va expira în cazul în care este accesată periodic (frecvenţa fiind mai mare decât timpul de expirare) – prin metodele serviciu care iniţializează (din nou) perioada în care sesiunea poate fi utilizată. Totodată, atunci când interacţiunea cu un client HTTP este încheiată,​ se poate folosi metoda ​''​invalidate()'' ​pentru a distruge sesiunea eliberând resursele folosite.+Întrucât un client HTTP nu poate specifica momentul în care sesiunea nu mai este necesară, este asociat un timp de expirare (prin metodele ​[[https://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​http/​HttpSession.html#​getMaxInactiveInterval--|getMaxInactiveInterval()]],​ [[https://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​http/​HttpSession.html#​setMaxInactiveInterval-int-|setMaxInactiveInterval()]]), astfel încât resursele utilizate de sesiune să poată fi refolosite. O sesiune nu va expira în cazul în care este accesată periodic (frecvenţa fiind mai mare decât timpul de expirare) – prin metodele serviciu care iniţializează (din nou) perioada în care sesiunea poate fi utilizată. Totodată, atunci când interacţiunea cu un client HTTP este încheiată,​ se poate folosi metoda ​[[https://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​http/​HttpSession.html#​invalidate--|invalidate()]] pentru a distruge sesiunea eliberând resursele folosite.
  
-Asocierea unei sesiuni cu un utilizator implică de regulă transmiterea ​ unui identificator între client şi server. Acesta poate fi reţinut pe client sub formă de cookie sau poate fi inclus în fiecare URL care este transmis clientului. Urmărirea sesiunii presupune faptul că aplicaţia ar trebui să rescrie URL-ul (folosind metoda ​''​encodeURL(URL)'' ​pe obiectul răspuns) de fiecare dată când servlet-ul transmite un răspuns, astfel încât, în situaţia în care clientul dezactivează posibilitatea de a reţine cookie-uri, identificatorul să fie inclus în URL. În situaţia în care clientul acceptă cookie-uri, efectul metodei ''​encodeURL(URL)''​ este nul, lăsând URL-ul pe care îl primeşte ca parametru neschimbat.+Asocierea unei sesiuni cu un utilizator implică de regulă transmiterea unui identificator între client şi server. Acesta poate fi reţinut pe client sub formă de cookie sau poate fi inclus în fiecare URL care este transmis clientului. Urmărirea sesiunii presupune faptul că aplicaţia ar trebui să rescrie URL-ul (folosind metoda ​[[http://​docs.oracle.com/​javaee/​7/​api/​javax/​servlet/​http/​HttpServletResponse.html#​encodeURL-java.lang.String-|encodeURL(String)]] pe obiectul răspuns) de fiecare dată când servlet-ul transmite un răspuns, astfel încât, în situaţia în care clientul dezactivează posibilitatea de a reţine cookie-uri, identificatorul să fie inclus în URL. În situaţia în care clientul acceptă cookie-uri, efectul metodei ''​encodeURL(URL)''​ este nul, lăsând URL-ul pe care îl primeşte ca parametru neschimbat.
  
 ===== Activitate de Laborator =====  ===== Activitate de Laborator ===== 
Line 519: Line 521:
 Se accesează opţiunea //Deploy// din meniul contextual al proiectului (accesat cu right-click). Se accesează opţiunea //Deploy// din meniul contextual al proiectului (accesat cu right-click).
  
-{{ :​laboratoare:​laborator04:​netbeans.png?nolink }}+{{ :​laboratoare:​laborator04:​netbeans01.png?nolink }}
  
 Alternativ, se poate porni serverul Apache Tomcat și dezvolta aplicația web în contextul său și prin opțiunea //Run// (F6), care va lansa și browser-ul implicit în care va fi prezentată pagina principală a aplicației web. Alternativ, se poate porni serverul Apache Tomcat și dezvolta aplicația web în contextul său și prin opțiunea //Run// (F6), care va lansa și browser-ul implicit în care va fi prezentată pagina principală a aplicației web.
Line 606: Line 608:
 </​spoiler>​ </​spoiler>​
  
-**11.** În pachetul ''​ro.pub.cs.aipi.lab07.servlets'',​ în clasa ''​ClientServlet'',​ metoda ''​doPost()'',​ să se implementeze operaţiile de anulare, respectiv finalizare a unei comenzi.+**11.** În pachetul ''​ro.pub.cs.aipi.lab04.servlets'',​ în clasa ''​ClientServlet'',​ metoda ''​doPost()'',​ să se implementeze operaţiile de anulare, respectiv finalizare a unei comenzi.
  
 <​spoiler|Indicații de Rezolvare>​ <​spoiler|Indicații de Rezolvare>​
Line 672: Line 674:
  
 ===== Soluții ===== ===== Soluții =====
- +[[https://​github.com/​aipi2015/​Laborator04/​tree/​master/​solutions/​eclipse/​04-BookStore-JavaServlets|Proiect Eclipse]]\\ ​ 
-TODO+[[https://​github.com/​aipi2015/​Laborator04/​tree/​master/​solutions/​netbeans/​04-BookStore-JavaServlets|Proiect NetBeans]]
laboratoare/laborator04.1447379064.txt.gz · Last modified: 2015/11/13 03:44 by Andrei Roșu-Cojocaru
CC Attribution-Share Alike 4.0 International
Driven by DokuWiki Recent changes RSS feed Valid CSS Valid XHTML 1.0