|
Universitatea POLITEHNICA din Bucuresti Facultatea de Electronica,
Telecomunicatii si Tehnologia Informatiei . |
2011 |
|
|
27/04/2012 |
(TPI) |
2012 |
In aceasta lucrare de laborator vor fi acoperite urmatoarele probleme:
- Crearea
aplicatiilor Web bazate pe servlet-uri utilizand NetBeans IDE
- Familiarizarea
cu platforma software pentru Internet mobil Windows Phone (C#)
Atentie: La inceputul laboratoarelor stergeti mai intai toate
proiectele existente (click dreapta pe
nodul
proiectului in fereastra Projects si selectati Delete,
si confirmati ca doriti sa fie sterse
sursele – in cazul proiectelor Java). La
finalul laboratoarelor stergeti proiectele create.
Un servlet este un obiect al unei clase Java ce extinde functionalitatea unui server
care lucreaza dupa modelul de acces cerere-raspuns
(cum este cel utilizat de protocolul HTTP, pe care se bazeaza aplicatiile Web) prin crearea unui continut dinamic.
Un servlet Web (care adauga
functionalitate unui server HTTP) trebuie sa extinda (prin mostenire)
clasa HttpServlet din pachetul javax.servlet.http.
Servlet-urile Web sunt componente care se executa intr-un container Web (Web container sau Web
engine), tot asa cum applet-urile
sunt executate intr-un Web browser.
Astfel,
operatiile care tin de ciclul de viata
al servlet-ului (apelul metodelor init(), destroy(), service()) sunt realizate de catre container in
momentele in care acestea sunt necesare (initializare, incarcare, etc.).
De asemenea, crearea obiectelor care incapsuleaza
cererea si raspunsul HTTP, pasarea
acestora metodei service(), gestionarea variabilelor CGI precum si multe alte servicii suport sunt realizate de catre container la momentul potrivit.
Metoda
service() mostenita de la clasa HttpServlet are o implementare
generica dar care se recomanda
sa fie pastrata, deoarece ea identifica
tipul de metoda a cererii HTTP si apeleaza
metoda potrivita (doPost() in cazul
metodei POST, doGet() in cazul metodei GET, etc.).
Pentru
a putea fi accesat servlet-ul, clientului trebuie sa i se furnizeze o adresa URL care in general difera de adresa la care se afla
cu adevarat fisierul cu codul sursa al servlet-ului.
Adresa
URL (1) este asociata
prin intermediul unui alias
(2) dat de programator cu calea
completa necesara
identificarii fisierului sursa (3) prin codul XML scris intr-un fisier
(web.xml) denumit deployment
descriptor (descriptor de desfasurare/amplasare -
DD).
De
exemplu, urmatorul continut al unui fisier web.xml
specifica:
- existenta unui servlet cu numele ClasaServlet (al
carui cod sursa se afla in ClasaServlet.java iar codul compilat in ClasaServlet.class) cu
ajutorul tag-urilor XML <servlet> si <servlet-class>,
- asocierea
servlet-ului ClasaServlet cu aliasul numeintern (prin intermediul tag-ului <servlet-name>),
- asocierea aliasului numeintern cu formatul
utilizat de client pentru URL /ServletAccesServiciu (prin intermediul tag-urilor <servlet-mapping> si <url-pattern>),
<web-app> <servlet> <servlet-name>numeintern</servlet-name> <servlet-class>ClasaServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>numeintern</servlet-name> <url-pattern>/ServletAccesServiciu</url-pattern> </servlet-mapping> </web-app> |
Rolurile pe care componentele Web (servlet-urile dar si paginile JSP) le pot juca sunt:
1) primirea cererilor HTTP de la client (sub forma de obiecte
HttpServletRequest) si eventual utilizarea
parametrilor obtinuti din formularul care a generat cererea,
2) executarea sarcinilor aplicatiei
(denumite business logic) fie direct
fie prin delegarea catre o alta
componenta:
- alte
componente Web – servlet-uri sau
pagini JSP,
- componente business locale (JavaBeans) sau
distribuite (Enterprise JavaBeans),
3) generarea dinamica a continutului si trimiterea lui in raspunsul catre client
prin intermediul raspunsurilor HTTP
(sub forma de obiecte HttpServletResponse).
Un posibil template al servlet-urilor Java:
import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class ClasaServlet
extends HttpServlet { protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException,
IOException { processRequest(request, response); } protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException,
IOException { processRequest(request, response); } protected void processRequest(HttpServletRequest request,
HttpServletResponse response) throws ServletException,
IOException { // Stabilirea tipului de continut response.setContentType("text/html"); // Utilizare "request" pentru a citi antetele HTTP primite
(de ex. cookies) // si datele formularului HTML (pe care utilizatorul le-a introdus
si trimis) // Utilizare "response" pentru a specifica linia si antetele raspunsului HTTP // (tipul de continut, cookies). PrintWriter out = response.getWriter(); // Utilizare "out" pentru a trimite
continut HTML catre browser } } |
Serverul Web de la Apache realizat in cadrul proiectului Jakarta, numit Tomcat, reprezinta o implementare de
referinta oficiala a specificatiilor servlet
si JSP. El include un container pentru servlet-uri si
a JSP-uri. Ultima versiune de Tomcat poate fi obtinuta de la adresa Web: http ://jakarta.apache.org/site/binindex.cgi. Mai multe detalii despre lucrul direct cu
containerele Jakarta Tomcat (structura de directoare, modul de amplasare, etc.)
pot fi obtinute la adresa http://discipline.elcom.pub.ro/swrtc/2006_Laborator/2006_SwRTc_Lab_3_Main_v01.htm.
Pentru exemplificare, vom folosi din clasa Orar, accesata la distanta prin
intermediul servlet-urilor:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
package pachetorar; public class Orar { private String[] orar; // camp ascuns (starea obiectului) public Orar()
{ orar = new
String[7]; // alocarea dinamica a
spatiului pentru tablou // popularea tabloului cu valori orar[0] = "Luni este curs TPI la
seriile D si E, laborator TPI la seria E."; orar[1] = "Marti
nu sunt ore de TPI."; orar[2] = "Miercuri este
laborator TPI la seriile D si E."; orar[3] = "Joi este laborator TPI
la seria D."; orar[4] = "Vineri este laborator
TPI la seria D."; orar[5] = "Sambata nu sunt ore de
TPI."; orar[6] = "Duminica nu sunt ore
de TPI."; } public String
getOrar(int
zi) { // metoda accesor - getter return orar[zi]; // returneaza un element al tabloului } public void setOrar(int zi,
String text) { // metoda accesor -
setter orar[zi] = text; // inlocuieste un element } } |
In laborator: 1. Se deschide NetBeans IDE. 2. Se sterg toate
proiectele anterior deschise, cu click dreapta in fereastra Projects
pe nodul fiecarui proiectul, selectand apoi Delete, si confirmand ca doriti sa fie sterse sursele Java. |
In laborator: 1. Se creaza un nou
proiect cu File > New Project... (sau Ctrl-Shift-N). 2. In zona Categories se
selecteaza Web, in zona Projects se selecteaza Web
Application, si se apasa Next. 3. La Project Name se scrie
numele ales pentru noul proiect, AplicatieOrar1,
la Project
Location se selecteaza subdirectorul corespunzator serie, grupei si
subgrupei proprii (calea va fi de genul: D:\TPI\seriaD\434\pare).
Se apasa Next. 4. La Server se selecteaza Apache Tomcat 6.0.16.
Se apasa Finish. |
In laborator: 1. Se adauga un nou fisier sursa cu File
> New File... (sau Ctrl- N). 2. In
zona Categories se selecteaza Java, in zona FileTypes
se selecteaza Java Class. Se apasa Next. 3. In
zona.in zona Class Name se scrie numele Orar, in zona Package se scrie numele
pachetorar. 4. Se inlocuieste codul generat automat
cu codul de mai sus. |
Vom incepe cu un servlet simplu care permite accesul la obiecte Orar:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
package pachetorar; import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class ServletOrarInitial extends HttpServlet { protected void processRequest(HttpServletRequest
request, HttpServletResponse response) throws ServletException,
IOException { response.setContentType("text/html;charset=UTF-8"); PrintWriter out = response.getWriter(); // Generarea formularului pentru
accesul recursiv la servicii out.println("<html>"); out.println("<head>"); out.println("<title>Acces orar</title>"); out.println("</head>"); out.println("<body>");
out.println("<h1>Acces orar (forma initiala) - generat de
servlet</h1>"); out.println("<hr><form name=\"input\"
action=\"AccesInitial\"" + "
method=\"get\">");
out.println("<input type=\"radio\" name=\"zi\"
checked=\"checked\"" + "
value=\"0\"> Luni"); out.println("<br> <input
type=\"radio\" name=\"zi\"
value=\"1\"> Marti"); out.println("<br> <input
type=\"radio\" name=\"zi\"
value=\"2\"> Miercuri"); out.println("<br> <input
type=\"radio\" name=\"zi\"
value=\"3\"> Joi"); out.println("<br> <input
type=\"radio\" name=\"zi\"
value=\"4\"> Vineri"); out.println("<br> <input
type=\"radio\" name=\"zi\"
value=\"5\"> Sambata"); out.println("<br> <input
type=\"radio\" name=\"zi\"
value=\"6\"> Duminica"); out.println("<hr>");
out.println("<input type=\"radio\" name=\"serviciu\"
checked=\"checked\"" + "
value=\"getOrar\">
Obtinere orar");
out.println("<br><input type=\"radio\"
name=\"serviciu\"
value=\"setOrar\">" + "
Modificare orar");
out.println("<input type=\"text\"
name=\"modificare\" value=\"\">"); out.println("<hr><input type=\"submit\"
value=\"Trimite\">");
out.println("</form><hr>"); Orar orar = new Orar(); // Obtinerea parametrilor introdusi de
utilizator in formular int
zi = Integer.parseInt(request.getParameter("zi")); // Daca serviciu cerut e obtinere orar if (request.getParameter("serviciu").equals("getOrar")) { out.println("<b>Orarul
cerut:</b> <br>" + orar.getOrar(zi)); } // Daca serviciu cerut e modificare orar else if (request.getParameter("serviciu").equals("setOrar")) { String
modificare = request.getParameter("modificare"); orar.setOrar(zi,
modificare);
out.println("<b>Modificarea ceruta:</b>
<br>" + orar.getOrar(zi)); } out.println("</body>"); out.println("</html>"); out.close(); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{ processRequest(request, response); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); } } |
In laborator: 1. Se adauga un nou
fisier sursa cu File > New File... (sau Ctrl- N). 2. In zona Categories se
selecteaza Web si in zona FileTypes se selecteaza Servlet.
Se apasa Next. 3. In zona Class Name se scrie
numele ServletOrarInitial, in zona Package se pastreaza
numele pachetorar. Se apasa Next. 4. La Configure Servlet Deployment se
precizeaza numele intern (Servlet Name) ca fiind servletinitial iar adresa URL (URL Pattern) ca fiind /AccesInitial. Se
apasa Finish. 5. Se inlocuieste codul generat automat pentru ServletOrarInitial cu codul de mai sus. |
Se poate observa continutul generat automat al
fisierului web.xml (in directorul WEB-INF,
selectand XML in loc de General). Portiunea finala specifica
corespondenta URL-alias-fisier:
<servlet> <servlet-name>servletinitial</servlet-name> <servlet-class>pachetorar.ServletOrarInitial</servlet-class> </servlet> <servlet-mapping> <servlet-name>servletinitial</servlet-name> <url-pattern>/AccesInitial</url-pattern> </servlet-mapping> <session-config> <session-timeout> 30 </session-timeout> </session-config> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> </web-app> |
In laborator: 1. Se inlocuieste codul generat automat al fisierului index,jsp cu codul de mai jos. |
<%@page contentType="text/html"
pageEncoding="UTF-8"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01
Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type"
content="text/html; charset=UTF-8"> <title>JSP Page</title> </head> <body> <h1>Pagina Index</h1> <hr> <a href="PaginaAccesInitiala.html">Pagina
acces la orar (initiala)</a> <hr> </body> </html> |
Acum va fi adaugata pagina HTML care contine formularul pentru accesul la
servlet:
In laborator: 1. Se adauga un nou
fisier sursa cu File > New File... (sau Ctrl- N). 2. In zona Categories se
selecteaza Web si in zona FileTypes se selecteaza HTML,
se apasa Next. 3. In zona.in zona HTML
File Name se scrie numele PaginaAccesInitiala. 4. Se inlocuieste codul generat automat cu codul de mai jos. |
<!DOCTYPE HTML PUBLIC
"-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <meta
http-equiv="Content-Type" content="text/html;
charset=UTF-8"> <title>Acces orar</title> </head> <body> <h1>Acces orar (forma initiala)</h1>
<hr><form name="input" action="/AplicatieOrar1/AccesInitial"
method="get"> <input
type="radio" name="zi" checked="checked"
value="0"> Luni <br> <input
type="radio" name="zi" value="1"> Marti <br> <input
type="radio" name="zi" value="2"> Miercuri <br> <input
type="radio" name="zi" value="3"> Joi <br> <input
type="radio" name="zi" value="4"> Vineri <br> <input
type="radio" name="zi" value="5"> Sambata <br> <input
type="radio" name="zi" value="6"> Duminica <hr> <input
type="radio" name="serviciu" checked="checked"
value="getOrar">
Obtinere
orar <br>
<input type="radio" name="serviciu" value="setOrar">
Modificare orar <input
type="text" name="modificare" value=""> <input
type="submit" value="Trimite"> </form> <hr> </body> </html> |
In laborator: 1. Se selecteaza Build
pe nodul proiectului AplicatieOrar1. 2. Se selecteaza Run
pe nodul proiectului AplicatieOrar1. 3. Se utilizeaza pagina in diverse moduri, testand serviciile obtinere
si modificare. |
Exemplu de utilizare a serviciului de modificare a orarului, in care se face apel la metoda setOrar():
Dar,
daca se acceseaza din nou serviciul de obtinere, modificarea nu se
regaseste:
Pentru ca modificarea sa fie retinuta
trebuie modificat servlet-ul. Protocolul HTTP nu are stari
(este stateless) asa incat serverul
HTTP nu retine informatii privind cererile anterioare. In plus, pentru ca servlet-urile sa fie accesate eficient
de catre mai multi clienti in acelasi timp containerul de servlet-uri formeaza
un asa-numit thread pool cu instante
ale servlet-ului din care alege unul oarecare pentru fiecare client. De
aceea declararea obiectului de tip Orar
ca variabila instanta nu este o solutie.
Obiectele din clasa HttpSession gestionate de containerul de servlet-uri permit pastrarea referintelor catre obiecte ale aplicatiei, numite atribute ale sesiunii, si regasirea acestora, prin intermediul
metodelor setAttribute() si getAttribute().
Vom modifica servletul pentru a crea si utiliza o sesiune.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
package pachetorar; import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class ServletOrarFinal extends HttpServlet { protected void processRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException { response.setContentType("text/html;charset=UTF-8"); PrintWriter out = response.getWriter(); // Generarea formularului pentru
accesul recursiv la servicii out.println("<html>"); out.println("<head>"); out.println("<title>Acces orar</title>"); out.println("</head>"); out.println("<body>");
out.println("<h1>Acces orar (forma finala) - generat de
servlet</h1>"); out.println("<hr><form name=\"input\"
action=\"AccesFinal\"" + "
method=\"get\">");
out.println("<input type=\"radio\"
name=\"zi\" checked=\"checked\"" + "
value=\"0\"> Luni"); out.println("<br> <input
type=\"radio\" name=\"zi\" value=\"1\">
Marti"); out.println("<br> <input
type=\"radio\" name=\"zi\" value=\"2\">
Miercuri"); out.println("<br> <input
type=\"radio\" name=\"zi\" value=\"3\">
Joi"); out.println("<br> <input
type=\"radio\" name=\"zi\" value=\"4\">
Vineri"); out.println("<br> <input
type=\"radio\" name=\"zi\" value=\"5\">
Sambata"); out.println("<br> <input
type=\"radio\" name=\"zi\" value=\"6\">
Duminica"); out.println("<hr>"); out.println("<input
type=\"radio\" name=\"serviciu\" checked=\"checked\"" + "
value=\"getOrar\">
Obtinere orar");
out.println("<br><input type=\"radio\"
name=\"serviciu\" value=\"setOrar\">" + "
Modificare orar"); out.println("<input
type=\"text\" name=\"modificare\"
value=\"\">"); out.println("<hr><input type=\"submit\"
value=\"Trimite\">");
out.println("</form><hr>"); // Transformarea obiectului orar in atribut al sesiunii
curente pentru // salvarea starii lui HttpSession ses = request.getSession(); Orar orar = (Orar) ses.getAttribute("orar"); if (orar == null) { //
Daca nu exista orarul salvat ca atribut al sesiunii orar = new Orar(); ses.setAttribute("orar", orar); } //
Obtinerea parametrilor introdusi de utilizator in formular int zi = Integer.parseInt(request.getParameter("zi")); //
Daca serviciu cerut e obtinere orar if (request.getParameter("serviciu").equals("getOrar")) {
out.println("<b>Orarul cerut:</b> <br>" + orar.getOrar(zi)); } //
Daca serviciu cerut e modificare orar else if (request.getParameter("serviciu").equals("setOrar")) { String modificare = request.getParameter("modificare"); orar.setOrar(zi, modificare);
out.println("<b>Modificarea ceruta:</b>
<br>" + orar.getOrar(zi)); }
out.println("</body>"); out.println("</html>"); out.close(); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{ processRequest(request, response); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { processRequest(request, response); } } |
In laborator: 1. Se adauga un nou
fisier sursa cu File > New File... (sau Ctrl- N), selectand Web si Servlet.
Se apasa Next. 2. La Class Name se scrie ServletOrarFinal, se pastreaza pachetorar. Se apasa Next. 3 La Configure Servlet Deployment se
precizeaza Servlet Name ca fiind servletfinal iar URL
Pattern ca fiind /AccesFinal. Se apasa Finish. 4. Se inlocuieste codul generat automat pentru ServletOrarFinal cu codul de mai sus. 5. Se inlocuieste codul generat automat al fisierului index,jsp cu codul de mai jos. |
<%@page contentType="text/html"
pageEncoding="UTF-8"%> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01
Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta
http-equiv="Content-Type" content="text/html;
charset=UTF-8"> <title>JSP Page</title> </head> <body> <h1>Pagina Index</h1> <hr> <a href="PaginaAccesInitiala.html">Pagina
acces la orar (initiala)</a> <hr> <a href="PaginaAccesFinala.html">Pagina acces la orar
(finala)</a> <hr> </body> </html> |
Acum va fi adaugata pagina HTML care contine formularul pentru accesul la
servlet:
In laborator: 1. Se adauga un nou
fisier sursa cu File > New File... (sau Ctrl- N), selectand Web si HTML,
se apasa Next. 2. In zona.in zona HTML
File Name se scrie numele PaginaAccesFinala. 3. Se inlocuieste codul generat automat cu codul de mai jos. |
<!DOCTYPE HTML PUBLIC
"-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <meta
http-equiv="Content-Type" content="text/html;
charset=UTF-8"> <title>Acces orar</title> </head> <body> <h1>Acces orar (forma finala)</h1> <hr><form
name="input" action="/AplicatieOrar1/AccesFinal"
method="get"> <input
type="radio" name="zi" checked="checked"
value="0"> Luni <br> <input
type="radio" name="zi" value="1"> Marti <br> <input
type="radio" name="zi" value="2"> Miercuri <br> <input
type="radio" name="zi" value="3"> Joi <br> <input
type="radio" name="zi" value="4"> Vineri <br> <input
type="radio" name="zi" value="5"> Sambata <br> <input
type="radio" name="zi" value="6"> Duminica <hr><input type="radio" name="serviciu"
checked="checked"
value="getOrar">
Obtinere
orar <br>
<input type="radio" name="serviciu" value="setOrar">
Modificare orar <input
type="text" name="modificare" value=""> <input type="submit"
value="Trimite"> </form><hr> </body> </html> |
In laborator: 1. Se selecteaza Build
pe nodul proiectului AplicatieOrar1. 2. Se selecteaza Run
pe nodul proiectului AplicatieOrar1. 3. Se utilizeaza pagina in diverse moduri, testand serviciile obtinere
si modificare. |
De aceasta data, daca se acceseaza serviciul de obtinere dupa cel de modificare,
modificarea produsa se regaseste.
3.4.1. Introduction
to Windows Phone, Silverlight and Visual Studio
Resurse: Lab 3.2
Broken TimeCalculator
3.4.2. User Interface
Design
Resurse: Lab
4.3 Data Binding Time Calculator
3.4.3. Storage
and Networking on Windows Phone
Resurse: Lab
5.1 Customer Time Logger Storage
Lab
6.1 Customer Time Logger Database