Laboratorio di Servizi Web - servlet - Ardissono
1
Java Servlet API
• package javax.servlet: include classi e interfacce di gestione di servlet indipendenti da protocollo di comunicazione
• package javax.servlet.http: include classi e interfacce specifiche per uso di servlet con protocollo HTTP
• alcune classi e interfacce di javax.servlet.http estendono le rispettive di javax.servlet
Laboratorio di Servizi Web - servlet - Ardissono
2
Porzione di gerarchia delle classi - Servletinterface javax.servlet.Servlet
•init(ServletConfig c)•service(ServletRequest req, ServleResponse res)•destroy(), … altri metodi ...
abstract class javax.servlet.GenericServlet implements Servlet, ServletConfig, Serializableoffre implementazione di interfaccia Servlet indipendenteda protocollo di comunicazione (HTTP, …)
abstract class javax.servlet.http.HttpServlet extends GenericServlet implements Serializableoffre implementazione di interfaccia Servlet specifica per HTTP
interface javax.servlet.ServletConfig
mantiene dati di configurazione di servlet
Laboratorio di Servizi Web - servlet - Ardissono
3
javax.Servlet - Interface ServletConfig
specifica metodi per accedere a parametri di configurazione di Servlet (es. database driver, costanti
globali della Servlet, …)
– public String getInitParameter(String name)• restituisce valore di parametro di inizializzazione “name”,
se esiste. Null altrimenti
– public Enumeration getInitParameterNames()• restituisce enumerazione di nomi dei parametri di
inizializzazione della Servlet
– public String getServletName()– ...
Laboratorio di Servizi Web - servlet - Ardissono
4
javax.Servlet - Interface Servlet - I
specifica metodi di gestione della Servlet – public void init(ServletConfig c) throws ServletException
• invocato da Web Container dopo aver istanziato Servlet
• inizializza variabili di Servlet (prima di accettare HTTP requests). Es: leggere dati di configurazione, registrare database driver, …
– public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException
• invocato da Web Container ad ogni HTTP request (oggetto req contiene dati di richiesta, res contiene risposta)
– public void destroy()• invocato da Web Container prima di rimuovere istanza di Servlet (es:
prima di shut down di web server, o se serve spazio di memoria, …)
Laboratorio di Servizi Web - servlet - Ardissono
5
javax.Servlet - Interface Servlet - II
Offre anche metodi per accedere a informazioni generiche su Servlet e a oggetto ServletConfig
(questi metodi sono usati nel codice delle classi da noi implementate che estendono le Servlet)
– ServletConfig getServletConfig()• restituisce oggetto ServletConfig di una Servlet
– String getServletInfo()• restituisce informazioni generali su Servlet (autore, data di
creazione, ...)
Laboratorio di Servizi Web - servlet - Ardissono
6
javax.Servlet.http - abstract class HttpServlet - I
– public void service(ServletRequest req, ServleResponse res)
• implementa metodo service di GenericServlet. Fa cast di ServletRequest/ServletResponse ad HttpServiceRequest/HttpServiceResponse e invoca metodo service protected.
• Non ridefinire!!
– protected void service(HttpServletRequest req, HttpServleResponse res)
• invoca req.getMethod per sapere se è GET, POST, HEAD, … e delega gestione a metodo doXXX specifico….
• Non ridefinire!!!
Laboratorio di Servizi Web - servlet - Ardissono
7
javax.Servlet.http - abstract class HttpServlet - II
– protected void doGet(HttpServletRequest req, HttpServleResponse res)
• gestisce HTTP request di tipo GET. Ridefinibile
– protected void doPost(HttpServletRequest req, HttpServleResponse res)
• gestisce HTTP request di tipo POST. Ridefinibile
– protected void doHead(HttpServletRequest req, HttpServleResponse res)
• gestisce HTTP request di tipo HEAD. Ridefinibile
– ...
Laboratorio di Servizi Web - servlet - Ardissono
8
Invocazione di Servlet
Web container
Webserver
Webbrowser
POSTHTTP
HttpServlet
Invoca metodopubblico service di Servlet
service(req, res)
service (protected)fa cast di parametrie invoca doXXX(req, res)
doXXX gestisce richiesta
Ridefinendo metodi doXXX integriamo logica applicativa
in funzionalità offerte da web server
NB: metodoservice eseguito
in thread diprocesso
principale gestione
parallela di richieste,
ma leggera
Laboratorio di Servizi Web - servlet - Ardissono
9
Porzione di gerarchia delle classi - Request
Interface javax.servlet.ServletRequest
offre • metodi per accedere a connessione client • input stream associata a connessionesupporta lettura di dati da input stream
interface javax.servlet.http.HttpServletRequest offre implementazione di ServletRequest specifica per HTTP
InputStreamServiceInputStream
Laboratorio di Servizi Web - servlet - Ardissono
10
Porzione di gerarchia delle classi - Response
Interface javax.servlet.ServletResponse
offre • metodi per accedere a connessione client • output stream associata a connessionesupporta scrittura dati per client
interface javax.servlet.http.HttpServletResponse
offre implementazione di ServletResponse specifica per HTTP
OutputStreamServiceOutputStream
Laboratorio di Servizi Web - servlet - Ardissono
11
Metodi per comunicazione con client - I
• javax.http.HttpServletRequest– String getParameter(String parameterName)
• parsifica contenuto di request HTTP ed estrae valore di parametro “parName”
• Es:
– String tipoInfo = req.getParameter("tipoInfo");– String loginName = req.getParameter("login");
FORM HTML...<input type="text" name="login" align="left" size="25"><input type="password" name="passwd" align="left” size=“25”>
Laboratorio di Servizi Web - servlet - Ardissono
12
Metodi per comunicazione con client - II
• HttpServletResponse– void setContentType(String mimeType)
• specifica formato MIME di output
– PrintWriter getWriter()
• restituisce oggetto PrintWriter costruito da Web Container a partire da OutputStream associato a connessione client
Laboratorio di Servizi Web - servlet - Ardissono
13
Struttura standard di applicazione web
• Directory pubblica– contiene pagine HTML e JSP
• WEB-INF/web.xml– file che descrive parametri di configurazione della
Servlet e varie proprietà
• WEB-INF/classes/– contiene classi compilate delle Servlet e altre classi di
utilità, eventualmente organizzate in package
• WEB-INF/lib/– contiene eventuali JAR file di librerie usate da
applicazione
swebi/
Laboratorio di Servizi Web - servlet - Ardissono
14
Esempio di prova (Hello)
/usr/home/studenti/labgroup/labsweb/swebi/– file HTML: pagina.html
– WEB-INF
• classes
– application
» servlets: application.servlets.Hello.java
» other: altre classi di utilità (application.other.InterrogaDB.java, …)
• web.xml: non specificato
– src (albero dei sorgenti)
Applicazione di prova cheavete usato è in package
“application”. Servlets separate da altre
classi per comodità ...
NB: se non si descrive Servletin deployment descriptor si
rinuncia a usare configurationparameters etc.
Laboratorio di Servizi Web - servlet - Ardissono
15
Deployment descriptor - web.xml
• Un descrittore per ogni applicazione web• file web.xml (associato a contesto di applicazione
- swebi)• usato da Web Container per
– inizializzare applicazione web
– identificare applicazione invocata da HTTP request
• specifica– parametri di inizializzazione di Servlet e applicazione
(es: URL di database usato da applicazione, …)
– definizione di servlets e JSPs di applicazione
– ….
Laboratorio di Servizi Web - servlet - Ardissono
16
Altro esempio
Estendiamo applicazione swebi, che inizialmente faceva solo il saluto, aggiungendo servizio: richiesta
informazioni personali
Implementiamo una nuova Servlet (Informazioni.java), in aggiunta ad Hello.java, che invocheremo da una
pagina HTML
Laboratorio di Servizi Web - servlet - Ardissono
17
Nota bene
• NB: anche se le due Servlet sono parte della stessa applicazione, non comunicano tra loro
• In generale, le Servlet di un’applicazione dovrebbero cooperare e bisognerebbe definire applicazioni diverse, se si offrono servizi indipendenti
• Tuttavia, ciascun gruppo di laboratorio corrisponde, per questioni di configurazione del web server, ad una diversa applicazione usiamo applicazione per sviluppare tutte le
Servlet che vogliamo (indipendentemente dal fatto che c’entrino l’una con l’altra …)
Laboratorio di Servizi Web - servlet - Ardissono
18
Struttura standard di applicazione web
webapps
sweb01 sweb40
WEB-INF
XMLSchema classes
first application
srccodice
sorgenteclassi
compilateSchemi XMLe classi
generate
coffeeOrder.xsd coffee1
CoffeeOrderType.java, …
coffee1
Comeattesa da
Web container
tomcat
Laboratorio di Servizi Web - servlet - Ardissono
19
Gestione informazioni personali
• /usr/home/studenti/labgroup/labsweb/swebi/– file HTML: richiesta.html
– WEB-INF
• classes
– application
» servlets: application.servlets.Informazioni.java
» other: nessuna classe di utilità
• web.xml
– src (albero dei sorgenti da compilare)
Laboratorio di Servizi Web - servlet - Ardissono
20
swebi - web.xml - preambolo
<?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>
<display-name>Web Application sweb40 </display-name> <description> descrizione dell'applicazione... </description>
….
DTD di web.xmlDescrizione applicazione web
Laboratorio di Servizi Web - servlet - Ardissono
21
swebi - web.xml - context parameters
<!-- Context parameters definiscono costanti di tipo String condivise tra più servlet e JSP dell’applicazione. Questi parametri possono essere definiti dal system administrator che installa l’applicazione.
Da una Servlet (o JSP) si accede ai valori assegnati ai parametri invocando il metodo:
String value = getServletContext().getInitParameter("name"); dove “name” corrisponde al nome dato al parametro usando <param-name> --> <context-param> <param-name>contextPar</param-name> <param-value>Questo parametro è generale
di applicazione </param-value> <description> ... </description> </context-param>
Parametri di inizializzazione usati in tutta l’applicazione web sono memorizzati
nel contesto di applicazione
Laboratorio di Servizi Web - servlet - Ardissono
22
swebi - web.xml - descrizione servlet
<servlet>
<servlet-name>info</servlet-name>
<description> Servlet che fornisce informazioni personali </description>
<servlet-class>application.servlets.Informazioni</servlet-class>
<init-param> <param-name>saluto</param-name> <param-value>CIAO!! </param-value> </init-param>
Parametri di inizializzazione di
Servlet info
Descrizione di Servletgestita da web container
Alias per invocazione Servlet
Nome della classe Servlet
Laboratorio di Servizi Web - servlet - Ardissono
23
swebi - web-xml - ultima parte
<init-param> <param-name>DB-URL</param-name> <param-value> jdbc:idb:/usr/home/studenti/labgroup/labsweb/sweb40/localDB/properties.prp
</param-value> </init-param>
<!-- Load this servlet at server startup time --> <load-on-startup>5</load-on-startup> </servlet>
<servlet> …… definizione di altra servlet …. </servlet> …...</web-app>
Specifico che Servlet deve essere
caricata (per quinta)appena Web Container
viene lanciatoNON FATELO!!!!
Laboratorio di Servizi Web - servlet - Ardissono
24
Pagina web: richiesta.html - I
<HEAD> <TITLE>RICHIESTA INFORMAZIONI</TITLE></HEAD> <BODY TEXT="#000000" BGCOLOR="#FFFFFF"
LINK="#CC33CC" VLINK="#970097" ALINK="#B300B3"> <h1> Richiesta di informazioni </h1><hr><br><center> <FORM ACTION="servlet/info" METHOD="POST" ><!-- <FORM ACTION="servlet/application.servlets.Informazioni"
METHOD="POST" >--> …..
NB: posso invocare laServlet con nome di classe
o con alias (alias piùrobusto e flessibile)
Laboratorio di Servizi Web - servlet - Ardissono
25
Pagina web: richiesta.html - II
<table align="center" width="100%" cellspacing="2" cellpadding="2"> <tr> <td align="right">Login:</td> <td> <input type="text" name="login" align="left" size="25"> </td> </tr> <tr> <td align="right">Password:</td> <td><input type="password" name="passwd" align="left” size="25"></td> ...
Laboratorio di Servizi Web - servlet - Ardissono
26
Pagina web: richiesta.html - III<tr> <td align="right">Tipo di informazioni:</td> <td> <select name="tipoInfo" SIZE="1"> <option value="no">Nessuna informazione</option> <option value="nomi">Nomi persone</option> <option value="cc">Conti correnti bancari</option> </select> </td> </tr></table> <CENTER> <INPUT TYPE="Submit" NAME="btnSubmit" VALUE="Submit request"></CENTER> </FORM> </BODY> </HTML>
Laboratorio di Servizi Web - servlet - Ardissono
27
Servlet Informazioni.java - I
package application.servlets;
import javax.servlet.*;import javax.servlet.http.*;import java.io.*;import java.util.*;
import java.sql.*;
public class Informazioni extends HttpServlet {String cheers;String url;Connection con;
public Informazioni() {cheers = "";
url = “”; con = null;
}
Costruttore classe(usato da Web Containerper istanziare la Servlet)
Laboratorio di Servizi Web - servlet - Ardissono
28
Servlet Informazioni.java - II public void init(ServletConfig config) throws ServletException {
super.init(config);
cheers = config.getInitParameter("saluto");
url = config.getInitParameter("DB-URL");
try {
Class.forName("org.enhydra.instantdb.jdbc.idbDriver");
} catch (ClassNotFoundException e)
{ System.err.println(e);
throw new ServletException(e);}
}
Prima di istruzioni di inizializzazionespecifiche eseguo metodo init di base!!
Chiedo a ServletConfig object i valori dei parametridi inizializzazione di Servlet
Carico Driver JDBC ecatturo eccezioni forzando
ServletException...
Laboratorio di Servizi Web - servlet - Ardissono
29
Servlet Informazioni.java - III
public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
res.setContentType("text/html");
String tipoInfo = req.getParameter("tipoInfo");String loginName = req.getParameter("login");
String contextP = getServletContext().getInitParameter(“contextPar”);
Specifico contenutoMIME di risposta
Estraggo parametrida HTTPRequest
Prendo riferimento a oggettoServletContext (per recuperare
parametri generalidi applicazione)
Chiedo a oggetto ServletContextvalore di parametro generale“contextPar” - vd web.xml
Laboratorio di Servizi Web - servlet - Ardissono
30
Servlet Informazioni.java - IV
PrintWriter out = res.getWriter();
out.println("<HTML> <HEAD> <TITLE>Informazioni”+ “</TITLE></HEAD>");
out.println("<BODY><CENTER><H1>" + cheers + " Ecco le informazioni che desideri, "+loginName+“</H1></CENTER> <BR>“);
out.println(contextP);
Chiedo a riferimento a oggettoPrintWriter (da usare per
produrre output da inviare a web server - HTTP response)Inizio costruzione risposta
(pagina HTML generata dinamicamente)
NB: In generale, i parametri di applicazione sono par diconfigurazione (qui lo uso
solo per fare una stampa…)
Laboratorio di Servizi Web - servlet - Ardissono
31
Servlet Informazioni.java - V … se tipoInfo è “no” stampo su out “no info” altrimenti, se tipoInfo è “nomi” { try { apro connessione a database; eseguo query SQL e salvo risultati in Hashtable valori; chiudo connessione; } catch (SQLException e) { System.err.println(e); throw new ServletException(e);}
if (valori==null) out.println("****** RISULTATO NULL");else {
scorro ResultSet con cursore per estrarre informazioni; stampo informazioni su oggetto PrintWriter (out);
}}else out.println("Tipo di informazione non accessibile");out.println(“</BODY></HTML>");
out.close(); }
ForzoServletException
Chiudo PrintWriter
Laboratorio di Servizi Web - servlet - Ardissono
32
Ciclo di vita di una servlet
Servletinesistente
Servletistanziata
Servletinizializzata e/o
pronta per richieste
ServiceDestroyed
Unavailable
Istanziazione a startupdel container o inseguito a HTTP request
inizializzazione
HTTP request(s)da client(s) Fine
threadservice
shut-down di web container
Garbagecollection
Inizializzfallita
Fallimentotemporaneoo permanente
Laboratorio di Servizi Web - servlet - Ardissono
33
Esecuzione metodo service
• Ad ogni HTTP request Web Container crea thread per esecuzione richiesta
richieste di client diversi gestite in parallelo nell’ambito del processo principale, con poco spreco di risorse computazionali
• MA: attenti agli accessi a risorse in mutua esclusione. Es:– variabili globali di Servlet, da non modificare in
parallelo– accessi a DB che non garantiscono modifiche in
mutual esclusione
Laboratorio di Servizi Web - servlet - Ardissono
34
Deployment di applicazione - ant
• Usiamo tool ANT, che permette di compilare applicazioni web, caricarle e scaricarle da web container
• Ant– programma di aiuto allo sviluppo di applicazioni (web e
non)
– Esegue file di build (build.xml) che specifica operazioni da fare (task) e ordine di esecuzione dei task
• Tipi di task: delete dir, make dir, copy, compile, install URL, remove URL, … in generale permette di lanciare anche programmi, come xjc di JAXB
Laboratorio di Servizi Web - servlet - Ardissono
35
Deployment di applicazione - ant
• Dato il nostro build.xml, si effettuano le seguenti operazioni– eliminazione e ricostruzione di directory di applicazione
sotto area di deployment (WEB-INF/classes), per accertarsi che classi compilate vecchie vengano rimosse e ad ogni ricompilazione applicazione sia completamente rinnovata
– compilazione classi java in directory di deployment (WEB-INF/classes)
– installazione applicazione in web container (ant install)– eliminazione di installazione da web container (ant
remove)– lista applicazioni attive in Web Container (ant list)– ….
Laboratorio di Servizi Web - servlet - Ardissono
36
Deployment di applicazione – build - I
• ANT esegue file di build passato come parametro: build.xml specifica operazioni di deployment (task eseguibili)
• vd alias definito in catEnv.sh– alias ant '$JWSDP_HOME/jakarta-ant-1.5.1/bin/ant -
buildfile build.xml’
• ant install: task di installazione di applicazione (rinnova directory, compila, installa)
• ant remove: rimuove installazione di applicazione da web container
Laboratorio di Servizi Web - servlet - Ardissono
37
Deployment di applicazione – build - II
• build.xml: file di build da usare per deployment delle vostre applicazioni in ambiente unix
• Versione da voi scaricata è la base ma è estensibile• Come esempio, consideriamo versione estesa per
vedere come utilizzare anche classi generate da JAXB in deployment di applicazione
• Vediamo alcune parti del file di build esteso: definizione di properties (variabili), di task, esecuzione task, ... Le parti relative a JAXB sono in viola
Laboratorio di Servizi Web - servlet - Ardissono
38
Deployment di applicazione – build - III
clean: rimuovo file
build: compilo classimettendo compilati
sotto classes
prepare: ricreo directories
bindXMLSchema: generoclassi da schema XML (xjc)
webapps
sweb01 sweb40
WEB-INF
XMLSchema classes
first application
srccodice
sorgenteclassi
compilateSchemi XMLe classi
generate
coffeeOrder.xsd coffee1
CoffeeOrderType.java, …
coffee1
Laboratorio di Servizi Web - servlet - Ardissono
39
build.xml - I<project name="helloWorld-example" default="build" basedir="."> <target name="init"> <tstamp/> </target> <property name="jwsdp.path" value="/usr/NFS/Solaris/jwsdp-1.1" /> <property name="context.path” value="/usr/home/studenti/labgroup/labsweb/sweb40" /> <property name="WEB-INF.path" value="${context.path}/WEB-INF" /> <property name="user.path” value="/usr/home/studenti/labgroup/labsweb/sweb40" /> <property name="src.application.home" value="application" /> <property name="path" value="/sweb40"/> <property name="deployed.application.path" value=
"${WEB-INF.path}/classes/${src.application.home}"/> <property name="XSD.path" value="${user.path}/src/XMLSchema/" /> <property name="deployed.JAXBClasses.path" value= "${WEB-INF.path}/classes/coffee1"/> …...
Definizione properties usate come variabili nel resto del file
Laboratorio di Servizi Web - servlet - Ardissono
40
build.xml - II <property name="username" value=“sweb" /> <property name="password" value=“sweb" /> <property name="myPath" value=".:/${user.path}" />
<!-- Configure properties to access the Manager application --> <property name="url"
value="http://130.192.241.1:10000/manager"/> <property file="build.properties"/> <property file="${context.path}/build.properties"/>
<!-- Configure the custom Ant tasks for the Manager application --> <path id="classpath"> <fileset dir="${jwsdp.path}/common/lib"> <include name="*.jar"/> </fileset> </path>
Login e passwordper installare
applicazioni in web container
URL per connettersia tomcat durante
installazione applicaz
Carico librerie JWSDP da classpath
Laboratorio di Servizi Web - servlet - Ardissono
41
build.xml - III<taskdef name="list" classname="org.apache.catalina.ant.ListTask"/>
<taskdef name="install" classname="org.apache.catalina.ant.InstallTask"/><taskdef name="reload"
classname="org.apache.catalina.ant.ReloadTask"/><taskdef name="remove"
classname="org.apache.catalina.ant.RemoveTask"/>
<!-- per usare xjc dentro la build: JAXB --> <taskdef name="xjc" classname="com.sun.tools.xjc.XJCTask"/>
<target name="clean"><delete dir="${deployed.application.path}"/><delete dir="${deployed.JAXBClasses.path}"/>
</target>
Definizione taskdi ant di base
Task di invocazionedi codice esterno (jaxb)
Rimozione directoryapplicazione in area
di deployment
Laboratorio di Servizi Web - servlet - Ardissono
42
build.xml - IV<target name="prepare" depends="init" description="Create build directories."> <mkdir dir="${deployed.application.path}" /> <mkdir dir="${deployed.JAXBClasses.path}" /> </target>
<!-- Executable Targets --> <target name="list" description="List web applications" > <list url="${url}" username="${username}" password="${password}" /> </target>
<target name="install” description="Install web application" depends="build"> <install url="${url}" username="${username}" password="${password}" path="${path}" war="file:${context.path}"/> </target>
Creazionedirectory di
build: richiamainit task ...
ant install ...
init prepare
build install
Laboratorio di Servizi Web - servlet - Ardissono
43
build.xml - V….
<target name="remove" description="Remove web application">
<remove url="${url}" username="${username}”
password="${password}"
path="${path}"/>
</target>
ant remove ...
Laboratorio di Servizi Web - servlet - Ardissono
44
build.xml - VI <target name="build" depends="clean, prepare, bindXMLSchema" description="Compile app Java files and copy HTML and JSP pages" > <javac srcdir="${user.path}/src"
destdir="${WEB-INF.path}/classes" debug="on" classpath="${classpath}:${myPath}:"> <include name="**/*.java" />
</javac><!-- copio i file di properties etc. delle classi JAXB -->
<copy todir="${deployed.JAXBClasses.path}"> <fileset dir="${XSD.path}/coffee1"> </fileset> </copy> <copy todir="${WEB-INF.path}"> <fileset dir="${user.path}/src"> </fileset> </copy> </target>
Clean
build
Prepare
bindXMLSchema
Laboratorio di Servizi Web - servlet - Ardissono
45
build.xml - VII
<!-- per usare xjc dentro la build: JAXB -->
<target name="bindXMLSchema" description="Expand all XML schema files and place generated
classes in SOURCE package" > <xjc target="${XSD.path}"
package="coffee1"> <schema dir="${XSD.path}" includes="*.xsd" /> </xjc> </target>
</project>
Invoca xjc per generareclassi da XML schema