Pagine Web statiche Pagine dinamiche Server-Side in J2EE: S Servlet e JSP S In una pagina web statica il contenuto della pagina viene stabilito al momento della creazione della pagina p g Ogni volta che un utente accede all’URL di una pagina statica, riceverà sempre le stesse informazioni Pagine Web dinamiche Pagine Web dinamiche (2) Una pagina web dinamica o interattiva viene realizzata “al volo” sul web server I contenuti variano in dipendenza degli input e delle richieste dell’utente Una pagina web dinamica è costituita da classico HTML (eventualmente con qualche script lato client) Il browser del client non ha modo di sapere se la pagina richiesta risiedeva già sul web server o è stata generata all’istante. Es. viene interrogato il database e vengono visualizzati i dati che soddisfano una particolare condizione. Pagine dinamiche server-side Per generare delle pagine dinamiche è necessario avere in esecuzione sul web server un applicativo in grado di generare HTML al volo Il web server deve quindi: Elaborare Comporre Per il browser cambiano solo i contenuti, non le tecnologie usate!!! Pagine dinamiche server-side (2) Il codice per generare la pagina dinamica può essere: Programma compilato eseguibile (Java, Visual Basic, C++)) C Programma non compilato (script) che viene interpretato ed elaborato durante l’esecuzione (ASP, JSP) gli input del client dinamicamente una pagina Web Opzionalmente può interagire con un DBMS Inviarla di risposta al client. Programmi e/o script server side vengono eseguiti esclusivamente sul server quindi non dipendono dal browser 1 Tecnologie di DHTML Tecnologie Web/database Elaborazioni dal lato server Programmi compilati Servlet Java CGI Elaborazioni dal lato client Script dal lato server Java Server Page (JSP) Active Server Pages (ASP) Download ed esecuzione di programmi compilati Applet Java Programmi ActiveX JavaScript VBScript Cos’è una servlet Una servlet è una normalissima applicazione Java, eseguita in una JVM (Java Virtual Machine) residente su un web server Ha la particolarità che il suo output è redirezionato verso un web-client Tipicamente Le Servlet Script dal lato client Esecuzione di una servlet l’output è HTML Ha dei metodi già pronti per gestire in modo semple le REQUEST ed i RESPONSE del browser del client Esecuzione di Servlet Le servlet vengono caricate in memoria una sola volta al momento della prima chiamata Le servlet risiedono in memoria tra una richiesta e l’altra Servlet vs. CGI Ogni richiesta NON causa la creazione di un nuovo processo La tecnologia CGI richiede l’esecuzione di un nuovo processo per ogni client connesso al web server. C’è quindi la necessità di eseguire q g una exec p per ogni g richiesta di pagine dinamiche Ottimo modo per divorare le risorse del server! Ciò comporta che le inizializzazioni necessarie vengono eseguite una volta sola Una solo istanza della servlet risponde a più richieste Dispongono di classi per la gestione delle sessioni Consentono una più semplice condivisione dei dati fra le istanze di una servlet Ereditano la portabilità di Java Il client richiede al server web una pagina dinamica Il server richiama la servlet richiesta per la gestione dei contenuti dinamici La servlet viene caricata dinamicamente ed eseguito all’interno della JVM residente sul web server L’output della servlet (HTML) viene inviato al client, dove verrà interpretato dal browser come una normale pagina web Le servlet sono caricate solo una volta, alla connessione del primo client, quindi restano in memoria pronti a servire nuove richieste, anche di client diversi 2 Come eseguire una servlet Environment di esecuzione per Servlet L’esecuzione di servlet richiede delle estensioni del web server E’ necessario un framework aggiuntivo, gg detto Servlet Container E’ un software in grado di: Gestire l’ambiente di esecuzione di Servlet una servlet Caricare una servlet Eseguire una servlet Creare Come eseguire una servlet (2) I Servlet Containers Esistono vari tipi di Containers, in base al grado di interazione con il web server: In-process container container Container stand alone Out-of-process Per i nostri scopi utilizzeremo un Container Stand-Alone Tomcat APACHE JAKARTA TOMCAT è un Web Server stand-alone, supporta le servlets (ver. 2.5) e le JSP (ver. 2.1) Utilizzo di Servlet Per la creazione/testing di servlet occorrono inoltre : Java Virtual Machine Compilatore Java Browser 3 I Package Il package Java di base per le API Servlet è javax.servlet: contiene i prototipi di tutti i metodi necessari alla gestione del ciclo di vita di una servlet e alla esecuzione delle operazione implementate dal servlet Tutte le servlet sono classi che implementano l’interfaccia servlet, in maniera diretta, o estendendo una classe che la implementa, come ad esempio HttpServlet I Package (2) Sono due i package che utilizzeremo per la generazione di servlet: contiene la definizione dell’interfaccia Servlet e contiene classi utili alla comunicazione fra client e server L’interfaccia servlet I Package utilizzati javax.servlet javax.servlet.http Il package javax.servlet contiene le interfacce generiche e le classi che vengono implementate ed estese da tutte le servlet Il package javax.servlet.http è specializzato per servlet che operano su HTTP (Quelle usate per rispondere HTML ad un client) L’interfaccia javax.servlet.Servlet L’interfaccia javax.servlet.Servlet fornisce il supporto per tutte le servlet Definisce 5 metodi. I 3 piu’ importanti sono: init() Inizializza una servlet service() Gestisce richieste e risposte per i client destroy() Libera la memoria non piu’ utilizzata Ciclo di vita di un servlet Il ciclo di vita di una servlet segue una struttura ben precisa: 1. 2. 3. La servlet viene costruita e inizializzata La servlet serve una o piu’ richieste fino a che il servizio viene chiuso La servlet viene distrutta e lo spazio che occupava recuperato Tutte le servlet devono implementare questa interfaccia, direttamente o tramite ereditarietà Ciclo di vita di una servlet (2) Il ciclo di vita di una servlet: Loading: caricamento e istanziazione sono eseguiti dal web server e avvengono al momento della prima richiesta da parte di un client 2 Inizializzazione: in questa fase la servlet carica dati persistenti 2. persistenti, apre connessioni verso DB, ecc... Questa operazione avviene tramite la chiamata al metodo init(). 3. Gestione richieste e risposte del client: il metodo eseguito all’arrivo di una nuova richiesta è il metodo service(), che riceve come parametri gli oggetti ServletRequest e ServletResponse per gestire le richieste 4. Terminazione (tipicamente quando termina l’esecuzione del web server): si specifica come rilasciare le risorse occupate. Questa operazione avviene tramite la chiamata al metodo destroy() 1. 4 Il metodo service() E’ invocato dal Servlet Container ogni volta che un client accede al servlet E E’ in grado di interpretare la richiesta del client e di rispondere di conseguenza Utilizza le classi: HttpServlet ServletRequest ServletResponse La classe HttpServlet Un po’ di HTTP HttpServlet è una specializzazione di GenericServlet Implementa metodi dell dell’interfaccia interfaccia Servlet Mette a disposizione alcuni metodi di alto livello per la gestione di dati Http Un po’ di HTTP (2) La classe HttpServletRequest Un client può richiamare una risorsa web utilizzando due comandi HTTP: GET E E’ tipicamente usato per una semplice richiesta di risorse Consiste nel riferimento all’URL della risorsa. I messaggi HTTP sono di 2 tipi: Request Response Meccanismo di base: Si apre una connessione TCP tra client e server Il browser richiede una risorsa al server http (web server) 3. Il server risponde (se possibile, fornendo la risorsa richiesta) 4. Si chiude la connessione 1. 2. Fornisce al servlet i metodi per accedere ai parametri passati dal client Mediante i metodi di questa classe è possibile: 1. accedere a parametri o meta informazioni relative alla richiesta. Es: POST E’ tipicamente usato per spedire informazioni al web server La richiesta della risorsa è inviata al server nell’header della richiesta HTTP. 2. getRequestURI() restituisce l’URI richiesto getMethod() fornisce il metodo HTTP utilizzato per inoltrare la richiesta getParameter(String) consente di accedere per nome ai parametri contenuti nella query string creare gli stream di input e la possibilità quindi di ricevere i dati della richiesta attraverso i metodi getInputStream e getReader 5 La classe HttpServletResponse Fornisce alla servlet i metodi per rispondere al client: Il metodo service() Permette di fissare parametri relativi alla risposta i i t ((come llunghezza inviata h o titipo MIME) Rende possibile il reindirizzamento Fornisce i metodi per creare gli stream di output e la possibilità quindi di inviare i dati della risposta. A differenza di quanto avviene con GenericServlet, se si estende HttpServlet non è solitamente necessario implementare il metodo service(): ci pensa la classe HttpServlet Il prototipo del metodo service() è il seguente: Protected void service(HttpServlet req, HttpServletResponse resp)throws ServletException, IOException; getOutputStream per l’invio di dati in forma binaria getWriter per l’invio attraverso il canale System.out Definisce una serie di constanti per inviare al browser il risultato della operazione richiesta Il metodo service() (2) HttpServlet Usando HTTP, lo scopo del metodo service() è di invocare i metodi doGet() o doPost(), in base al tipo di richiesta inviata dal client. Se il metodo service() non viene sovrascritto, la nostra classe eredita il metodo definito all’interno della classe che estendiamo Nel caso non si implementi una nuova versione del metodo service() sarà necessario implementare nella nostra classe i metodi doGet() e/o doPost(), in base al tipo di richiesta da gestire. Esecuzione di un servlet Client 1 Thread 1 init() service() doGet(req,res) Get La Servlet “Hello World” import java.io.*; import javax.servlet.*; import javax.servlet.http.*; HTML public class HelloWorldServlet extends HttpServlet { public pub c void o d doGet( doGet(HttpServletRequest ttpSe et equest req, eq, HttpServletResponse res) throws IOException, ServletException { res.setContentType("text/html"); PrintWriter out = res.getWriter(); out.println("<html>"); Ser let Servlet Thread 2 Client 2 Get service() doGet(req,res) Oltre a questi due tipi di metodi ne esistono altri e tutti hanno lo stesso insieme di parametri del metodo service() HTML out.println("<head><title>HelloWorldServlet</title></head>"); out.println("<body><h1>HelloWorld, by Servlet</h1></body>"); out.println("</html>"); out.close(); } } 6 L’output ricevuto dal client Gestire gli input dell’utente import java.io.*; import javax.servlet.*; import javax.servlet.http.*; <html> public class HelloWorldServlet extends HttpServlet { <head> <title>HelloWorldServlet</title> </head> public void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException IOException, ServletException { String name = "param"; String value = req.getParameter(name); <body> <h1>HelloWorld, by Servlet</h1> </body> res.setContentType("text/html"); PrintWriter out = res.getWriter(); out.println("<html>"); out.println("<head><title>HelloWorldServlet</title></head>"); out.println("<body><h1>HelloWorld, by Servlet</h1></body>"); out.println("</html>"); out.close(); </html> } } Considerazioni sulle servlet Le Java Server Pages Le servlet sono una delle più potenti tecnologie server-side Permettono con facilità di: Leggere L glili h header d d delle ll richieste i hi t HTTP dati da form HTML Impostare header di response HTTP Condividere dati tra servlet Utilizzare cookies Memorizzare dati tra richieste successive Leggere 39 Limitazioni delle servlet 40 Limitazioni delle servlet Presentano però una grossa limitazione: Utilizzano istruzioni di println per generare codice HTML E’ difficile manutenere l’HTML creare una pagina web sono richieste conoscenze avanzate di Java Non è possibile usare strumenti di authoring affermati (es: Dreamweaver) Per 41 Le servlet, in pratica, concentrano l’attenzione sulla “business logic” invece che sulla “presentation p logic” g Gli sforzi vanno concentrati su JAVA piuttosto che su HTML 42 7 Le Java Server Pages Vantaggi di JSP IDEA: Invertire l’approccio delle Servlet Invece che avere codice HTML in una classe Java, inseriamo istruzioni di scripting Java in una pagina HTML Esempio: <html> <body> <% out.println("Hello World"); %> </body> </html> Tecnicamente, le JSP hanno esattamente la stessa potenza delle servlet Le JSP però rendono più facile: Scrivere Leggere HTML e manutenere HTML Le JSP inoltre rendono possibile: Utilizzare tool di authoring standard un team di sviluppo più mirato, con alcune figure skillate su JAVA ed altre su HTML Avere Infine le JSP incoraggiano la separazione del codice Java che crea i contenuti, dal codice HTML che li presenta 43 44 Struttura di una JSP Come funzionano le JSP Le pagine JSP sono semplici documenti testuali (con estensione .jsp) che combinano tag HTML con tag di scripting Il codice JSP è racchiuso in vari tag che seguono la sintassi XML. I tag di chiusura sono obbligatori. I tag JSP rilevano le maiuscole e le minuscole. 45 46 Esecuzione di una JSP Il JSP Container Aspetto fondamentale della tecnologia JSP: Ogni g p pagina g JSP viene tradotta in un Servlet traduzione è trasparente per il programmatore Viene effettuata da un’estensione del Web Server Similmente ai Servlet, per distribuire una pagina JSP, il Web Server deve includere un “JSP container”, Il JSP container è un ambiente software che legge la pagina JSP e la utilizza come modello per creare e compilare una servlet. Il JSP container invoca la servlet temporanea, che crea la pagina web da inviare all’utente. Es: Questa 47 Tomcat è sia un Servlet che un JSP container container. 48 8 Compilazione Ciclo di vita di una JSP Il ciclo di vita di una pagina JSP prevede 5 step: 1. Compilazione C il i Caricamento Inizializzazione Esecuzione Cleanup 2. 3. 4. 5. Quando un client richiede una pagina JSP, il Web Server controlla se la pagina richiesta deve essere compilata. Se la pagina non è stata mai compilata oppure sono state apportate delle modifiche dalla ultima compilazione, il JSP container la compila. Il processo di compilazione implica tre step: Parsing della JSP di una servlet, Compilazione della servlet. Creazione 49 50 Il caricamento Inizializzazione Quando un client richiede una pagina JSP, il Web Server controlla se la servlet corrispondente p alla p pagina g richiesta sia g già in esecuzione Quando la pagina JSP è inizializzata viene invocato il metodo jspinit(). Se lo sviluppatore ha la necessità di una inizializzazione personalizzata è necessario ridefinire tale metodo. 51 52 Esecuzione Cleanup Ogni volta che un browser richiede una pagina caricata ed inizializzata , il JSP container ne invoca il corrispondente metodo t d _jspService(). j S i () Lo sviluppatore non dovrebbe ridefinire tale metodo, poichè viene generato dal compilatore JSP. Al termine dell’esecuzione, il JSP container invoca il metodo jspDestroy() per deallocare eventuali risorse richieste p nella fase di inizializzazione. public void _jspService(ServletRequestSubtype request, ServletResponseSubtype response) throws ServletException, IOException; 53 54 9 Riassumendo JSP: sviluppo e installazione Sviluppo: abbastanza semplice (se la JSP è usata correttamente: per gestire prevalentemente la presentazione) Installazione: è sufficiente copiare la pagina JSP in una directory della applicazione Web. Una JSP assume tre forme diverse: Il file sorgente .jsp contenente il codice HTML e gli elementi JSP Il codice sorgente Java di una classe servlet La classe Java compilata Non sono necessarie operazioni di configurazione (come ad esempio la scrittura di informazioni nel descrittore della applicazione web.xml) NOTA: Scrivere applicazioni Web usando solo JSP è molto simile a scrivere applicazioni Web che adottano altre tecnologie (ad es. Php o MS ASP) Java-Server-Pages Tipi di tag Istruzioni JSP Il tag <%...%> viene utilizzato per indicare la presenza di codice Server-Side nella pagina p g HTML. Le specifiche JSP permettono di usare, oltre a JAVA, altri linguaggi di scripting. Attualmente solo pochi web server supportano altri linguaggi. 57 58 Java-Server-Pages Esempio 1 Esempio 1: Risultato nel Browser <HTML> <BODY bgcolor=yellow> <FONT COLOR=“#FF0000”> <% out.println(“<H1>esempio di tag </H1>”); Out è una istanza della %> classe JspWriter, utilizzata </FONT> per inviare la risposta al browser </BODY> </HTML> 59 60 10 Java-Server-Pages Esempio 1: Servlet generata private static java.util.Vector _jspx_includes; Esempio 1: HTML generato session = pageContext.getSession(); out = pageContext.getOut(); _jspx_out = out; public java.util.List getIncludes() { return _jspx_includes; } public void _jspService(HttpServletRequest request, HttpServletResponse response) throws java.io.IOException, ServletException { <HTML> <BODY bgcolor=yellow> <FONT COLOR=“#FF0000”> <H1>esempio di tag </H1> </FONT> </BODY> </HTML> out.write("<HTML>\r\n"); out.write("<BODY bgcolor=yellow>\r\n\r\n"); out.write("<FONT COLOR=\"#FF0000\">\r\n"); out.println("<H1>esempio di tag </H1>"); JspFactory _jspxFactory = null; j javax.servlet.jsp.PageContext l tj P C t t pageContext C t t = null; ll HttpSession session = null; ServletContext application = null; ServletConfig config = null; JspWriter out = null; Object page = this; JspWriter _jspx_out = null; try { _jspxFactory = JspFactory.getDefaultFactory(); response.setContentType("text/html;charset=ISO-8859-1"); pageContext = _jspxFactory.getPageContext(this, request, response, null, true, 8192, true); application = pageContext.getServletContext(); config = pageContext.getServletConfig(); out.write("\r\n"); out.write("</FONT>\r\n \r\n\r\n"); out.write("</BODY>\r\n"); out.write("</HTML>"); } catch (Throwable t) { out = _jspx_out; if (out != null && out.getBufferSize() != 0) out.clearBuffer(); if (pageContext != null) pageContext.handlePageException(t); } finally { if (_jspxFactory != null) _jspxFactory.releasePageContext(pageContext); } } } 61 62 Java-Server-Pages Il tag <%= Esempio 2 Il tag <%= … %> è una notazione compatta per sostituire la chiamata al metodo println() dell’oggetto gg out E’ equivalente scrivere: <%out.println(“<H1>esempio di tag </H1>”);%> e <%= “<H1>esempio di tag</H1>” %> <HTML> <BODY bgcolor=yellow> <FONT COLOR=“#FF0000”> <%= “<H1>esempio <H1>esempio di tag</H1>” tag</H1> %> </FONT> </BODY> </HTML> 63 64 Java-Server-Pages I commenti (1) I commenti (2) Il Tag <!- - - -> Il tag <%- - - -%> <html> <body> b d <FONT COLOR="#FF0000"> <!-- Questo è un commento che utilizza TAG di HTML --> <%= "<H1>Hello World!!!</H1>" %> </FONT> </body> </html> 65 <html> <body> <FONT COLOR="#FF0000"> <%-- Questo è un commento che non apparirà nella Servlet --%> <%= "<H1>Hello World!!!</H1>" %> </FONT> </body> </html> 66 11 Java-Server-Pages Dichiarazione di metodi e di variabili in una pagina JSP I commenti (3) I commenti con la sintassi Java Il tag <%! … %> consente di inserire l’implementazione di metodi scritti in JAVA nelle pagine JSP. <HTML> <BODY> <H1> H1 <%! <html> <body> y <FONT COLOR="#FF0000"> <% /* Questo è un commento che utilizza la sintassi prevista da Java per i commenti */ %> <%= "<H1>Hello World!!!</H1>" %> </FONT> </body> </html> public String my_method(String param) { return "Benvenuti al corso di " + param; } %> <%=my_method(“Basi di dati su rete")%> </H1> </BODY> </HTML> 67 68 Java-Server-Pages Esempio 3-risultato Scriptlet E’ possibile immergere i tag nelle strutture di controllo Esempio: <% String nome=(String)request.getParameter(“nome”); if (nome==null) { %> <p>Benvenuto, immetti il tuo nome</p> <form action=“...” method=“...”>...</form> <% } else { %> <p>Benvenuto, <% out.print(nome);%> </p> <% } %> 69 Scriplet <html> <body> <h1>Tavola pitagorica</h1> <table> <% % for o ( (int t i = 1; ; i<= 10; 0; i++) ) { % %> <tr> <% for (int j=1; j<= 10; j++) { %> <td> <% out.print(i*j); %> </td> <% }%> </tr> <% }%> </table> </body> </html> Elementi JSP 72 12 Java-Server-Pages Java-Server-Pages Elementi JSP Le direttive La parte delle pagine JSP che viene processata dal server può essere classificata nelle seguenti g categorie g : Le direttive sono dei messaggi per il JSP container. Vengono utilizzate per settare le variabili globali non ¾Le direttive ¾Le azioni producono output al client. Tutte le direttive hanno come scope la pagina JSP corrente. La sintassi è la seguente : ¾Gli oggetti impliciti di una pagina JSP <%@ nome_direttiva attributo=“valore”%> 73 74 Java-Server-Pages Tipi di direttive Java-Server-Pages Le direttive di Page Vi sono tre tipi di direttive : Definiscono importanti attributi che influenzano l’intera pagina. In una pagina JSP è possibile specificare più direttive page a patto che le opzioni siano uniche. Sintassi : ¾page ¾include ¾taglib <%@ page Attributo %> 75 76 Java-Server-Pages Le direttive di Page Attributi principali (ce ne sono altri) import content-type co te t type session errorPage isErrorPage info La direttiva Page Il parametro import E’ utilizzato per indicare al JSP engine quali package importare durante la compilazione E’ l’unico che può avere valori multipli <%@ page import=“java.sql.*, java.util.*” %> 78 13 Java-Server-Pages Java-Server-Pages La direttiva Page La direttiva Page Il parametro session. E’ utilizzato per indicare al JSP engine se la pagina utilizza gli oggetti session. Assume un valore booleano. Il parametro Info. Inserisce una stringa recuperabile dal metodo Servlet.getServletInfo(). <%@ page session=“true” %> <%@ page info=“JSP che controlla i dati” %> <%@ page session=“false” %> 79 80 Java-Server-Pages Java-Server-Pages La direttiva Page Il La direttiva Page parametro errorPage Il Se si verifica una eccezione non catturata il container passerà alla pagina error_url. parametro iserrorPage isErrorPage impostato a true indica al JSP container che la pagina corrente può essere utilizzata come error page da un’altra JSP JSP. <%@ page isErrorPage=“true” %> <%@ page errorPage=“error_url” %> 81 82 Java-Server-Pages Java-Server-Pages La direttiva Page Il Esempio : contentType = text/xml parametro contentType contentType permette di specificare il formato dei dati che si stanno per ritornare al browser. <%@ page contentType=“text/html” %> Possiamo utilizzare l’ attributo contentType della direttiva page per generare un documento XML g dinamicamente. <%@ page contentType=“text/xml” %> 83 84 14 Java-Server-Pages Java-Server-Pages Esempio : contentType = text/xml Output della pagina JSP <%@ page contentType="text/xml"%> <!-- l' usato su strada --> <veicoli> <automobili> <fiat>punto 1.4 benzina</fiat> <BMW>Z3</BMW> <mercedes>mercedes compressor</mercedes> p <citroen>C3 1.2 benzina</citroen> </automobili> <ciclomotore> <ducati>ducati monster</ducati> <kawasaki>ZXR 900</kawasaki> <piaggio>free</piaggio> </ciclomotore> </veicoli> 85 86 Java-Server-Pages Gli oggetti impliciti di una JSP Ogni pagina JSP ha accesso ad una serie di oggetti impliciti Questi possono essere usati come variabili JAVA negli scriptlet(<%...%>) e nelle espressioni (<%=...%>) ma non in dichiarazioni (<%! ...%>). Gli oggetti impliciti 87 88 Java-Server-Pages Java-Server-Pages Gli oggetti impliciti di una JSP Gli oggetti impliciti di una JSP application è una istanza della classe javax.servlet.ServletContext ed ha un ciclo di vita pari a quello dell’ applicazione; contiene i dati condivisi da tutte le servlet in una specifica p applicazione. pp config è una istanza della classe javax.servlet.ServletConfig e contiene informazioni di configurazione per la pagina JSP.Ha un ciclo di vita page. exception è una istanza della classe java.lang.Throwable avente un ciclo di vita page. È disponibile solo nelle pagine di errore(quelle con l’attributo isErrorPage=true). 89 out è una istanza della classe javax.servlet.jsp.JspWriter ed ha un ciclo di vita pari a page. È utilizzato per spedire una risposta al browser. page è una istanza della classe java java.lang.Object lang Object ed ha un ciclo di vita pari a page. Rappresenta la corrente pagina JSP e come in JAVA vi si può accedere mediante il puntatore implicito this. pageContext è una istanza della classe javax.servlet.jsp.PageContext,ha un ciclo di vita pari a page. Esso contiene i riferimenti alla maggior parte degli oggetti presenti in una JSP. 90 15 Java-Server-Pages Gli oggetti impliciti di una JSP Sommario request è una istanza della classe javax.servlet.http.HttpServletRequest, ha un ciclo di vita pari al contesto della richiesta. Esso memorizza informazioni riguardanti le richieste entranti. response è una istanza della classe javax.servlet.http.HttpServletResponse, ha un ciclo di vita pari a page. Esso contiene informazioni riguardanti la risposta da inviare al client ed i cookies. session è una istanza della classe javax.servlet.http.HttpSession, ha un ciclo di vita pari a session.Esso contiene i dati associati alla sessione intraprese con il browser. Sintassi elementi JSP Commenti JSP <%-- commento JSP --> Scriplet <% codice Java %> Espressioni <%= espressione Java %> Dichiarazioni <%! Definizione di metodi e variabili %> Direttive <%@ direttiva attr1="val1"… attrN="valN" %> 91 Java-Server-Pages Utilizza il metodo get per Richiama la Una form HTML inviare dei valori al server pagina che saranno visibili nell’ <HTML> form1_handler.jsp URL; con il metodo POST <BODY> che costruirà la <H1> Informazioni</H1> tali varlori non saranno <FORM action="form1_handler.jsp" method="get">risposta da inviare visibili all’utente Cognome: <INPUT type="text" name="Nome"> al browser Nome: <INPUT type="text" name="Cognome"> <p> Sesso: <INPUT type="radio" checked name=“sex" value="Maschio"> Maschio <INPUT type="radio" name=" sex " value="Femmina"> Femmina <P> I quale In l personaggio i ti identifichi id tifi hi ? <SELECT name=“star"> <OPTION value="pippo"> pippo </option> <OPTION value="pluto"> pluto </option> <OPTION value="paperino"> paperino </option> <OPTION value="minny"> minny </option> <OPTION value="topolino"> topolino </option> </SELECT> <p> <INPUT type="submit" value="INVIA DATI"> </FORM> </BODY> </HTML> JSP ed i Form 93 form1.html Java-Server-Pages 94 Java-Server-Pages La risposta JSP alla form Output della form Request è uno dei tanti oggetti impliciti presenti in una pagina JSP e memorizza le richieste entranti Mediante l’ oggetto <HTML> request accediamo al <BODY> metodo getParameter <% per recuperare il Ivalore nomi delle variabili String nome=request.getParameter(“Nome"); della form devono avere un String cognome =request.getParameter(“Cognome"); match con q quelle String sesso=request.getParameter("sex"); presenti nella form String personaggio=request.getParameter("star"); %> <%-- Stampa un messaggio con i parametri passati --%> <H1>Ciao, <%=nome%> <%=cognome%> !</H1> Adesso so che sei: <b><%=sesso%></b><br> e ti senti un <b><%=personaggio%></b> </BODY> </HTML> form1_handler.jsp 95 96 16 Java-Server-Pages Output della risposta Java-Server-Pages Una form con valori multipli <HTML> <BODY> <H1>Inserisci una lista di nomi</H1> <FORM action=“form2_handler.jsp" method="get"> <INPUT type="text" name="names"><BR> <INPUT type="text" name="names"><BR> <INPUT type="text" name="names"><BR> <INPUT type="text" name="names"><BR> <INPUT type="text" name="names"><BR> <INPUT type="submit“ value=“Invia query”> </FORM> </BODY> </HTML> Form2.html 97 Java-Server-Pages Java-Server-Pages input form HTML Æ handler form JSP Interazione tra le pagine 98 <!-- PRIMA PARTE --> <HTML> <HEAD> <TITLE>Questionario di preferenza</TITLE> </HEAD> <BODY bgcolor="#ffffff"> <B>Questionario di preferenza</B> <BR> <P> Per favore spendi un pò del tuo tempo per compilare un questionario <P> <FORM action=“form3_handler.jsp" method="POST"> Vi sono vari meccanismi che permettono di gestire le form, i più comuni sono : input form HTML Æ handler form JSP input form JSP Æ handler form JSP ¾ JSP singola ¾ ¾ form3.html 99 Java-Server-Pages input form HTML Æ handler form JSP 100 Java-Server-Pages input form HTML Æ handler form JSP <!-- SECONDA PARTE --> 1. Quale dei seguenti linguaggi preferisci per sviluppare software ? <BR> <SELECT name="langpref"> <OPTION value="c++">C/C++</OPTION> <OPTION value="java" SELECTED>Java</OPTION> <OPTION value= value="vb">Visual vb >Visual Basic</OPTION> </SELECT> <P> 2. Quale sistema operativo preferisci per sviluppare software ? <BR> <input type="radio" name="osdevpref" value="windows">Windows 98/NT<BR> <input type="radio" name="osdevpref" value="linux" checked>Linux<BR> <input type="radio" name="osdevpref" value="unix">Unix<BR> <P> form3.html 101 <!-- TERZA PARTE --> 3. Attualmente la tua compagnia che sistema operativo utilizza ? <BR> <input type="checkbox" name="osuse" value="windows">Windows 98/NT<BR> <input type="checkbox" name="osuse" checked value="linux">Linux<BR> <input type="checkbox" name="osuse" value="unix">Unix<BR> <input i t type="checkbox" t " h kb " name="osuse" " " value="os/2">OS/2<BR> l " /2" OS/2 BR <P> 4. Che tecnologia stai pianificando per valutare i successivi 12 mesi ? <BR> <SELECT name="technologies" multiple size=3> <option value="CORBA">Corba</OPTION> <option value="RMI">RMI</OPTION> <option value="EJB">EJB</OPTION> <option value="COM">COM</OPTION> <option value="XML">XML</OPTION> form3.html 102 17 Java-Server-Pages input form HTML Æ handler form JSP <-- QUARTA PARTE --> </SELECT> <P> <P> <TABLE> <TR> <TD>Nome:<TD><INPUT type="text" name="name"> <TD><FONT SIZE=-1 COLOR="#ff0000">*</FONT>E-Mail: <TD><INPUT type="email" name="email"> </TABLE> <FONT SIZE=-1>*Non daremo il tuo indirizzo e-mail a nessuno <P> <INPUT TYPE="submit" value="Submit questionario"> </FORM> </BODY> </HTML> Java-Server-Pages Output della form HTML Sergio form3.html 103 104 Java-Server-Pages Java-Server-Pages input form HTML Æ handler form JSP input form HTML Æ handler form JSP <-- PRIMA parte --> <%@ page language="java" import="java.io.*" %> <HTML> <BODY bgcolor="#ffffff"> <% String langpref = request.getParameter("langpref"); String osdevpref = request request.getParameter( getParameter("osdevpref"); osdevpref ); // osuse is a checkbox, there are multiple values String[ ] osuse = request.getParameterValues("osuse"); if (osuse == null) osuse = new String[0]; // technologies is a multi-values select, there are multiple values String[ ] technologies = request.getParameterValues( "technologies"); if (technologies == null) technologies = new String[0]; String name = request.getParameter("name"); String email = request.getParameter("email"); // SECONDA PARTE // scrive il risultato nel file try { PrintWriter fileOut = new PrintWriter( new FileWriter("survey.out", Fil W it (" t" true)); t )) fileOut.println(langpref); fileOut.println(osdevpref); // print the values separated by commas for (int i=0; i < osuse.length; i++){ if (i > 0) fileOut.print(", "); fileOut.print(osuse[i]); } fileOut.println(); form3_handler.jsp form3_handler.jsp 105 Java-Server-Pages 106 Java-Server-Pages input form HTML Æ handler form JSP input form HTML Æ handler form JSP <-- TERZA PARTE --> // stampa i valori separati da virgole for (int i=0; i < technologies.length; i++){ if (i > 0) fileOut.print(", "); fileOut print(technologies[i]); fileOut.print(technologies[i]); } fileOut.println(); fileOut.println(name); fileOut.println(email); fileOut.println("-----"); fileOut.close(); %> <-- QUARTA PARTE --> <H1>Grazie !</H1> Grazie per aver partecipato al questionario.Il tuo feedback è importante! <% } catch (IOException ioExc){ application log("Error application.log( Error saving survey results" results , ioExc); %> <H1>Sorry!</H1> si è verificato un errore nel server, non posso salvare il risultato del test. <% } %> </BODY> </HTML> form3_handler.jsp form3_handler.jsp 107 108 18 Java-Server-Pages Java-Server-Pages input form JSP Æ handler form JSP Output della pagina JSP In alcuni casi vi è la necessità di generare form di input in maniera dinamica. Consideriamo ll’esempio esempio di una questionario online nel quale le domande sono memorizzate in un file di dati. La pagina JSP legge il file e costruisce la form di input. c/c++ unix linux, unix File di output che contiene le risposte Sergio [email protected] ----- 109 110 Java-Server-Pages Java-Server-Pages input form JSP Æ handler form JSP <-- PRIMA PARTE --> <%@page language="java" import="java.io.*,java.util.*" %> <HTML> <BODY bgcolor="#ffffff"> <% try Lettura delle informazioni { da file per creare File pollFile = null; la form di input pollFile = new File("poll.in"); // Open the poll file BufferedReader in = new BufferedReader(new FileReader(pollFile)); // The poll question should be on the first line String question = in.readLine(); String line; Vector answers = new Vector(); input form JSPÆ handler form JSP <-- SECONDA PARTE --> // Now read each possible answer, one per line while ((line = in.readLine()) != null) { Vengono lette le possibili answers.addElement(line); domande e visualizzate } in.close(); // Now display the question and the possible answers %> <%-- First display the question --%> <P> Please take a few moments to respond to our poll <P> <FORM action="PollVote.jsp" method="POST"> <B><%=question%></B> poll.jsp poll.jsp 111 Java-Server-Pages 112 Java-Server-Pages input form JSP Æ handler form JSP input form JSP Æ handler form JSP <-- TERZA PARTE --> <BR> <%-- Now loop through the possible answers --%> <% Enumeration e = answers.elements(); Creazione della while (e.hasMoreElements()) form di input { String answer = (String) e.nextElement(); %> <INPUT type="radio" name="answer" value="<%=answer%>"> <%=answer%> <BR> <% } %> <P> <INPUT type="submit" value="Vote"> </FORM> poll.jsp <-- QUARTA PARTE --> <%-- Now handle the case of an IOException while reading the poll file --%> <% } catch (IOException exc) { %> <H1>Sorry</H1> The poll is currently unavailable. Please try again later. <% } %> </BODY> </HTML> 113 poll.jsp 114 19 Java-Server-Pages input form JSP Æ handler form JSP Java-Server-Pages input form JSP Æ handler form JSP <-- PRIMA PARTE --> <%@ page language="java" import="java.util.*,java.io.*" %> <HTML> <BODY bgcolor="#ffffff"> <% String answer = request.getParameter("answer"); if (answer == null) { %> <H1>Oops!</H1> You tried to vote without voting on anything! </BODY> </HTML> <% return; } Si effettua la lettura dal file poll.in pollvote.jsp 115 116 Java-Server-Pages input form JSP Æ handler form JSP Java-Server-Pages input form JSP Æ handler form JSP //<-- SECONDA PARTE --> try { File pollFile = null; File tempFile = null; pollFile = new File("poll.dat"); tempFile = new File("poll.tmp"); boolean createSucceeded = false; // Loop until the file is available or there have been too many tries for (int i=0; i < 30; i++) { // Only one process or thread can create the temp file, others fail // if the file exists. In other words, only one thread can be updating // the poll data. if (tempFile.createNewFile()) { createSucceeded = true; break; } 117 118 pollvote.jsp Java-Server-Pages input form JSP Æ handler form JSP Java-Server-Pages input form JSPÆ handler form JSP // <-- QUARTA PARTE --> try { // Try to read the poll.dat file BufferedReader in = new BufferedReader(new FileReader(pollFile)); // Output will go to the temp file PrintWriter pollOut = new PrintWriter(new FileWriter(tempFile)); String line; boolean foundAnswer = false; while ((line = in.readLine()) != null) { // The poll.dat file should have lines in the form count:answer // Split out the count and the answer here int colonPos = line.indexOf(':'); // If there is no colon, just skip the line if (colonPos < 0) continue; String countStr = line.substring(0,colonPos); String answerStr = line.substring(colonPos+1); int count = 0; try { count = Integer.parseInt(countStr); } catch (Exception ignore) {} <-- TERZA PARTE --> // Up to this point, the create has failed. Sleep for 1 second // and try again try { Thread.sleep(1000); } catch (Exception ignore) {} } if (!createSucceeded) { throw new IOException("Unable to lock file"); } // Create a temporary holder for the counts and answers Vector counts = new Vector(); Vector answers = new Vector(); int totalVotes = 0; pollvote.jsp Sincronizzazione dei thread Attraverso File/Semaforo 119 pollvote.jsp 120 20 Java-Server-Pages input form JSPÆ handler form JSP <-- QUINTA PARTE --> // Compare the answer sent from the user with the answer on this // line. If they are the same, increment the count if (answerStr.equals(answer)) { foundAnswer = true; count++; t } totalVotes = totalVotes + count; pollOut.println(count+":"+answerStr); // Save the answer and the current count answers.addElement(answerStr); counts.addElement(new Integer(count)); } pollOut.close(); in.close(); Java-Server-Pages input form JSPÆ handler form JSP // <--SESTA PARTE --> // Now replace the original poll file with the new one pollFile.delete(); tempFile.renameTo(pollFile); if (!foundAnswer) { %> <H1>Unexpected Answer</H1> You entered an answer that the vote taker doesn't recognize. </BODY> </HTML> <% return; } } pollvote.jsp pollvote.jsp 121 122 Java-Server-Pages input form JSPÆ handler form JSP <-- SETTIMA PARTE --> catch (IOException ioExc) { // If there's an error, just delete the temp file, meaning that this // vote won't be counted and another process can try recording a vote try { t tempFile.delete(); Fil d l t () } catch (Exception ignore) {} %> <H1>Sorry!</H1> The vote taker is unable to record your vote. Please try again later. </BODY> </HTML> <% return; } %> pollvote.jsp 123 Java-Server-Pages input form JSPÆ handler form JSP <!--OTTAVA PARTE --> <%-- Now display the poll results --%> <H2>Thank you for your vote!</H1> <P> <B>Here are the current poll results:</B> <P> <TABLE> <% % int numAnswers = answers.size(); for (int i=0; i < numAnswers; i++) { String currAnswer = (String) answers.elementAt(i); Integer count = (Integer) counts.elementAt(i); int countPct = 0; if (totalVotes > 0) { countPct = (100 * count.intValue()) /totalVotes; } %> pollvote.jsp 124 Java-Server-Pages Java-Server-Pages input form JSPÆ handler form JSP input form JSPÆ handler form JSP <-- NONA PARTE --> <TR> <TD><IMG SRC="pollbar.gif" HEIGHT=20 WIDTH="<%=countPct*3%>"> <TD><%=currAnswer%> <TD><%=count%> (<%=countPct%>%) <% } %> </TABLE> There have been <%=totalVotes%> votes so far. <% } catch (Exception exc) { application.log("Error recording vote", exc); %> <H1>Sorry!</H1> The vote taker is unable to record your vote. Please try again later. <% } %> </BODY> </HTML> pollvote.jsp 125 126 21 Java-Server-Pages JSP singola Java-Server-Pages Jsp singola A volte può essere utile usare lo stesso file jsp per l’input form ed il gestore della form. Tipicamente i due aspetti possono essere combinati quando l’utente deve usare il form più volte, vedendo il risultato della precedente form. Vi sono diverse tecniche per individuare la presenza di precedenti data form: Cercare la presenza di variabili nel form. Passare una speciale variabile che indica lo stato della form. Passare la form usando il metodo POST di HTTP ed esaminare il metodo dell’ oggetto request nella form. <--PRIMA PARTE--> <HTML> <BODY> <% String firstName = request.getParameter("firstname"); if (firstName == null) firstName = ""; String lastName = request.getParameter("lastname"); if (lastName == null) lastName = ""; String address = request.getParameter("address"); if (address == null) address = ""; String city = request.getParameter("city"); if (city == null) city = ""; String state = request.getParameter("state"); if (state == null) state = ""; String zip = request.getParameter("zip"); if (zip == null) zip = ""; String formatOption = request.getParameter("formatoption"); if (formatOption == null) formatOption = ""; // Since some fields are required, set the default style for the "required" // labels String firstNameRequiredColor = "black"; String lastNameRequiredColor = "black"; String zipRequiredColor = "black"; String requiredNotifyColor = "red"; NameFormatter.js 127 128 Java-Server-Pages Jsp singola Jsp singola <-- SECONDA PARTE--> // When this form is originally shown, it is fetched by an HTTP GET // request, but in the METHOD option in the FORM tag below, the form // is fetched using an HTTP POST command. // See if this form was submitted (i.e. the user filled in the form // and pressed the submit button) if (request.getMethod().equals("POST")) { boolean allRequiredFieldsPresent = true; // See if any of the required fields are blank if (firstName.length() == 0) { firstNameRequiredColor = requiredNotifyColor; allRequiredFieldsPresent = false; } if (lastName.length() == 0) { lastNameRequiredColor = requiredNotifyColor; allRequiredFieldsPresent = false; } if (zip.length() == 0) { zipRequiredColor = requiredNotifyColor; allRequiredFieldsPresent = false; Java-Server-Pages NameFormatter.js <-- TERZA PARTE--> // If the user hasn't entered the required fields, tell them that the fields are marked in a separate color if (!allRequiredFieldsPresent){ %> You have not entered all the required fields. The fields you must still enter are marked in <font color="<%=requiredNotifyColor%>"> <%=requiredNotifyColor%></font>. <% } else { // Display the name and address as it has been entered String nameString = firstName+" "+lastName+ "<BR>"+ address+"<BR>"+city+", "+ state+" "+zip; out.println("The current name is:<P>"); if (formatOption.equals("bold")){ out.println("<B>"+nameString+"</B>"); } else if (formatOption.equals("italic")){ out.println("<I>"+nameString+"</I>"); } else{ out.println(nameString); } out.println("<P>"); } } %> NameFormatter.js 129 Jsp singola 130 Java-Server-Pages <!--QUARTA PARTE--> <%-- Always allow the user to update the data and submit --%> <FORM action="NameFormatter.jsp" method="POST"> <TABLE> <TR><TD>First Name:<TD><INPUT type="text" name="firstname" value="<%=firstName%>"> <TD><FONT color="<%=firstNameRequiredColor%>">required</FONT> <TR><TD>Last Name:<TD><INPUT type="text" name="lastname" value="<%=lastName%>"> <TD><FONT color="<%=lastNameRequiredColor%>">required</FONT> <TR><TD>Address:<TD><INPUT type="text" name="address" value="<%=address%>"> <TR><TD>City:<TD><INPUT type="text" name="city" value="<%=city%>"> <TR><TD>State:<TD><INPUT type="text" name="state" value="<%=state%>"> <TR><TD>Zip:<TD><INPUT type type="text" text name name="zip" zip value value="<%=zip%>"> <% zip%> > <TD><FONT color="<%=zipRequiredColor%>">required</FONT> </TABLE> <P> Format options:<BR> <SELECT name="formatoption"> <OPTION value="normal">Normal</OPTION> <OPTION value="bold">Bold</OPTION> <OPTION value="italic">Italic</OPTION> </SELECT> <P> <INPUT type="submit" value="Format!"> </FORM> NameFormatter.js </BODY> </HTML> 131 Java-Server-Pages JSP singola Input form 132 22 Java-Server-Pages Java-Server-Pages JSP singola JSP singola 133 134 Java-Server-Pages JSP singola Salvataggio di informazioni tra pagine 135 136 Java-Server-Pages Java-Server-Pages Utilizzo dell’oggetto Session Utilizzo dell’oggetto Session Set.jsp Una tecnica per poter scambiare informazioni fra pagine è quella di utilizzare l’oggetto gg implicito p session. session Una delle caratteristiche principali dell’oggetto session è che non fa uso di variabili nascoste (parametri) Metodo POST Print.java imposta gli attributi per ll’oggetto oggetto session Oggetto session legge gli attributi per ll’oggetto oggetto session Login.html public void setAttribute(String name,Object value) throws IllegalStateException public Object getAttribute(String name) throws IllegalStateException public void removeAttribute(String name,Object value) throws IllegalStateException 137 138 23 Java-Server-Pages Java-Server-Pages Utilizzo dell’oggetto Session Esempio <HTML> <BODY bgcolor="#ffffff"> <H1>Login</H1> Please log in <FORM action=“set.jsp" method="POST"> <TABLE> <TR><TD>User Name:<TD><INPUT type="text" name="username"> <TR><TD>Password:<TD><INPUT type="password" name="password"> </TABLE> <P> <INPUT type="submit" value="Login!"> </FORM> </BODY> </HTML> login.html 139 <%@ page language="java" import="java.util.*,usingjsp.*" %> <HTML> <BODY bgcolor="#ffffff"> <% String userName = request.getParameter("username"); String password = request.getParameter("password"); // memorizza la username dell’ utente nell’oggetto session session.setAttribute("username", userName);/ %> Welcome, <%=userName%>! <FORM action=“print.jsp" method="POST"> <P> Scegli il tuo colore preferito: <SELECT name="color"> <OPTION value="blue" SELECTED>Blue</OPTION> <OPTION value="red">Red</OPTION> <OPTION value="green">Green</OPTION> </SELECT> <P> <INPUT type="submit" value="Choose color!"> </FORM> </BODY> </HTML> 140 Java-Server-Pages Utilizzo dell’oggetto Session <%@ page language="java" import="java.util.*,usingjsp.*" %> <HTML> <BODY bgcolor="#ffffff"> <% // preleva la username dall’ oggetto session String userName = (String) session.getAttribute("username"); String color = request.getParameter("color"); %> //scrive la risposta al browser <% out println(“Il out.println( Il colore preferito di "+userName+ +userName+ %> </body> </html> JSP e JDBC "‘è è "+color+" +color+ ."); ); 141 142 JSP e JDBC Esempio JSP-JDBC Jsp permette di sfruttare tutte le istruzioni JDBC già viste IMPORTANTE: Per usare il bridge JDBC-ODBC, le sorgenti dati vanno definite come ‘DNS di sistema’ e non ‘DNS utente’ Facciamo un semplice esempio che sfrutta tutte le caratteristiche viste fino ad ora Vogliamo realizzare una sezione di un sito protetta Esiste un db di utenti utenti si loggano con UID e PWD Se UID e PWD inserite fanno match con valori nel db, allora si può accedere ad una sezione del sito, altrimenti si va su una pagina di errore Gli 143 144 24 Il DB La pagina HTML di login Una sola tabella, chiamata ‘Users’ UID: String, Primary Key String PWD: La fonte dati ODBC si chiama ‘Utenti’ 145 La pagina JSP di controllo <%@ page contentType="text/html" language="java" import="java.sql.*"%> <html> <head><title>Pagina di Check</title></head> <body> <p>Questa pagina non viene visualizzata</p> <% String user = request.getParameter("UID"); String pwd = request.getParameter("PWD"); try { Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); Connection con = DriverManager.getConnection("jdbc:odbc:Utenti"); Statement st=con.createStatement(); ResultSet rs=st.executeQuery("Select * from users where UID='"+user+"' AND PWD='"+pwd+"'"); if (rs.next()) response.sendRedirect("ok.jsp"); else response.sendRedirect("error.htm"); } catch(Exception ex){out.println("Errore in loading Connection"+ex);} %> </body> </html> <html> <head> <title>Prova JSP-JDBC</title> </head> <body> <p align="center">Benvenuto nella pagina di Login.</p> <form name="form1" name= form1 method= method="post" post action= action="check check.jsp jsp"> > <p>Nome Utente: <input name="UID" type="text" id="UID"></p> <p>Password:<input name="PWD" type="password" id="PWD"></p> <p> <input type="reset" name="Reset" value="Reset"> <input type="submit" name="Submit2" value="Submit"> </p> </form> </body> </html> 146 La pagina di errore <html> <head> <title> Errore </title> </head> <body> <p>Spiacente, Nome Utente o Password Errate.</p> <p><a href="login.htm">Torna al Login</a></p> </body> </html> 147 148 Miglioramento con le variabili session La pagina protetta (?) … if (rs.next()) <html> <head> <title>Untitled Document</title> </head> <body> Complimenti, ti sei loggato correttamente </body> </html> { session setAttribute("Log" session.setAttribute( Log ,"true"); true ); response.sendRedirect("ok.jsp"); } else response.sendRedirect("error.htm"); } … 149 150 25 Miglioramento con le variabili session <%@ page contentType="text/html; charset=iso-8859-1" language="java" import="java.sql.*" errorPage="error.htm" %> <html> <head><title>Untitled Document</title></head> body <body> <% String Log=(String)session.getAttribute("Log"); if (!Log.equals("true")) response.sendRedirect("error.htm"); %> Complimenti, ti sei loggato correttamente </body> </html> 151 26