Java Servlet
Davide Taibi
[email protected]
2010
Sommario
Servlet
Sessioni
Cookies
2
Davide Taibi
Servlet
Moduli scritti in Java che estendono
le funzionalità dei web server.
Usati al posto di script CGI e risiedono sul server
Cosa fanno?
Consentono di generare pagine web dinamiche facili da scrivere e
veloci da visualizzare
Si può interagire con un DB remoto attraverso il protocollo HTTP con
i soliti metodi POST e GET
Vantaggio
Essendo scritti in Java possono essere inseriti nella maggior parte dei
web server (java è indipendente dalla piattaforma)
…alcuni commenti generali…
Il problema della sicurezza è superato grazie a un Securiy
Manager simile quello degli applet
Si presentano come un’applicazione java in esecuzione su una
JVM residente su un sever
di solito essa esegue delle operazioni che producono un
codice HTML inviato al client
Servlet
Supportano richieste multiple (es. conferenze online)
Aggiornano, eliminano o consultano dati contenuti in un DB
tramite protocollo TCP/IP
Applicazioni di E-Commerce
Fare dei forward ad altri server per bilanciare i carichi di
lavoro
Vantaggi delle servlet
Efficienza. Le servlet vengono istanziate e caricate una volta soltanto.
Tutte le successive chiamate da parte di nuovi client vengono gestite creando dei
nuovi thread che si prendono carico del processo di comunicazione.
Portabilità: Grazie alla tecnologia Java, le servlet "portate" da una piattaforma ad
un'altra senza particolari problemi.
Persistenza: Dopo il caricamento, una servlet rimane in memoria mantenendo
intatte determinate informazioni (come la connessione ad un data base) anche alle
successive richieste.
Gestione delle sessioni: Come è noto il protocollo HTTP è un protocollo
stateless (senza stati) e, pertanto non in grado di ricordare i dettagli delle precedenti
richieste provenienti da uno stesso client. Le servlet sono in grado di superare questa
limitazione.
Per utilizzare i servlet bisogna…
E’ la libreria opzionale (javax sta per Standard Extension) di Java
(J2EE) che permette di realizzare classi Java, caricate
dinamicamente, per espandere le funzionalità di un Web server
Installare le classi servlet del package javax
Architettuura del package
javax.servlet
Servlet interface: dichiara I metodi della
servlet (init, service, etc.)
GenericServlet implements Servlet
HttpServlet (subclass) aggiunge funzionalita’
specifiche HTTP
Ciclo di vita di una servlet
1. A server loads and initializes the servlet
New thread created for each client.
2. The servlet handles zero or more client requests
3. The server terminates the servlet
Ciclo di vita di una servlet
• Il server in risposta ad una richiesta per una servlet ne effettua il caricamento in
memoria
• void init (ServletConfig config)
•
è avviato automaticamente da server prima che la servlet possa gestire la richiesta
• void service (ServletRequest request, ServletResponse response)
•
•
•
•
gestisce tutte le richieste
rceve le richieste le elabora e invia le risposte al client
è chiamato dal server per rispondere ad una richiesta
eseguito in un nuovo thread per ogni richiesta
• void destroy( )
•
chiamato al termine dell’esecuzione della servelt per rilasciare le risorse usate
dalla servlet
Classe HttpServlet
• Generalmente le Servlet web-based
• estendono la classe HttpServlet
• usano il metodo service per distinguere tra le richieste ricevute da un
client (web browser)
• Le richieste (metodi) HTTP sono di tipo:
• get per richiedere informazioni dal server, generalmente documenti
HTML o immagini
• post per inviare dati al server generalmente informazioni relative ad
autenticazione o data inseriti in un form
• Usa i metodi
• doGet e doPost rispettivamente per rispondere alle richieste
corrispondenti
HttpServletRequest Interface
Le chiamate a doPost e doGet per una HttpServlet ricevono
un oggetto che implementa l’interfaccia HttpServletRequest.
Il Web server che esegue la servlet crea un oggetto
HttpServletRequest e lo passa al metodo service.
HttpServletResponse Interface
Il web server che esegue la servlet crea un oggetto
HttpServletResponse che passa al metodo service della
servlet che a sua volta lo passa a doGet o doPost
Sviluppare una servlet
Affinchè una servlet possa essere eseguita è necessario che il
server sia attivo
Web Server che supportano le servlet
•
•
•
•
Apache Tomcat
JBoss
Jetty
…
Esempio n.1: costruzione di una servlet
La servlet genera un documento XHTML in risposta ad una
richesta di tipo get, che consente di recuperare il contenuto
di una specifica URL
• Generalmente il contenuto è di tipo HTML o XHTML
Il documento conterrà la sola stringa
• Welcome to Servlet!
1:
2:
3:
4:
5:
import javax.servlet.*;
import javax.servlet.http.*;
import java.io;
public class WelcomeServlet extends HttpServlet {
6: // gestisce le richieste "get" dai client
7: protected void doGet(HttpServletRequest request,
8:
HttpServletResponse response)
9: throws ServletException, IOException
10: {
11:
response.setContentType("text/html");
12:
PrintWriter out=response.getWriter();
Descrizione del contenuto della servlet
Le linee 1,2,3 consentono di includere I packages
javax.servlet a javax.servelet.http che contenogno le classi
per gestire la richiesta get e il package java.io
La classe WelcomeServlet deve estendere HttpServlet
ServletException consente di gestire le eccezioni
Overloading del metodo doGet
Il metodo doGet riceve come parametri gli oggetti request e
response rispettivamente delle classi
• HttpServletRequest
• HttpServletResponse
setContentType: metodo di HttpServletRequest usato per
specificare il tipo dei dati da inviare in risposta al client
Out: oggetto della classe PrintWriter
• Ottenuto mediante il metodo getWriter dell’oggetto response
• Utilizzato per inviare la risposta al client
13: // invia la pagina xhtml al client
14: // avvia il documento xhtml
15: out.println("<?xml version = \"1.0\"?>");
16: out.println("<!DOCTYPE html PUBLIC \”//W3C//DTD " +
17:
"XHTML 1.0 Strict//EN\" \"http://www.w3.org"+
18:
"/TR/xhtml1/DTD/xhtml1-strict.dtd\">");
19:
20: out.println("<html xmlns =\"http://www.w3.org/1999/xhtml\">");
Istruzioni per la creazione del
documento XHTML
21: // intestazione del documento
22:
out.println("<head>");
23:
out.println("<title> Prima servlet</title>");
24:
out.println("</head>");
25:
26:
// corpo del documento xhtml
27:
out.println("<body>");
28:
out.println("<h1> Welcome to Servlet! </h1>");
29:
out.println("</body>");
30:
31:
// fine del documento
32:
out.println("</html>");
33:
out.close(); // chiude lo stream
34:
}
35: }
Documento XHTML
il documento contiene un form per richiamare la servlet.
form action specifica la URL che richiama la servlet
welcome1
form method indica che il browser invia una richiesta get al
server
la richiesta richiama il metodo doGet della servlet
Documento XHTML
<?xml version = 1.0?>
<!DOCTYPE html PUBLIC "-//w3c//dtd xhtml 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<!-- Prima Servlet -->
<html xmlns = "http://www.w3.org/1999/xhtml">
<head>
<title> Gestione di una richesta HTTP di tipo Get </title>
</head>
<body>
<form action = "/welcome1" method = "get">
<p><label> Click the button to invoke the servlet
<input type = "submit" value = " Get HTML Document"/>
</label></p>
</form>
</body>
</html>
Metodo doPost
Una richiesta post è usata per inviare dati da un form HTML ad
un gestore di form server side che possa elaborare i dati
import
import
import
public
javax.servlet.*;
javax.servlet.http.*;
java.io;
class WelcomeServlet extends HttpServlet {
// gestisce le richieste "post" dai client
protected void doPost(HtpServletRequest request,
HttpServletResponse
response)
throws ServletException, IOException
{
String firstName =
request.getParameter("firstname");
response.setContentType("text/html");
PrintWriter out=response.getWriter();
// invia la pagina xhtml al client
// avvia il documento xhtml
out.println("<?xml version = \"1.0\"?>");
out.println("<!DOCTYPE html PUBLIC \"-//W3C//DTD " +
"XHTML 1.0 Strict//EN\"
\"http://www.w3.org"+
"/TR/xhtml1/DTD/xhtml1strict.dtd\">");
out.println("<html xmlns =
\"http://www.w3.org/1999/xhtml\">");
// intestazione del documento
out.println("<head>");
out.println("<title> Gestione di una richesta post con
invio di dati</title>");
out.println("</head>");
// corpo del documento xhtml
out.println("<body>");
out.println("<h1> Hello!" + firstname +
",<br />");
out.println("Welcome to Servlet! </h1>");
out.println("</body>");
// fine del documento
out.println("</html>");
out.close(); // chiude lo stream
}
}
Documento XHTML
<?xml version = 1.0?>
<!doctype HTML public "-//w3c//dtd xhtml 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<!-- Terza Servlet -->
<html xmlns = "http://www.w3.org/1999/xhtml">
<head>
<title> Gestione di una richesta Post con invio di dati
</title>
</head>
<body>
<form action = "/welcome3" method = "post">
<p><label> Type your name and press the Submit
button
<br> <input type = "text" name =
"firstname"/>
<input type = "submit" value = "Submit"/>
</label></p>
</form>
</body>
</html>
Session Tracking
Servlets in Duke’s Bookstore
BookStoreServlet: Forward to main page
CatalogServlet: Show all books and allow selection
BookDetailServlet: Show details of a book and allow selection
ShowCartServlet: Show shopping cart
CashierServlet: Check out
Session Tracking
Motivation
In a Bookstore, suppose a client has selected several books.
(Do this and check the page produced by CatalogServlet.)
Problem 1:
The client requests
ShowCartServlet to show the books in his/her shopping
cart.
Question:
How does ShowCartServlet know the selected books?
How communications between servlets are facilitated?
Problem 2:
The client decides to leave the bookstore and visit some
other pages.
Question: When the client comes back and makes further
requests, how do the servlets know the books that have
been selected previously?
How come servlets can remember things?
Session Tracking
Session tracking is a mechanism that servlets use to
maintain state about a series of requests
From the same user (that is, requests originating from
the same browser)
Across some period of time
Solution to Problem 2:
Servlets use sessions as “notebook” and hence can
remember
Sessions are shared among the servlets accessed by the same
client.
Solution to Problem 1.
Servlets communicate via sessions.
Session Tracking
Session is associated with a request.
To use session,
Get session from HttpServletRequest request:
HttpSession getSession(boolean create)
HttpSession
mySession =
request.getSession(boolean
create);
Case 1: create==true
Return the associated session if exists
Otherwise, create a new session, associate it with the request, and return the session
Case 2: create==false
Return the associated session if exists
Otherwise, return null.
Note: get session before accessing response streams.
Session Tracking
Store/retrieve information to/from HttpSession object.
public void setAttribute(String name, Object
obj)
public Object getAttribute(String name).
Invalidate the session (optional).
Manually: Session.invalidate()
Automatically when no request after certain time.
void setMaxInactiveInterval(int interval)
o Specifies the time, in seconds, between client requests before the
servlet container will invalidate this session. A negative time
indicates the session should never timeout.
public class HelloAgainServlet extends HttpServlet
{
public void doGet(HttpServletRequest req,
HttpServletResponse resp)
ServletException, IOException
{
resp.setContentType("text/html");
throws
HttpSession session = req.getSession(true); // get session if exists, does not
create
PrintWriter out = resp.getWriter();
out.println("<HTML><BODY><h1>Count me!</h1><HR>");
name = req.getParameter("name");
if (session == null)
{
out.println("Welcome," + name + ", I don't believe we've met!");
session = req.getSession(true); // create session
session.setAttribute("Count", new Integer(1));
}
else
{
int n=((Integer)session.getAttribute("Count")).intValue();
out.println("You again? " + name);
out.println("That makes " + (n + 1) + " visits!");
session.setAttribute("Count", new Integer(n + 1));
}
out.println("</BODY></HTML>");
out.close();
}
private String name = "";
}
Session Tracking
The program presented on the previous slide has a bug.
The fix is to change
HttpSession session = req.getSession(true); to
HttpSession session = req.getSession(false);
Some interesting observations:
After you test the correct version, go back and test the
original version. It works! Why?
Session Tracking - Exercise
Design the following servlets
CatalogServlet.java
ShowCartServlet.java
Cookies
Cookies: objects containing a little bit information
Made at server
Sent to client for storage
Retrieved by server when client connects again
(Part of HTTP, supported by Java)
Cookies can be used for
Session tracking. HttpSession implemented using cookies.
Persistent state. E.g. name, address, email address. When user
access some servlets again, no need to provide such information
one more time.
Cookies
Details:
Each cookie is a name=value pair.
Servlets
create cookies and
send them to clients by adding fields to HTTP response headers.
Client browser is expected to support 20 cookies for each Web server,
300 cookies total, and may limit cookie size to 4 KB each.
Clients
automatically return cookies by adding fields to HTTP request headers.
cookies can be retrieved from the request headers
NOTE: Cookies shared among servlets on the server accessed
by the same client.
Cookies
Cookies are objects of class javax.servlet.http.Cookie
To send a cookie,
1. Create a Cookie object
2.
3.
Cookie c = new Cookie(name, value);
Set attributes if necessary
c.setMaxAge(30); // expire after 30 seconds
Send the cookie
response.addCookie(c);
To get information from a cookie,
1.
2.
Retrieve all the cookies from the user's request
Cookie[] cookies = request.getCookies();
Find the cookie that you are interested in and get its
value
for (int i = 0; i < cookies.length; i++) {
String name = cookies[i].getName();
String value = cookies[i].getValue();
}
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException
{
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("Cookies received from client:<br>");
Cookie[] cookies = request.getCookies();
if(cookies !=null){
for (int i = 0; i < cookies.length; i++) {
Cookie c = cookies[i];
String name = c.getName();
String value = c.getValue();
out.println(name + " = " + value + "<br>");
}
}
out.println("<br>Cookies sent to client:><br>");
String name = request.getParameter("cookieName");
String value = request.getParameter("cookieValue");
if (!name.isEmpty() && !value.isEmpty()) {
Cookie c = new Cookie(name, value);
c.setMaxAge(180);
response.addCookie(c);
out.println(name + " = " + value + "<br>");
}} // CookieServlet.java
Cookies
Cookies not shared between different clients accessing the
same server.
Try to Access the following from two different browsers
http://localhost:8080/servlet/CookieServlet?cookieName=cookie1&cook
ieValue=a1
Cookies are not shared between different servers accessed by
the same client
Try:
http://localhost:8080/servlet/CookieServlet?cookieName=monkey&c
ookieValue=a
http://localhost:8080/servlet/CookieServlet?cookieName=scpu8&coo
kieValue=a