Tomcat – struttura delle directory • $CATALINA_HOME (oppure $TOMCAT_HOME): rappresenta la directory radice dell’installazione di Tomcat e contiene le seguenti directory: – – – – – – – bin common (lib nelle versioni più recenti) conf logs temp webapps work Complementi di Tecnologie Web – M. Franceschet, V.Della Mea e I.Scagnetto, a.a. 2011/12 - 1 Tomcat – directory bin • Questa directory contiene i file binari e gli script di amministrazione di Tomcat. • Tra questi ve ne sono due fondamentali: – startup.sh (startup.bat in Windows): avvia Tomcat – shutdown.sh (shutdown.bat in Windows): arresta Tomcat • Durante la fase di sviluppo di una web application è molto frequente dover arrestare e riavviare il servizio. Complementi di Tecnologie Web – M. Franceschet, V.Della Mea e I.Scagnetto, a.a. 2011/12 - 2 Tomcat – directory common • In questa directory si trovano le classi relative a Tomcat ed alle applicazioni web pubblicate in webapps: – classes/ • .class – lib/ • .jar • servlet.jar (o servlet-api.jar): da inserire nel classpath: javac –classpath $TOMCAT_HOME/common/lib/servlet-api.jar <file.java> • tools.jar • ... Complementi di Tecnologie Web – M. Franceschet, V.Della Mea e I.Scagnetto, a.a. 2011/12 - 3 Tomcat – directory conf • Questa directory contiene i file di configurazione di Tomcat. • In particolare vi sono i seguenti file: – server.xml: parametri di configurazione generali di Tomcat (in caso di modifica è necessario riavviare il server). – tomcat-users.xml: informazioni sugli utenti di Tomcat. Complementi di Tecnologie Web – M. Franceschet, V.Della Mea e I.Scagnetto, a.a. 2011/12 - 4 Tomcat – server.xml (I) • Struttura del file: – <Server> (tag principale) • <Service> (descrive la modalità di funzionamento, e.g., stand-alone) – Connector (porta TCP su cui Tomcat ascolta le richieste) – Engine (gestore delle richieste) » Host (host virtuale) Context (applicazione web) » Realm » Logger Complementi di Tecnologie Web – M. Franceschet, V.Della Mea e I.Scagnetto, a.a. 2011/12 - 5 Tomcat – server.xml (II) • Uno dei tag fondamentali è <Context> in quanto consente di definire il “contesto” di un’applicazione web: <Context path="/examples" docBase="examples" debug="0" reloadable="true" /> URL Posizione nel file system Complementi di Tecnologie Web – M. Franceschet, V.Della Mea e I.Scagnetto, a.a. 2011/12 - 6 Esempio: definire un’applicazione fuori da webapps • Specificando il tag Context come segue, si definisce una nuova applicazione i cui file risiedono in C:\nuovaapp e richiamabile tramite l’URL http://<host>:8080/nuova <Context path="/nuova" docBase="c:\nuovaapp" debug="0" reloadable="true" /> Complementi di Tecnologie Web – M. Franceschet, V.Della Mea e I.Scagnetto, a.a. 2011/12 - 7 Tomcat – server.xml (III) • Il tag <Logger> consente di definire le caratteristiche e la posizione dei file di log: <Logger className="org.apache.catalina.logger.filelogger" directory="logs" prefix="localhost_log. " suffix=".txt" timestamp="true" /> Complementi di Tecnologie Web – M. Franceschet, V.Della Mea e I.Scagnetto, a.a. 2011/12 - 8 Tomcat – tomcat-users.xml (I) <?xml version='1.0' encoding='utf-8'?> <tomcat-users> <role rolename="tomcat"/> <role rolename="role1"/> <role rolename="manager"/> <role rolename="admin"/> <user username="tomcat" password="tomcat" roles="tomcat"/> <user username="both" password="tomcat" roles="tomcat,role1"/> <user username="role1" password="tomcat" roles="role1"/> <user username="admin" password="adminpwd" roles="admin,manager"/> </tomcat-users> N.B.: le password degli utenti sono inserite in chiaro! Complementi di Tecnologie Web – M. Franceschet, V.Della Mea e I.Scagnetto, a.a. 2011/12 - 9 Tomcat – directory logs • Questa directory contiene i “registri” dell’attività di Tomcat. • Sono presenti molti file il cui nome è definito dal tag <Logger> nel file di configurazione server.xml. Ad esempio alcuni possibili formati sono: localhost_log.AAAA-MM-GG.txt localhost_admin_log.AAAA-MM-GG.txt localhost_users_log.AAAA-MM-GG.txt • Cosa viene registrato? – eventi relativi al server Tomcat (avvio, arresto, …); – eventuali errori; – … Complementi di Tecnologie Web – M. Franceschet, V.Della Mea e I.Scagnetto, a.a. 2011/12 - 10 Tomcat – directory temp • Temp è una directory di lavoro dove Tomcat memorizza dei file temporanei durante la sua attività. • Questa directory è essenziale per il funzionamento di Tomcat e non va rimossa (anche se appare vuota). Complementi di Tecnologie Web – M. Franceschet, V.Della Mea e I.Scagnetto, a.a. 2011/12 - 11 Tomcat - directory webapps • Directory contenente le applicazioni web: – scritte dagli utenti; – predefinite con l’installazione di Tomcat (e.g., gli esempi contenuti in examples/). Complementi di Tecnologie Web – M. Franceschet, V.Della Mea e I.Scagnetto, a.a. 2011/12 - 12 Tomcat – directory work • Anche questa è una directory di lavoro. • In particolare Tomcat la utilizza per memorizzare temporaneamente le servlet generate dalle pagine scritte con la tecnologia JSP (Java Server Pages). Complementi di Tecnologie Web – M. Franceschet, V.Della Mea e I.Scagnetto, a.a. 2011/12 - 13 Esempio – Ciao, mondo! • Fasi dello sviluppo: – – – – – – – – scrittura del codice in locale (CiaoMondo.java); compilazione in locale (CiaoMondo.class) – passo opzionale; opzionale scrittura del file web.xml (deployment descriptor file); Scrittura di una pagina HTML di presentazione che contenga il link alla servlet – passo opzionale; opzionale deployment e Test su un’installazione locale di tomcat – passo opzionale; opzionale copia dei file sul server (latoserver.dimi.uniud.it) nelle opportune directory tramite scp; compilazione sul server (se la compilazione è avvenuta in locale, si può provare a copiare sul server solo il file CiaoMondo.class, evitando questo passo); Arresto e riavvio della propria applicazione web tramite il Tomcat Manager. Complementi di Tecnologie Web – M. Franceschet, V.Della Mea e I.Scagnetto, a.a. 2011/12 - 14 Il codice import java.io.*; import javax.servlet.*; import javax.servlet.http.*; public class CiaoMondo extends HttpServlet { public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { res.setContentType("text/html"); PrintWriter out = res.getWriter(); } } out.println("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML "+ "1.1//EN\" \"http://www.w3c.org/TR/xhtml1/DTD/xhtml11.dtd\">"); out.println("<html xmlns=\"http://www.w3.org/1999/XHTML\" "+ "xml:lang=\"it\" lang=\"it\">"); out.println("<head><title>Ciao, mondo!</title></head>"); out.println("<body>"); out.println("<strong>Ciao, mondo!</strong>"); out.println("</body></html>"); Complementi di Tecnologie Web – M. Franceschet, V.Della Mea e I.Scagnetto, a.a. 2011/12 - 15 Compilazione in locale (ambiente Windows) • Supponendo di aprire un prompt del DOS, digitare i seguenti comandi: – cd <percorso della directory che contiene CiaoMondo.java> – javac -classpath "C:\Programmi\Apache Software Foundation\Tomcat 6.0\lib\servletapi.jar" CiaoMondo.java • Viene prodotto il file CiaoMondo.class Complementi di Tecnologie Web – M. Franceschet, V.Della Mea e I.Scagnetto, a.a. 2011/12 - 16 Il file web.xml <?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd"> <web-app> <servlet> <servlet-name>PrimoTest</servlet-name> <servlet-class>CiaoMondo</servlet-class> </servlet> <servlet-mapping> <servlet-name>PrimoTest</servlet-name> <url-pattern>/servlet/Primo</url-pattern> </servlet-mapping> </web-app> Complementi di Tecnologie Web – M. Franceschet, V.Della Mea e I.Scagnetto, a.a. 2011/12 - 17 Un file index.html con il link alla servlet <HTML> <HEAD> <TITLE>Servlet di prova</TITLE> </HEAD> <BODY> <TABLE> <TR> <TD> <A HREF="servlet/Primo">La mia prima servlet</A> </TD> </TR> </TABLE> </BODY> </HTML> Complementi di Tecnologie Web – M. Franceschet, V.Della Mea e I.Scagnetto, a.a. 2011/12 - 18 Deployment in locale (I) Ambiente Windows • Dove copiare i file? – supponiamo di aver installato Tomcat in C:\Programmi\Apache Software Foundation\Tomcat 7.0; – creiamo una cartella test all’interno di C:\Programmi\Apache Software Foundation\Tomcat 7.0\webapps; – creiamo una cartella WEB-INF all’interno di C:\Programmi\Apache Software Foundation\Tomcat 7.0\webapps\test; – creiamo una cartella classes all’interno di C:\Programmi\Apache Software Foundation\Tomcat 7.0\webapps\test\WEB-INF. Complementi di Tecnologie Web – M. Franceschet, V.Della Mea e I.Scagnetto, a.a. 2011/12 - 19 Deployment in locale (II) Ambiente Windows • Copiamo index.html (se lo abbiamo creato) in C:\Programmi\Apache Software Foundation\Tomcat 7.0\webapps\test. • Copiamo web.xml in C:\Programmi\Apache Software Foundation\Tomcat 6.0\webapps\test\WEB-INF; • Copiamo CiaoMondo.class in C:\Programmi\Apache Software Foundation\Tomcat 7.0\webapps\test\WEBINF\classes; Complementi di Tecnologie Web – M. Franceschet, V.Della Mea e I.Scagnetto, a.a. 2011/12 - 20 Schema della struttura delle directory create $CATALINA_HOME/webapps test index.html WEB-INF web.xml classes/ CiaoMondo.class Complementi di Tecnologie Web – M. Franceschet, V.Della Mea e I.Scagnetto, a.a. 2011/12 - 21 Deployment in locale (III) Ambiente Windows • Arrestiamo e riavviamo il servizio (tramite gli script shutdown.bat e startup.bat, oppure l’apposita applicazione nella tray-bar di Windows). • Testiamo la nostra applicazione: – http://localhost:8080/test/ (facciamo click sul link nella pagina che compare sul browser); – http://localhost:8080/test/servlet/Primo (test diretto senza passare dalla pagina HTML). Complementi di Tecnologie Web – M. Franceschet, V.Della Mea e I.Scagnetto, a.a. 2011/12 - 22 Deployment remoto (tramite scp) - I • Sintassi di scp: – $ man scp … NAME scp – secure copy (remote file copy program) SYNOPSIS scp [-pqrvBC46] [-F ssh_config] [-S program] [-P port] [-c cipher] [-i identity file] [-o ssh_option] [[user@]host1]:file1 […] [[user@]host2]:file2 … The options are as follows: … -r Recursively copies entire directories Complementi di Tecnologie Web – M. Franceschet, V.Della Mea e I.Scagnetto, a.a. 2011/12 - 23 Deployment remoto (tramite scp) - II • scp index.html <nome utente>@latoserver.dimi.uniud.it:/home/ <nome utente>/servlets/ • scp web.xml <nome utente>@latoserver.dimi.uniud.it:/home/ <nome utente>/servlets/WEB-INF/ • scp CiaoMondo.class <nome utente>@latoserver.dimi.uniud.it:/home/ <nome utente>/servlets/WEB-INF/classes/ Complementi di Tecnologie Web – M. Franceschet, V.Della Mea e I.Scagnetto, a.a. 2011/12 - 24 Deployment remoto (tramite client grafico) • Per i sistemi operativi della famiglia Windows esistono dei client grafici per le operazioni di copia remota. • Un client grafico gratuito è disponibile all’indirizzo http://www.coreftp.com • Le operazioni di copia sono notevolmente semplificate dall’interfaccia grafica (supporta anche la copia sicura, come scp). • Un alto client grafico gratuito è disponibile all'indirizzo http://winscp.net Complementi di Tecnologie Web – M. Franceschet, V.Della Mea e I.Scagnetto, a.a. 2011/12 - 25 Core FTP - Interfaccia Complementi di Tecnologie Web – M. Franceschet, V.Della Mea e I.Scagnetto, a.a. 2011/12 - 26 Deployment remoto su latoserver.dimi.uniud.it • Copiare i file su latoserver.dimi.uniud.it (tramite scp o CoreFTP) nelle seguenti directory: – index.html in ~/servlets/ – web.xml in ~/servlets/WEB-INF – CiaoMondo.class in ~/servlets/WEB-INF/classes/ • Se non si dispone del file .class: – copiare CiaoMondo.java nella propria home; – Compilarlo con il comando javac ~/CiaoMondo.java – Copiare il file compilato in ~/servlets/WEB-INF/classes/ Complementi di Tecnologie Web – M. Franceschet, V.Della Mea e I.Scagnetto, a.a. 2011/12 - 27 Deployment remoto su latoserver.dimi.uniud.it • Collegarsi a http://latoserver.dimi.uniud.it:8080/ • Fra i link a sinistra della home page di Tomcat cliccare su “Tomcat Manager” • Inserire lo username tomcat e la password comunicata a lezione • Compare una pagina web che elenca tutte le applicazioni registrate su Tomcat • Scrollare la pagina fino a individuare la propria (/<nome utente>) • Cliccare su Reload oppure prima su Stop e poi su Start (non cliccare su Undeploy) • Attenzione a non arrestare, avviare o rimuovere le applicazioni degli altri utenti. Complementi di Tecnologie Web – M. Franceschet, V.Della Mea e I.Scagnetto, a.a. 2011/12 - 28 Test finale • Collegarsi a http://latoserver.dimi.uniud.it:8080/ <nome utente>/ e cliccare sul link per testare la servlet • Oppure collegarsi a http://latoserver.dimi.uniud.it:8080/ <nome utente>/servlet/Primo per testare la servlet direttamente senza passare dalla pagina index.html. Complementi di Tecnologie Web – M. Franceschet, V.Della Mea e I.Scagnetto, a.a. 2011/12 - 29 Un esempio più complesso • Vogliamo ora sperimentare l'utilizzo dei FORM e dei vari campi di input di questi ultimi. • Più precisamente scriveremo una pagina (X)HTML contenente un form che chiederà all’utente di inserire alcune informazioni. • Alla pressione del pulsante di invio del form, verrà chiamata una servlet che leggerà i valori inseriti dall’utente e genererà una pagina visualizzandoli. Complementi di Tecnologie Web – M. Franceschet, V.Della Mea e I.Scagnetto, a.a. 2011/12 - 30 Il form: form.html (1) <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3c.org/TR/xhtml1/DTD/xhtml11.dtd"> <html xmlns="http://www.w3.org/1999/XHTML" xml:lang="it" lang="it"> <head> <title>Un semplice form</title> </head> <body> <form method="post" action="servlet/FormTest"> Qual è il tuo nome? <input type="text" name="nome"><br/> Inserisci una password: <input type="password" name="pwd"><br/> Scegli una città: <select name="citta"> <option value="1">Milano</option> <option value="2">Padova</option> <option value="3">Roma</option> <option value="4" selected="true">Udine</option> </select><br /> ... Complementi di Tecnologie Web – M. Franceschet, V.Della Mea e I.Scagnetto, a.a. 2011/12 - 31 Il form: form.html (2) ... Quali mezzi di trasporto usi? <br /> <input type="checkbox" name="trasporto1"> Auto<br /> <input type="checkbox" name="trasporto2"> Bicicletta<br /> <input type="checkbox" name="trasporto3"> Mezzi pubblici<br /> <input type="checkbox" name="trasporto4"> Vado a piedi<br /> Hai detto la verità? Sì <input type="radio" name="dichiarazione" value="S" checked> No <input type="radio" name="dichiarazione" value="N"><br/> <input type="submit" value="Invia >>"> </form> </body> </html> Complementi di Tecnologie Web – M. Franceschet, V.Della Mea e I.Scagnetto, a.a. 2011/12 - 32 La nuova servlet: FormFieldsTest.java (1) import java.io.*; import javax.servlet.*; import javax.servlet.http.*; Recupero dei valori dei campi del form public class FormFieldsTest extends HttpServlet { public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { res.setContentType("text/html"); PrintWriter out = res.getWriter(); String nome=req.getParameter("nome")==null ? "" : req.getParameter("nome"); String password=req.getParameter("pwd")==null ? "" : req.getParameter("pwd"); String citta=req.getParameter("citta")==null ? "" : req.getParameter("citta"); String mezzo1=req.getParameter("trasporto1")==null ? "" : req.getParameter("trasporto1"); String mezzo2=req.getParameter("trasporto2")==null ? "" : req.getParameter("trasporto2"); String mezzo3=req.getParameter("trasporto3")==null ? "" : req.getParameter("trasporto3"); String mezzo4=req.getParameter("trasporto4")==null ? "" : req.getParameter("trasporto4"); String dichiarazione=req.getParameter("dichiarazione")==null ? "" : req.getParameter("dichiarazione"); out.println("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML "+ "1.1//EN\" \"http://www.w3c.org/TR/xhtml1/DTD/xhtml11.dtd\">"); out.println("<html xmlns=\"http://www.w3.org/1999/XHTML\" "+ "xml:lang=\"it\" lang=\"it\">"); ... Complementi di Tecnologie Web – M. Franceschet, V.Della Mea e I.Scagnetto, a.a. 2011/12 - 33 La nuova servlet: FormFieldsTest.java (2) out.println("<head><title>Visualizzare i valori dei campi di un semplice form</title></head>"); out.println("<body>"); out.println("<strong>I valori inseriti nei campi del form sono i seguenti:</strong><br />"); out.println("<br /><strong>Nome:</strong> "+(nome.equals("") ? "n.d." : nome)); out.println("<br /><strong>Password:</strong> "+(password.equals("") ? "n.d." : password)); Stampa i valori out.println("<br /><strong>Città:</strong> "); di nome e int numeroCitta=0; password Conversione a try { numero intero numeroCitta=Integer.parseInt(citta); } catch(NumberFormatException e) { out.println("Errore di formato nella specifica della città! "); numeroCitta=0; } Complementi di Tecnologie Web – M. Franceschet, V.Della Mea e I.Scagnetto, a.a. 2011/12 - 34 La nuova servlet: FormFieldsTest.java switch(numeroCitta) { case 1: out.println("Milano"); break; case 2: out.println("Padova"); break; case 3: out.println("Roma"); break; case 4: out.println("Udine"); break; default: out.println("n.d."); } (3) L'intero che rappresenta la scelta della città diventa argomento di un comando switch. Complementi di Tecnologie Web – M. Franceschet, V.Della Mea e I.Scagnetto, a.a. 2011/12 - 35 La nuova servlet: FormFieldsTest.java (4) ... out.println("<br /><strong>Mezzi di trasporto:</strong>"); out.println(mezzo1.equals("on") ? "<br />Auto" : ""); out.println(mezzo2.equals("on") ? "<br />Bicicletta" : ""); out.println(mezzo3.equals("on") ? "<br />Mezzi pubblici" : ""); out.println(mezzo4.equals("on") ? "<br />Vado a piedi" : ""); out.println("<br /><strong>Dichiarazione di verità:</strong> "+ (dichiarazione.equals("S") ? "sì" : "no")); out.println(""); out.println("</body></html>"); } } Stampa della scelta relativa ai checkbox e al radio button Complementi di Tecnologie Web – M. Franceschet, V.Della Mea e I.Scagnetto, a.a. 2011/12 - 36 Modifiche da apportare a web.xml <?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd"> <web-app> … <servlet> <servlet-name>FormTest</servlet-name> <servlet-class>FormFieldsTest</servlet-class> </servlet> <servlet-mapping> <servlet-name>FormTest</servlet-name> <url-pattern>/servlet/FormTest</url-pattern> </servlet-mapping> </web-app> Complementi di Tecnologie Web – M. Franceschet, V.Della Mea e I.Scagnetto, a.a. 2011/12 - 37 Modifiche da apportare a index.html <HTML> <HEAD> <TITLE>Servlet di prova</TITLE> </HEAD> <BODY> <TABLE> <TR> <TD> <A HREF="servlet/Primo">La mia prima servlet</A> </TD> </TR> <TR> <TD> <A HREF="form.html">Una servlet un po' più complessa</A> </TD> </TR> </TABLE> </BODY> </HTML> Complementi di Tecnologie Web – M. Franceschet, V.Della Mea e I.Scagnetto, a.a. 2011/12 - 38 Gli argomenti dei metodi doGet/doPost • Osserviamo che le servlet sono dei veri e propri programmi Java che vengono invocati dal contenitore di servlet (e.g., Tomcat) per soddisfare le richieste dei client. • L’interfaccia con il protocollo HTTP messa a disposizione del programmatore consiste nell’utilizzo dei metodi dei due argomenti di tipo HttpServletRequest e HttpServletResponse. HttpServletResponse Complementi di Tecnologie Web – M. Franceschet, V.Della Mea e I.Scagnetto, a.a. 2011/12 - 39 HttpServletRequest • E’ un’interfaccia, definita in javax.servlet.http, che aggiunge alla “soprainterfaccia” ServletRequest (per servlet generiche), definita in javax.servlet, metodi specifici per le richieste HTTP. • Rappresenta la richiesta di un client verso una servlet. • L’oggetto corrispondente viene creato dal container (e.g., Tomcat) al momento della richiesta e passato al metodo opportuno della servlet. • Metodi fondamentali: – getInputStream: per leggere informazioni inviate dal client; – getParameter: per estrarre i parametri della richiesta. Complementi di Tecnologie Web – M. Franceschet, V.Della Mea e I.Scagnetto, a.a. 2011/12 - 40 HttpServletResponse • E’ un’interfaccia, definita in javax.servlet.http, che aggiunge alla “soprainterfaccia” ServletResponse (per servlet generiche), definita in javax.servlet, metodi specifici per le richieste HTTP. • Rappresenta la risposta al client da parte di una servlet. • L’oggetto corrispondente viene creato dal container (e.g., Tomcat) al momento della richiesta e passato al metodo opportuno della servlet. • Metodi fondamentali: – setContentType: per specificare il tipo MIME del contenuto che verrà spedito al client – getWriter: restituisce il flusso di dati verso il client. Complementi di Tecnologie Web – M. Franceschet, V.Della Mea e I.Scagnetto, a.a. 2011/12 - 41 Errori comuni • Tomcat manager: "FAIL - Application at context path /test could not be started" - Causa: errore di parsing - controllare il file web.xml. • HTTP Status 404 - Causa: servlet non trovata: – controllare l’URL della servlet ed i link ad essa relativi – controllare che il tag <url-pattern> abbia un "/"iniziale (a differenza degli URL relativi che si usano nelle pagine (X)HTML per richiamare le servlet). • HTTP Status 405 - HTTP method GET is not supported by this URL Causa: la servlet non pu` essere richiamata direttamente tramite il suo URL (non è stato eseguito l’overriding del metodo doGet()). • HTTP Status 500: 500 Errore interno (eccezione) della servlet. Complementi di Tecnologie Web – M. Franceschet, V.Della Mea e I.Scagnetto, a.a. 2011/12 - 42 Esercizi Eseguire il deployment ed il test di FormFieldsTest ( aggiornando anche i file web.xml e index.html) su latoserver.dimi.uniud.it • FormFieldsTest può essere richiamata direttamente (senza passare dal form) tramite il seguente URL? http://latoserver.dimi.uniud.it:8080/<nome utente>/servlet/FormTest Perché? • Apportare le dovute modifiche a FormFieldsTest.java affinché funzioni anche con una richiesta diretta (senza passare dal form). • Scrivere un’applicazione web che generi una pagina HTML con la tabellina Pitagorica. • Complementi di Tecnologie Web – M. Franceschet, V.Della Mea e I.Scagnetto, a.a. 2011/12 - 43
© Copyright 2024 Paperzz