Laboratorio di reti II: Java Server Pages Stefano Brocchi [email protected] 6 aprile, 2009 Stefano Brocchi Laboratorio di reti II: Java Server Pages 6 aprile, 2009 1 / 34 Java Server Pages JSP - Java Server Pages Le Java Server Pages (JSP) sono un’astrazione di alto livello per rappresentare delle servlet Una JSP è rappresentata da codice HTML con incapsulato al suo interno delle direttive JSP rappresentanti codice Java Stefano Brocchi Laboratorio di reti II: Java Server Pages 6 aprile, 2009 2 / 34 Java Server Pages JSP - Java Server Pages Alla prima richiesta di una pagina JSP il server effettuerà i seguenti passi Il codice JSP viene compilato per ottenere il codice Java rappresentante una servlet Il codice della servlet viene a sua volta compilato per ottenere un file class rappresentante una servlet La richiesta HTTP viene inviata alla classe che si occupa di generare la risposta Dopo la prima richiesta la classe viene tenuta in cache dal server per permettere una rapida risposta alle richieste successive Stefano Brocchi Laboratorio di reti II: Java Server Pages 6 aprile, 2009 3 / 34 Java Server Pages Perchè usare JSP ? Il principale vantaggio delle JSP è quello di separare il codice HTML dal codice Java, separando cosı̀ la vista dalla logica del sito Per questo obiettivo è opportuno inserire meno codice Java possibile in una JSP delegando eventualmente operazioni complesse a classi esterne alla pagina In questo modo una volta creata una pagina JSP questa può essere mantenuta o modificata da chiunque conosca anche solo l’HTML Stefano Brocchi Laboratorio di reti II: Java Server Pages 6 aprile, 2009 4 / 34 Java Server Pages Oggetti predefiniti In una pagina JSP vengono resi disponibili automaticamente diversi oggetti, tra cui i seguenti out di tipo JSPWriter, lo stream che scrive sulla risposta HTTP request di tipo HttpServletRequest, rappresentante la richiesta HTTP response di tipo HttpServletResponse, rappresentante la risposta HTTP session di tipo HttpSession, contenente la sessione corrente application di tipo ServletContext, rappresentante il contesto della servlet pageContext di tipo PageContext, rappresentante il contesto della pagina JSP Stefano Brocchi Laboratorio di reti II: Java Server Pages 6 aprile, 2009 5 / 34 Java Server Pages Scriptlet Hello World in JSP Il codice Java può essere inserito direttamente nelle JSP tramite il tag <% ... %>. In questo caso si parla di scriptlet Vediamo una semplice pagina JSP di esempio: <html> <head> <title>Hello world in JSP</title> </head> <body> <% out.println("<h1>Hello World !</h1>"); %> </body> </html> Stefano Brocchi Laboratorio di reti II: Java Server Pages 6 aprile, 2009 6 / 34 Java Server Pages Scriptlet Scriptlet frammentate E’ possibile inserire codice Java anche in frammenti di per sè incompleti: <html> <head> <title>Hello world in JSP</title> </head> <body> <% String lang = request.getHeader("Accept-Language"); if (lang != null && lang.startsWith("it")) { %> <h1> Ciao mondo ! </h1> <% } else { %> <h1> Hello World ! </h1> <% } %> </body> </html> Stefano Brocchi Laboratorio di reti II: Java Server Pages 6 aprile, 2009 7 / 34 Java Server Pages Scriptlet Esempio di stampa dei parametri Vediamo inoltre un esempio di pagina HTML che stampa in output i parametri in ingresso: <html><head><title>...</title></head><body> <%@ page import=’java.util.*’ %> <h2> Parametri in ingresso: </h2><ul> <% Enumeration e = request.getParameterNames(); while (e.hasMoreElements()) { String p = (String)e.nextElement(); out.println("<li>" + p + " = " + request.getParameter(p)); } %> </ul></body></html> Stefano Brocchi Laboratorio di reti II: Java Server Pages 6 aprile, 2009 8 / 34 Java Server Pages Espressioni JSP Espressioni JSP Tramite il tag <%= ... %> è possibile specificare delle espressioni che verranno valutate ed il loro risultato, convertito se necessario a stringa, scritto nell’HTML. Degli esempi: Valore del rapporto aureo: <%= (1 + Math.sqrt(5)) / 2 %> <br> Data di oggi: <%= new Date() %> <br> Stefano Brocchi Laboratorio di reti II: Java Server Pages 6 aprile, 2009 9 / 34 Java Server Pages Dichiarazioni JSP Dichiarazioni JSP Tramite il tag <%! ... %> è possibile specificare delle dichiarazioni Java relative a campi o metodi della servlet Un esempio che conteggia il numero totale di visite ad una pagina <%! private int numeroAccessi = 0; %> <% numeroAccessi ++; %> Accessi globali a questa pagina: <%= numeroAccessi %> Notare che la variabile numeroAccessi viene inizializzata a zero solo al momento della creazione della servlet, cioè alla prima richiesta della pagina, mentre il suo incremento avviene ad ogni accesso Stefano Brocchi Laboratorio di reti II: Java Server Pages 6 aprile, 2009 10 / 34 Java Server Pages Direttive JSP Direttiva import Con il tag <%@ ... %> si dichiarano le direttive JSP Una possibile direttiva è la direttiva page che permette di specificare caratteristiche relative alla servlet che verrà generata Tramite l’attributo import questa permette di specificare i pacchetti Java da importare nella servlet La sintassi da utilizzare è <%@ page import="..." %> Es, <%@ page import="java.util.*, java.sql.*" %> I pacchetti javax.servlet, javax.servlet.jsp e javax.servlet.http sono inclusi implicitamente in ogni JSP Stefano Brocchi Laboratorio di reti II: Java Server Pages 6 aprile, 2009 11 / 34 Java Server Pages Direttive JSP Da JSP a servlet Riassumendo, le direttive di inclusione andranno nell’intestazione della servlet, le dichiarazioni nel corpo della classe e le scriptlet all’interno dei metodi di servizio (doGet, doPost...) Servlet JSP <%@ page import=’java.util.*’%> import java.util.*; ... public class myServlet extends HttpServlet { <%! private int numeroAccessi = 0;%> private int numeroAccessi = 0; ... public void doGet(...) { ... out.println("<html>"); ... numeroAccessi ++; out.println("Data corrente: "+ new Date()); } <html> ... <% numeroAccessi ++; %> Data corrente: <%= new Date() %> ... } Stefano Brocchi Laboratorio di reti II: Java Server Pages 6 aprile, 2009 12 / 34 Java Server Pages Direttive JSP Direttiva page Altri attributi che si possono definire in direttive di tipo <%@ page ... %> sono: extends che permette di specificare che la servlet generata estende una determinata classe isThreadSafe che specifica se più richieste possono essere inviate alla servlet contemporaneamente senza problemi. Per default impostato a true, se uguale a false le richieste successive alla prima vengono messe in attesa errorPage che indica una pagina che viene richiamata nel caso in cui si verifica un’eccezione nella JSP isErrorPage che specifica, se uguale a true, che la pagina in questione viene utilizzata per la gestione degli errori Stefano Brocchi Laboratorio di reti II: Java Server Pages 6 aprile, 2009 13 / 34 Java Server Pages Direttive JSP Gestione degli errori Per gestire errori in JSP si utilizzano delle pagine apposite specificate tramite le direttive JSP Quando in una pagina si verifica un’eccezione e questa ha specificato una errorPage, l’esecuzione passa a questa seconda pagina Oltre ai normali oggetti a disposizione nelle JSP, nelle pagine per gli errori sarà disponibile l’oggetto exception di tipo Throwable rappresentante l’eccezione che ha causato il problema Stefano Brocchi Laboratorio di reti II: Java Server Pages 6 aprile, 2009 14 / 34 Java Server Pages Direttive JSP Gestione degli errori Vediamo un esempio di una pagina che genera un errore e di un altra che lo gestisce: <%@ page errorPage=’err.jsp’ %> <% throw new RuntimeException("Eccezione di prova"); %> Nella pagina err.jsp: <%@ page isErrorPage=’true’ %> <h1> Riscontrata un’eccezione ! </h1> <%= exception %> L’output dell’ultima riga di err.jsp sarà uguale al risultato di exception.toString(), in questo caso a java.lang.RuntimeException: Stefano Brocchi Eccezione di prova Laboratorio di reti II: Java Server Pages 6 aprile, 2009 15 / 34 Java Server Pages Direttive JSP Direttiva include Un’altra direttiva JSP è la direttiva include, definita con la seguente sintassi <%@ include file="filename" %> La direttiva include nella pagina JSP il contenuto del file specificato come se questo si trovasse al posto della direttiva E’ possibile specificare l’inclusione di file JSP Spesso si includono inoltre dei file con del codice JSP che non rappresentano di per sè una pagina JSP completa ma solo un frammento di codice da eseguire nel contesto della pagina originale Stefano Brocchi Laboratorio di reti II: Java Server Pages 6 aprile, 2009 16 / 34 Java Server Pages Uso di bean Uso di bean Per permettere l’astrazione della logica dalla vista, si fa uso nelle JSP di classi Java con un’interfaccia molto semplice dette bean Grazie alla loro semplicità, l’accesso ai loro metodi si può fare in modo del tutto automatico specificando gli opportuni parametri senza scrivere altro codice Grazie alle loro caratteristiche i bean vengono usati in molte librerie Java, come per esempio nelle swing Stefano Brocchi Laboratorio di reti II: Java Server Pages 6 aprile, 2009 17 / 34 Java Server Pages Uso di bean Bean in Java Un bean è una classe Java con un numero di campi privati detti proprietà Per ogni proprietà con un determinato nome XXX possono esistere i due metodi getXXX() che ritorna il valore della proprietà setXXX() che imposta la proprietà ad un determinato valore Spesso i due metodi non fanno altro che quanto richiesto nella loro definizione; è possibile specificare comunque operazione aggiuntive Si può controllare, per esempio, che il valore della proprietà resti sempre in un determinato intervallo Nel caso in cui la proprietà derivi da un input dell’utente, i metodi set possono essere utilizzati per controllarne la validità Stefano Brocchi Laboratorio di reti II: Java Server Pages 6 aprile, 2009 18 / 34 Java Server Pages Uso di bean Uso di Java bean Grazie alla reflection di Java, è possibile automatizzare la chiamata ad un metodo di un bean Per utilizzare un bean si può utilizzare la sintassi <jsp:useBean id="Id" scope="scope" class="classname "> </jsp:useBean> Con il seguente codice si inizializza un bean istanza della classe classname in un oggetto di nome Id Il campo scope serve a definire l’accesso e la durata di vita del bean. Può assumere i valori page, request, session o application Stefano Brocchi Laboratorio di reti II: Java Server Pages 6 aprile, 2009 19 / 34 Java Server Pages Uso di bean Uso di Java bean Una volta dichiarato l’utilizzo di un bean, si possono manipolare i suoi valori con i tag <jsp:getProperty> e <jsp:setProperty> definiti dalla seguente sintassi: <jsp:getProperty name="beanId" property="proprietà"/> <jsp:setProperty name="beanId" property="proprietà" value="valore"/> L’attributo name specifica l’identificativo del bean da usare, property la proprietà da modificare e value il valore da impostare Il tag <jsp:getProperty> restituisce nella pagina JSP il valore della proprietà richiesta I tag <jsp:setProperty> e <jsp:getProperty> devono essere privi di contenuto Stefano Brocchi Laboratorio di reti II: Java Server Pages 6 aprile, 2009 20 / 34 Java Server Pages Uso di bean Gestione dei parametri tramite bean Se nel tag <jsp:setProperty> l’attributo value non viene specificato, di default viene utilizzato il parametro della richiesta HTTP con lo stesso nome Questo consente di elaborare molto semplicemente dati in GET o in POST Se si vuole impostare un campo di un bean al valore di un parametro con un altro nome, specificare questo nome nell’attributo param Es. <jsp:setProperty name="beanId" property="beanProperty" param="getParameter"> Sempre in <jsp:setProperty>, se l’attributo property è impostato a ”*”, verranno impostate tutte le proprietà del bean con nome uguale ad un parametro in ingresso Stefano Brocchi Laboratorio di reti II: Java Server Pages 6 aprile, 2009 21 / 34 Java Server Pages Uso di bean Esempio d’uso dei bean: form HTML Vediamo un esempio di gestione di una form tramite bean File submit.html per l’immissione di dati: <html> <head> <title> Pagina immissione dati </title> </head> <body> <form action=’compute.jsp’> <p><input type=’text’ name=’nome’> Nome </p> <p><input type=’text’ name=’cognome’> Cognome </p> <p><input type=’submit’></p> </form> </body> </html> Stefano Brocchi Laboratorio di reti II: Java Server Pages 6 aprile, 2009 22 / 34 Java Server Pages Uso di bean Esempio d’uso dei bean: bean Java Bean mybean.java: package beans; public class mybean { private String nome = ""; private String cognome = ""; public void setNome(String n) { nome = n; } public void setCognome(String c) { cognome = c; } public String getNome() { return nome; } public String getCognome() { return cognome; } } Stefano Brocchi Laboratorio di reti II: Java Server Pages 6 aprile, 2009 23 / 34 Java Server Pages Uso di bean Esempio d’uso dei bean: pagina JSP File compute.jsp per l’elaborazione dei dati: <jsp:useBean class="beans.mybean" id="beanId"> <jsp:setProperty name="beanId" property="*"/> </jsp:useBean> <html> <head> <title>Pagina elaborazione dati</title> </head> <body> Nome inserito: <jsp:getProperty name="beanId" property="nome"/> <br> Cognome inserito: <jsp:getProperty name="beanId" property="cognome"/> <br> </body> </html> Stefano Brocchi Laboratorio di reti II: Java Server Pages 6 aprile, 2009 24 / 34 Java Server Pages Uso di bean Vantaggi dei bean Come si vede nell’esempio, tramite la gestione con i bean i dati di un form vengono processati in modo molto semplice E’ possibile inoltre implementare nel bean una logica complessa per effettuare controlli sui campi inseriti dall’utente Si può per esempio controllare che un indirizzo email inserito rispetti la sintassi [email protected], o controllare che uno username di un nuovo utente non sia già in uso In questo caso si mantiene l’isolamento della logica del programma (nel codice Java) dalla pagina web stessa (pagina JSP) Stefano Brocchi Laboratorio di reti II: Java Server Pages 6 aprile, 2009 25 / 34 Java Server Pages Uso di bean Visibilità dei bean Per permettere la visibilità di un bean, la classe che lo realizza deve essere nel classpath relativo all’applicazione web In Tomcat, inserire le classi nella cartella WEB-INF/classes Sempre in Tomcat, inserire sempre i bean in un pacchetto (nell’esempio: beans) altrimenti il server potrebbe non essere in grado di trovare la classe Stefano Brocchi Laboratorio di reti II: Java Server Pages 6 aprile, 2009 26 / 34 Java Server Pages JSP ed XML JSP ed XML I tag JSP non rientrano nella normale sintassi HTML, nè nel linguaggio XML A volte considerare pagine JSP come una famiglia di documenti XML può essere comodo, in quanto cosı̀ si potrebbero elaborare pagine JSP con strumenti relativi all’XML Per questo per ogni tag JSP è stato elaborato un tag equivalente che rispetta la sintassi XML: Dichiarazioni Direttive include Direttive page Espressioni Scriptlet Stefano Brocchi <%! ... %> <%@ include ... %> <%@ page ... %> <%= ... %> <% ... %> <jsp:declaration> ... </jsp:declaration> <jsp:directive.include ... /> <jsp:directive.page ... /> <jsp:expression> ... </jsp:expression> <jsp:scriptlet> ... </jsp:scriptlet> Laboratorio di reti II: Java Server Pages 6 aprile, 2009 27 / 34 Java Server Pages Cenni sulle taglib Le taglib Nelle JSP, è possibile definire dei nuovi tag da inserire nell’HTML il cui comportamento è definito da delle classi Java Alcuni brevissimi cenni sul loro funzionamento: Una taglib viene definita nelle JSP tramite la direttiva <%@ taglib uri="uri" prefix="prefix"> Dove viene specificato un file tld, che definisce la taglib e segnala le classi in essa contenute, ed il prefisso del tag associato A questo punto quando nella JSP vengono incontrati i tag definiti, verranno richiamati dei metodi delle classi associate che produrranno l’output relativo a questo nuovo tag Le taglib non sono che un ulteriore meccanismo per astrarre operazioni Java tramite codice HTML Stefano Brocchi Laboratorio di reti II: Java Server Pages 6 aprile, 2009 28 / 34 Java Server Pages Cenni sulle taglib Esempio di taglib Per avere un’idea di come è strutturata una pagina con taglib, un breve esempio di pagina JSP che fa uso della taglib definita in taglib.tld, dove è definita una classe di tag mytagclass <%@ taglib uri="/taglib.tld" prefix="mytag" %> <html> <head><title> Esempio di taglib </title></head> <body> <mytag:mytagclass /> </body> </html> In questo esempio quando il tag introdotto viene incontrato vengono richiamati gli opportuni metodi dalla classe associata al nome mytagclass nel file taglib.tld Stefano Brocchi Laboratorio di reti II: Java Server Pages 6 aprile, 2009 29 / 34 Java Server Pages Cenni sulle taglib Esempio di taglib (2) Un altro esempio di taglib: supponiamo di stampare il titolo ed il contenuto di un thread in un forum con il seguente codice <% out.println(threadGestor.getThreadTitle(1)); %> <% out.println(threadGestor.getThreadBody(1)); %> Notare che per non mischiare codice Java con la pagina JSP, presupponiamo che i metodi siano implementati in un oggetto di nome threadGestor definito in una classe diversa dalla JSP L’isolamento della logica è già abbastanza buono, in quanto visualizziamo un thread con una quantità minima di codice Java; tuttavia tramite taglib questo codice si può completamente occultare Stefano Brocchi Laboratorio di reti II: Java Server Pages 6 aprile, 2009 30 / 34 Java Server Pages Cenni sulle taglib Esempio di taglib (2) Tramite taglib il precedente codice si potrebbe riscrivere come: <%@ taglib uri="/taglib.tld" prefix="thread" %> <thread:title threadId=1 /> <thread:body threadId=1 /> In questo caso il file taglib.tld e le classi da esso associate a thread:title e thread:body si occuperanno di delegare le operazioni necessarie ai metodi opportuni Stefano Brocchi Laboratorio di reti II: Java Server Pages 6 aprile, 2009 31 / 34 Java Server Pages Esercizio Esercizio Realizzare tramite JSP la funzionalità di registrazione di nuovi utenti Per ogni utente, definire una serie di dati che questo dovrà inserire per registrarsi al forum Es. username, password, nome, cognome, email, telefono... Imporre vari vincoli sui parametri cosı̀ inseriti Si può imporre per esempio di usare nomi utenti contenenti solo caratteri alfanumerici, password con una lunghezza minima e massima, controllare che gli indirizzi email siano plausibili (es. contenere una chiocciola ed almeno un punto) Stefano Brocchi Laboratorio di reti II: Java Server Pages 6 aprile, 2009 32 / 34 Java Server Pages Esercizio Esercizio Quando l’utente ha inserito i dati, visualizzarne una schermata riassuntiva Stampare un messaggio di errore in caso di dati non validi, e chiedere di reinserire i dati Per controllare che le varie stringhe siano in un determinato formato, si può controllare la loro corrispondenza con un’espressione regolare tramite il metodo matches di String Due esempi: s.matches("[a-zA-Z0-9]*") restituisce true se s è formata solo da alfanumerici; s.matches(".*@.*\\..*") controlla che sia presente una chiocciola e un punto dopo di essa Se l’utente ha inserito correttamente i dati, creare l’account aggiornando il database Stefano Brocchi Laboratorio di reti II: Java Server Pages 6 aprile, 2009 33 / 34 Java Server Pages Esercizio Esercizio Isolare più possibile la logica del codice Java dalla pagina JSP Trattare i dati in ingresso e controllarne la validità tramite un bean Delegare l’operazione di inserimento nel database all’apposita classe Stefano Brocchi Laboratorio di reti II: Java Server Pages 6 aprile, 2009 34 / 34