Enginy
eria del SW II: Aplicacions
web: servlets i JSP
Aplicacions web bàsiques
Introducció a servlets i JSP
Toni Navarrete
Enginy
eria del SW II: Aplicacions
web: servlets i JSP
Pàgina 2
Què són servlets i JSP?
• Permeten escriure pàgines web
dinàmiques amb Java
– Servlets: des d’una classe que extén
HttpServlet
– JSP: directament insertant codi java en una
pàgina HTML
• S’executen en un motor de servlets
(servlet-engine), també anomenat
contenidor web (web-container)
Enginy
eria del SW II: Aplicacions
web: servlets i JSP
Pàgina 3
Arquitectura d’un servidor web
Enginy
eria del SW II: Aplicacions
web: servlets i JSP
Pàgina 4
Arquitectura d’un motor de servlets o
contenidor web
• Exemple: Tomcat, Oracle IAS (Internet
Application Server, que també té un EJB
Container)
Enginy
eria del SW II: Aplicacions
web: servlets i JSP
Pàgina 5
Servlets
• Un servlet és una classe Java que implementa la
interface Servlet, o bé extén les classes abstractes
GenericServlet o
HttpServlet
(el més habitual) que ja
implementen aquesta interface
• GenericServlet i HttpServlet:
– Tenen un mètode service per a manegar peticions HTTP
• HttpServlet permet distingir si les peticions són de tipus Get (mètode doGet) o Post (mètode doPost)
– Els paràmentres d’aquests mètodes (en el cas de HttpServlet) són:
• HttpServletRequest (ServletRequest per GenericServlet): conté els
arguments que es passen mitjançant formularis. També, si n’hi ha, paràmetres de sessió
• HttpServletResponse (ServletResponse per GenericServlet):
l’utilitzarem per escriure la resposta que el servlet retorna (li hem de dir el content-type)
– Tenen mètodes per manegar el cicle de de vida del servlet: init i destroy
– Ambdòs també tenen altres dos mètodes que no se solen sobreescriure: getServletInfo i getServletConfig
Enginy
eria del SW II: Aplicacions
web: servlets i JSP
Pàgina 6
Exemple de servlet simple
public class HolaServlet extends HttpServlet {
/**
* gestiona les peticions GET */
public void doGet (HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
// cal posar el content type abans d’escriure la pàgina
response.setContentType("text/html");
// i ara ja podem escriure al PrintWriter
PrintWriter out = response.getWriter(); out.println("<HTML><HEAD><TITLE>"); out.println(“Exemple de servlet simple”); out.println("</TITLE></HEAD><BODY>");
out.println(“<H1>Hola, soc un servlet</H1>"); out.println("</BODY></HTML>");
out.close();
} }
Enginy
eria del SW II: Aplicacions
web: servlets i JSP Pàgina 7
Exemple de
servlet simple
import javax.servlet.*; import javax.servlet.http.*;public class ExempleServlet extends HttpServlet { /** Inicialització del servlet */
public void init(ServletConfig config) throws ServletException { super.init(config);
}
/** Destrucció del servlet. */ public void destroy() { }
/** Processa peticions (es crida des de doGet i doPost. Escriu la pàgina que s'ha de retornar */
protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, java.io.IOException {
response.setContentType("text/html"); java.io.PrintWriter out = response.getWriter(); out.println("<html>");
out.println("<head>");
out.println("<title>Exemple de servlet simple</title>"); out.println("</head>");
out.println("<body>");
out.println("Hola, soc un servlet que respon a peticions GET i POST"); out.println("</body>");
out.println("</html>"); out.close();
}
/** s'executa quan es rep una petició GET */
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, java.io.IOException { processRequest(request, response);
}
/** s'executa quan es rep una petició POST */
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, java.io.IOException { processRequest(request, response);
} }
Enginy
eria del SW II: Aplicacions
web: servlets i JSP Pàgina 8
Un exemple de JSP
<HTML> <BODY> <H1> <% out.println(“Hola, sóc un JSP"); %> </H1> </BODY> </HTML>• Tot el que hi hagi entre <% i %> és codi Java (es pot
configurar per utilitzar altre llenguatge)
• Hi ha objectes built-in (ja existents sense haver de
declarar-los). Entre d’altres:
– out – request – response
• Compilació de JSPs: es fa la primera vegada que
s’executa (per evitar haver d’interpretar-ho cada
execució)
Enginy
eria del SW II: Aplicacions
web: servlets i JSP Pàgina 9
Un altre exemple de JSP
<%@ page contentType="text/html"%> <HTML> <BODY><% java.util.Calendar dataActual = new java.util.GregorianCalendar(); int mes = dataActual.get(dataActual.MONTH)+1; //comencen en 0 int dia = dataActual.get(dataActual.DAY_OF_MONTH);
int any = dataActual.get(dataActual.YEAR);
int hora = dataActual.get(dataActual.HOUR_OF_DAY); %>
La data actual és <% out.println(dia); %> / <% out.println(mes); %> / <% out.println(any); %>
<BR><B><%
if (hora<14) out.println("Bon dia!");
else if (hora<20) out.println("Bona tarda!"); else out.println("Bon vespre!");
%></B> </BODY> </HTML>
No cal posar-ho, és l’opció per defecte. Si fos XML seria “text/xml”
Enginy
eria del SW II: Aplicacions
web: servlets i JSP
Pàgina 10
Un exemple de JSP amb declaració de
mètodes
• Amb <%! ... %> també podem declarar
mètodes i variables “de classe” que
podran ser accedides des de qualsevol
punt del JSP
<HTML> <BODY>
<%!
public String diguesHola() {
return “Hola, soc un JSP"; }
%>
<B><% =diguesHola() %></B> </BODY>
Enginy
eria del SW II: Aplicacions
web: servlets i JSP
Pàgina 11
Un exemple de JSP amb variables “de classe”
• Les variables declarades amb <%! ... %> poden accedir
als mètodes declarats
• Són compartides per totes les execucions del JSP:
<html> <body bgcolor="#ffffff"> Valor: <% valor = valor+1; out.println(valor); %> </body> </html> <%! int valor;
public void jspInit() { valor = 0; } %> El mètode jspInit es crida només la
primera vegada que s’executa el JSP
Enginy
eria del SW II: Aplicacions
web: servlets i JSP
Pàgina 12
Estructura d’una aplicació web
Web ARchives (WARs)
• Per a que una aplicació amb JSPs, servlets i altres classes pugui ser executada a qualsevol motor de servlets, es va definir WAR
• Estructura de directoris concreta i fitxer de descripció web.xml – / (arrel) on es posen els documents HTML i JSP
– /WEB-INF
• web.xml (descripció i paràmetres de l’aplicació web)
– /classes: servlets, altres classes,... (els .class) – /lib: paquets jar necessaris
– /META-INF
• context.xml (conté el path virtual on executar-se al motor de servlets)
– Es poden crear subdirectoris específics tant en l’arrel com al directori de les classes (WEB-INF/classes)
• Generació del WAR:
– J2EE porta una eina (packager) per empaquetar i generar el WAR – També es pot fer amb jar si tenim l’estructura adequada:
• jar cvf archiveName.war ... – ant
Enginy
eria del SW II: Aplicacions
web: servlets i JSP
Pàgina 13
Passant dades entre peticions
• HTTP no treballa amb connexions permanents
(no orientat a sessió)
– Com passem dades d’un servlet (o JSP) a un altre?
• Un servlet pot manegar paràmetres de
formulari o URL amb un objecte
HttpServletRequest (objecte built-in request en
els JSP), que té el mètode:
– getParameter(“nom_parametre")
– Exemple:
HttpServletRequest request;
String nom = (String)request.getParameter(“nomUsuari”);
Enginy
eria del SW II: Aplicacions
web: servlets i JSP
Pàgina 14
Passant dades entre peticions: sessions
• Es pot crear un objecte de sessió
– Funciona com a una cookie (que normalment no es guarda en disc) que conté un identificador de la sessió
– L’objecte de sessió es crea amb
• HttpSession session = request.getSession();
– Quan es crea la sessió, el motor de servlets envia al navegador la cookie contenint un ID de sessió
– El motor de servlets és qui guarda els paràmetres que cal
mantenir al llarg de la sessió, per exemple el “login”. Utilitza els mètodes de HttpSession:
• void setAttribute(String name, Object value); – Exemple: session.setAttribute(“login”,”toni”); • Object getAttribute(String name);
– Exemple: String s = (String)session.getAttribute(“login”); • void removeAttribute(String name, Object value);
– El client després envia l’identificador de sessió de nou al servidor quan fa qualsevol petició
– El motor de servlets inspecciona els seus objectes de sessió i esborra els que no s’han usat des d’un cert temps (configurable)
Enginy
eria del SW II: Aplicacions
web: servlets i JSP
Pàgina 15
Accedint als objectes de sessió
• Els JSPs tenen l’objecte built-in
session
• Els servlets el poden obtenir des del
request:
Enginy
eria del SW II: Aplicacions
web: servlets i JSP
Pàgina 16
Quan els atributs són objectes
• S’utilitzen JavaBeans
per definir les classes:
– La classe és
serialitzable
– Declara (com a public)
tots els get i set dels
attributs
class Usuari implements Serializable { String login;
String nom;
public String getLogin() {
return this.login; }
public void setLogin(String login) {
this.login = login; }
public String getNom() {
return this.nom; }
public void setNom(String nom) {
this. nom = nom; }
Enginy
eria del SW II: Aplicacions
web: servlets i JSP
Pàgina 17
Quan els atributs són objectes
• S’utilitzen els objectes de sessió de la mateixa
forma. Per exemple:
Usuari usuari = (Usuari)session.getAttribute(“user”); <%= usuari.getLogin() %>
<%= usuari.getNom() %>
• En JSP es poden utilitzar les etiquetes
<jsp:useBean>, <jsp:getProperty> i
<jsp:setProperty>. L’exemple anterior també es
pot escriure així:
<jsp:useBean id=“usuari” class=“Usuari” scope=“session” /> <jsp:getProperty name=“usuari” property=“login” />
Enginy
eria del SW II: Aplicacions
web: servlets i JSP
Pàgina 18
Forçar crear una sessió nova
• Si no es diu el contrari, s’utilitza la
sessió ja creada
• Per fer-ne una de nova:
HttpSession antigaSessio =
request.getSession(false);
// false indica que recuperi la sessió si n’hi havia
// però que no en crei una nova sessió si no n’existia cap
if (antigaSessio != null)
antigaSessio.invalidate();
HttpSession session =
Enginy
eria del SW II: Aplicacions
web: servlets i JSP
Pàgina 19
Guardant dades a nivell d’aplicació
• A vegades volem mantenir
dades/objectes que siguin compartits per
totes les classes, servlets o JSP d’una
aplicació web (per exemple: l’adreça de
la base de dades)
• Es pot utilitzar un objecte d’aplicació
• Mentre que l’objecte de sessió és diferent
per a cada execució (cada usuari), el
Enginy
eria del SW II: Aplicacions
web: servlets i JSP
Pàgina 20
Objectes d’aplicació
• Amb JSP, objecte built-in
application
• Els mateixos mètodes que session:
– setAttribute, getAttribute, removeAttribute
• Amb servlets, és en realitat un objecte que
implemente la interfície ServletContext i s’obté:
ServletContext context = getServletContext();
context.setAttribute(“bd_url”,”http://....”);
• Si el servlet no extén GenericServlet o
HttpServlet, es fa des de ServletConfig:
Enginy
eria del SW II: Aplicacions
web: servlets i JSP
Pàgina 21
Integrant JDBC i JSP/Servlets
• Dins del servlet (doGet o doPost) o del JSP
(entre <% i %>) es poden incloure crides JDBC
per recuperar dades de la BD i a partir dels
resultats generar la pàgina de resultats
• En un JSP s’utilitza la directiva page (que hem
vist abans per declarar el content-type) també
per importar llibreries. Exemple:
<%@ page import=“java.sql.*”> <%@ page import=“java.util.*”>
O
<%@ page import=“java.sql.*, java.util.*”>
• Les classes del driver JDBC han d’estar en el
classpath del motor de servlets (no en el client)
Enginy
eria del SW II: Aplicacions
web: servlets i JSP
Pàgina 22
Integrant JDBC i JSP/Servlet. Exemple
<%@ page import="java.sql.*" %> <html> <body> <h1>Llista d'alumnes</h1> <% Class.forName("com.mysql.jdbc.Driver").newInstance(); String url = "jdbc:mysql://localhost/test";
Connection con = DriverManager.getConnection(url, "", ""); //definim la connexió
Statement stmt = con.createStatement(); // creem un statement sobre la connxió
String mysql = "SELECT codi,nom from alumnes";
ResultSet rs = stmt.executeQuery(mysql); //executem la consulta
while (rs.next()) // recorrem el recordset, fila a fila i anem afegint les "persones" al vector
{
int codi = rs.getInt("codi");
String nom = rs.getString("nom"); %>
Codi: <B><% out.print(codi); %></B>; Nom: <B><% out.print(nom);%></B><BR>
<% }
rs.close(); // tanquem el recordset
stmt.close(); // tanquem el statement con.close(); // tanquem el recordset %>
</body> </html>
Enginy
eria del SW II: Aplicacions
web: servlets i JSP
Pàgina 23