You are on page 1of 43

Desarrollo de aplicaciones Java para la Web

Jos Ramn Mndez Reboredo Departamento de Informtica Universidad de Vigo

Servlets: Introduccin

Fueron introducidos por Sun en 1996 como pequeas aplicaciones Java para aadir funcionalidad dinmica a los servidores web. Todos los servlets asociados con un servidor se ejecutan dentro de un proceso simple. Cada vez que llega una peticin, la JVM (Java Virtual Machine) crea un hilo Java para manejar la peticin, reduciendo as la sobrecarga del sistema Una desventaja de esta aproximacin es que el contenido (esttico y dinmico) de la pgina HTML generada, reside en el cdigo fuente del servlet. Como consecuencia cualquier cambio esttico en la pgina (cambio de una URL de un enlace o una imagen), requiere la intervencin del programador y la recompilacin del servlet. Se escriben utilizando la API Servlet (que se distribuye como una extensin estndar del JDK 1.2 y posteriores, sin formar parte del ncleo de la plataforma Java). El lunes 3 de noviembre de 2006 Java pas a ser software libre y se distribuye bajo licencia GNU GPL v.2

Contenedor de componentes de vista

El primer paso es descargar el software que implementa las especificaciones Java Servlet 2.4 y Java Server Pages 2.0. Se puede obtener una versin gratuita, conocida como Tomcat @ Jakarta en http://jakarta.apache.org/tomcat/. En la direccin http://java.sun.com/products/servlet/industry.html se muestra un listado completo de servidores Web que soportan el API Servlet. Para trabajar con servlets es necesario importar el paquete javax.servlet. El mtodo service() implementa el manejo real de la solicitud y respuesta del servlet. El servidor web invoca a este mtodo cuando se solicita la URL del servlet. El servidor pasa los argumentos ServletRequest y ServletResponse al servlet.

Servlet para generar una fecha


import javax.servlet.*; import java.util.*; import java.io.*; public class TimeServlet extends GenericServlet { public String getServletInfo() { return "Time Servlet"; } public void service(ServletRequest peticion, ServletResponse respuesta) throws ServletException, IOException { String fecha = new Date().toString(); PrintStream outputStream = new PrintStream(respuesta.getOutputStream()); outputStream.println(fecha); }

};

Servlet para generar una fecha


import javax.servlet.*; import java.util.*; import java.io.*; public class TimeServlet extends GenericServlet { public String getServletInfo() { return "Time Servlet"; } public void service(ServletRequest peticion, ServletResponse respuesta) throws ServletException, IOException { String fecha = new Date().toString(); PrintStream outputStream = new PrintStream(respuesta.getOutputStream()); outputStream.println(fecha); }

};

EchoRequest Servlet
<FORM action="servlet/EchoRequest.class" method="POST"> <P>NOMBRE: <BR> <INPUT type="text" name="Nombre"> <P>E-MAIL: <BR> <INPUT type="password" name="Email"> <P>TIPO DE INSCRIPCIN: <BR> <INPUT type="radio" name="Inscripcion" value="Normal"> Normal <BR> <INPUT type="radio" name="Inscripcion" value="Estudiante"> Estudiante <BR> <INPUT type="radio" name="Inscripcion" value="Socio de ATI"> Socio de ATI <P>TIPO DE COMUNICACIN: <BR> <INPUT type="checkbox " name="TIPO_1" value="paper"> Artculo <BR> <INPUT type="checkbox " name="TIPO_2" value="poster"> Poster <BR> <INPUT type="checkbox " name="TIPO_3" value="demo"> Demo Comercial <P>ORGANIZACIN: <BR> <INPUT type="text" name="Organizacion"> <P>PAS: <BR> <SELECT size="5" name="Pais"> <OPTION>ESPAA</OPTION> <OPTION>PORTUGAL</OPTION> <OPTION>FRANCIA</OPTION> <OPTION>ALEMANIA</OPTION> <OPTION>ITALIA</OPTION> <OPTION>REINO UNIDO</OPTION> <OPTION>EEUU</OPTION> <OPTION>AFRICA</OPTION> </SELECT> <P><INPUT type="submit" value="Realizar Inscripcin"> <INPUT type="reset" value="Borrar"> </FORM>

EchoRequest Servlet
import javax.servlet.*; import java.util.*; import java.io.*; public class EchoRequest extends GenericServlet { public String getServletInfo(){ return "Echo Request Servlet"; } public void service(ServletRequest peticion, ServletResponse respuesta) throws ServletException, IOException { respuesta.setContentType("text/plain"); PrintStream outputStream = new PrintStream(respuesta.getOutputStream()); outputStream.print("Servidor: " + peticion.getServerName() + ":"+ peticion.getServerPort()); outputStream.print("Cliente: " + peticion.getRemoteHost() + " " + peticion.getRemoteAddr()); outputStream.println("Protocolo: " + peticion.getProtocol()); Enumeration params = peticion.getParameterNames(); if (params != null) { while (params.hasMoreElements()) { String parametro = (String) params.nextElement(); String valor = peticion.getParameter(parametro); outputStream.println(parametro + " = " + valor); } } }

};

EchoRequest Servlet
import javax.servlet.*; import java.util.*; import java.io.*; public class EchoRequest extends GenericServlet { public String getServletInfo(){ return "Echo Request Servlet"; } public void service(ServletRequest peticion, ServletResponse respuesta) throws ServletException, IOException { respuesta.setContentType("text/plain"); PrintStream outputStream = new PrintStream(respuesta.getOutputStream()); outputStream.print("Servidor: " + peticion.getServerName() + ":"+ peticion.getServerPort()); outputStream.print("Cliente: " + peticion.getRemoteHost() + " " + peticion.getRemoteAddr()); outputStream.println("Protocolo: " + peticion.getProtocol()); Enumeration params = peticion.getParameterNames(); if (params != null) { while (params.hasMoreElements()) { String parametro = (String) params.nextElement(); String valor = peticion.getParameter(parametro); outputStream.println(parametro + " = " + valor); } } }

};

Cabeceras de solicitud

Cuando un cliente HTTP (por ejemplo, un navegador) enva una peticin, es necesario que suministre una lnea de peticin (normalmente GET o POST). Es posible tambin enviar un nmero de cabeceras que acompaan a la peticin y que son opcionales excepto Content-Length, que es requerida slo para peticiones POST. La Tabla 1 muestra las cabeceras ms comunes que pueden estar presentes en una peticin HTTP.
Cabecera HTTP
Accept Accept-Charset Accept-Encoding

Significado
Tipos MIME que prefiere el navegador. Conjunto de caracteres que espera el navegador. Tipos de codificacin de datos (como gzip) para que el navegador sepa cmo decodificarlos. Los servlets pueden comprobar explcitamente el soporte para gzip y devolver pginas HTML comprimidas con gzip para navegadores que las soportan, seleccionando la cabecera de respuesta Content-Encoding para indicar que estn comprimidas con gzip. En muchos casos, esto puede reducir el tiempo de descarga por un factor de cinco o diez. Idioma que est esperando el navegador, en el caso de que el servidor tenga versiones en ms de un idioma. Informacin de autorizacin, usualmente en respuesta a una cabecera www-Authenticate enviada desde el servidor. Se usan conexiones persistentes?. Si un servlet recupera un valor Keep-Alive de esta cabecera, u obtiene una lnea de peticin con HTTP 1.1 (donde las conexiones son persistentes por defecto), es posible ahorrar un tiempo considerable en el envo de pginas web que incluyen muchas piezas pequeas (imgenes o applets). Para hacer esto, es necesario enviar una cabecera Content-Length en la respuesta, escribiendo en un ByteArrayOutputStream, y preguntando por el tamao antes de escribir la salida. En mensajes POST especifica el nmero de datos que se han aadido. Manejo de Cookies. (se explica porteriormente). Especifica la direccin de correo electrnico del usuario que realiza la peticin. Slo es usado por aceleradores web, no por clientes personalizados ni por navegadores. Host y puerto escuchado en la URL original Slo devuelve documentos ms nuevos que el especificado, de otra forma se enva una respuesta 304 Not Modified response. El valor no-cache indica que el servidor debera devolver un documento nuevo, incluso si es un proxy con una copia local. URL de la pgina que contiene el enlace que el usuario sigui para obtener la pgina actual. Especifica el tipo de navegador. til cuando el servlet est devolviendo contenido especfico para un navegador. Cabeceras no estndar enviadas por algunas versiones de Internet Explorer, indicando el tamao de la pantalla, la profundidad del color, el sistema operativo, y el tipo de CPU usada por el sistema del navegador.

Accept-Language Authorization Connection

Content-Length Cookie From Host If-Modified-Since Pragma Referer User-Agent UA-Pixels, UA-Color, UAOS, UA-CPU

Ejemplo
import java.io.*; import java.util.*; import javax.servlet.*; import javax.servlet.http.*; public class RequestHeader extends HttpServlet { public void doGet(HttpServletRequest peticion, HttpServletResponse respuesta) throws IOException, ServletException { respuesta.setContentType("text/html"); PrintWriter out = respuesta.getWriter(); out.println("<HTML><HEAD><TITLE>Pgina genereda por el servlet RequestHeader + </TITLE><HEAD>"); out.println("<BODY BGCOLOR=\"WHITE\" TEXT=\"BLACK\">"); out.println("<H1>MOSTRANDO LAS CABECERAS ENVIADAS POR EL CLIENTE</H1>"); out.println("<P>Request Method: " + peticion.getMethod() + "<BR>"); out.println("Request URI: " + peticion.getRequestURI() + "<BR>"); out.println("Request Protocol: " + peticion.getProtocol() + "<BR>"); out.println("<P><table border=\"1\">"); Enumeration e = peticion.getHeaderNames(); while (e.hasMoreElements()) { String nombre = (String)e.nextElement(); String valor = peticion.getHeader(nombre); out.println("<tr><td>" + nombre + "</td><td>" + valor + "</td></tr>"); } out.println("</table></BODY></HTML>");

Ejemplo
import java.io.*; import java.util.*; import javax.servlet.*; import javax.servlet.http.*; public class RequestHeader extends HttpServlet { public void doGet(HttpServletRequest peticion, HttpServletResponse respuesta) throws IOException, ServletException { respuesta.setContentType("text/html"); PrintWriter out = respuesta.getWriter(); out.println("<HTML><HEAD><TITLE>Pgina genereda por el servlet RequestHeader + </TITLE><HEAD>"); out.println("<BODY BGCOLOR=\"WHITE\" TEXT=\"BLACK\">"); out.println("<H1>MOSTRANDO LAS CABECERAS ENVIADAS POR EL CLIENTE</H1>"); out.println("<P>Request Method: " + peticion.getMethod() + "<BR>"); out.println("Request URI: " + peticion.getRequestURI() + "<BR>"); out.println("Request Protocol: " + peticion.getProtocol() + "<BR>"); out.println("<P><table border=\"1\">"); Enumeration e = peticion.getHeaderNames(); while (e.hasMoreElements()) { String nombre = (String)e.nextElement(); String valor = peticion.getHeader(nombre); out.println("<tr><td>" + nombre + "</td><td>" + valor + "</td></tr>"); } out.println("</table></BODY></HTML>");

Manejo de sesiones / Session Tracking

Una sesin es una conexin continuada de un mismo navegador a un servidor web durante un intervalo prefijado de tiempo. Este tiempo depende habitualmente del servidor, aunque a partir de la versin 2.1 de la API Servlet puede establecerse mediante el mtodo setMaxInactiveInterval(int) de la interfaz HttpSession. Esta interfaz es la que proporciona los mtodos necesarios para mantener sesiones. La forma de obtener una sesin es mediante el mtodo getSession(boolean) de un objeto HttpServletRequest. Si el parmetro es true se crea una sesin nueva si es necesario, mientras que si es false, el mtodo devolver la sesin actual. Una vez que se tiene un objeto HttpSession, es posible mantener una coleccin de pares nombre/valor, de forma que pueda almacenarse todo tipo de informacin sobre la sesin. Este valor puede ser cualquier objeto de la clase Object que se desee. La forma de aadir valores a la sesin es mediante el mtodo putValue(String, Object) de la interfaz HttpSession, y la de obtenerlos mediante el mtodo getValue(String) del mismo objeto.

Manejo de Sesiones (Sessin Tracking)


import java.io.*; import java.util.*; import javax.servlet.*; import javax.servlet.http.*; public class SetSession extends HttpServlet { public void service(HttpServletRequest peticion, HttpServletResponse respuesta) throws IOException, ServletException { respuesta.setContentType("text/html"); PrintWriter out = respuesta.getWriter(); out.println("<H3>Ejemplo de Sesiones</H3>"); HttpSession session = peticion.getSession(true); // Se crea la sesion si es necesario Date created = new Date(session.getCreationTime()); // Visualizar informacion de la sesion Date accessed = new Date(session.getLastAccessedTime()); out.println("<hr>"); out.println("<b>ID:</b> " + session.getId() + "<br>"); out.println("<b>Fecha de creacin:</b> " + created + "<br>"); out.println("<b>Fecha de ltimo acceso:</b> " + accessed + "<br>"); out.println("<hr><p>"); String nombreDato = peticion.getParameter("NombreDato"); // Se guarda la informacin if (nombreDato != null && nombreDato.length() > 0) { String valorDato = peticion.getParameter("ValorDato"); session.setAttribute(nombreDato, valorDato); } out.println("<b><i>Los siguientes datos estn en tu sesin:</b></i><br>"); // Visualizar objetos contenidos en la sesion actual Enumeration e = session.getAttributeNames(); while (e.hasMoreElements()) { String nombre = (String)e.nextElement(); String valor = session.getAttribute(nombre).toString(); out.println(nombre + " = " + valor + "<BR>"); } } }

Manejo de Sesiones (Sessin Tracking)


import java.io.*; import java.util.*; import javax.servlet.*; import javax.servlet.http.*; public class SetSession extends HttpServlet { public void service(HttpServletRequest peticion, HttpServletResponse respuesta) throws IOException, ServletException { respuesta.setContentType("text/html"); PrintWriter out = respuesta.getWriter(); out.println("<H3>Ejemplo de Sesiones</H3>"); HttpSession session = peticion.getSession(true); // Se crea la sesion si es necesario Date created = new Date(session.getCreationTime()); // Visualizar informacion de la sesion Date accessed = new Date(session.getLastAccessedTime()); out.println("<hr>"); out.println("<b>ID:</b> " + session.getId() + "<br>"); out.println("<b>Fecha de creacin:</b> " + created + "<br>"); out.println("<b>Fecha de ltimo acceso:</b> " + accessed + "<br>"); out.println("<hr><p>"); String nombreDato = peticion.getParameter("NombreDato"); // Se guarda la informacin if (nombreDato != null && nombreDato.length() > 0) { String valorDato = peticion.getParameter("ValorDato"); session.setAttribute(nombreDato, valorDato); } out.println("<b><i>Los siguientes datos estn en tu sesin:</b></i><br>"); // Visualizar objetos contenidos en la sesion actual Enumeration e = session.getAttributeNames(); while (e.hasMoreElements()) { String nombre = (String)e.nextElement(); String valor = session.getAttribute(nombre).toString(); out.println(nombre + " = " + valor + "<BR>"); } } }

Y si no hay cookies entonces reescritura de URLs

A pesar de que la mayora de los navegadores ms extendidos soportan las cookies en la actualidad, para poder emplear sesiones con clientes que, o bien no soportan cookies o bien las rechazan, debe utilizarse la reescritura de URLs. Para emplear est tcnica lo que se hace es incluir el cdigo identificativo de la sesin (sessionId) en la URL de la peticin. Los mtodos que se encargan de reescribir la URL si fuera necesario son encodeURL() y encodeRedirectURL(). El primero de ellos lee un String que representa una URL y si fuera necesario la reescribe aadiendo el identificativo de la sesin, dejndolo inalterado en caso contrario. El segundo realiza lo mismo slo que con URLs de redireccin, es decir, permite reenviar la peticin del cliente a otra URL.

Reescritura de URLs
// ... continuacin del cdigo anterior // Visualizar objetos contenidos en la sesion actual Enumeration e = session.getAttributeNames(); int contValores = 1; while (e.hasMoreElements()) { ++contValores; String nombre = (String)e.nextElement(); String valor = session.getAttribute(nombre).toString(); out.println(nombre + " = " + valor + "<BR>"); } out.print("<p><a href=\""); out.print(respuesta.encodeURL( "SetSession?NombreDato=nombre" + contValores + "&ValorDato=valor" + contValores)); out.println("\" >URL encoded </a>"); }

Subir ficheros al servidor


<HTML> <HEAD> <TITLE></TITLE> </HEAD> <BODY> <CENTER> <FORM method="POST" enctype='multipart/form-data' action="UploadFichero"> Por favor, seleccione el trayecto del fichero a cargar <BR><INPUT type="file" name="fichero"> <INPUT type="submit"> </FORM> </CENTER> </BODY> </HTML>

Subir ficheros al servidor


<HTML> <HEAD> <TITLE></TITLE> </HEAD> <BODY> <CENTER> <FORM method="POST" enctype='multipart/form-data' action="UploadFichero"> Por favor, seleccione el trayecto del fichero a cargar <BR><INPUT type="file" name="fichero"> <INPUT type="submit"> </FORM> </CENTER> </BODY> </HTML>

A continuacin, se debe que crear un servlet que sea capaz de procesar la respuesta. Para facilitar la labor se pueden emplear las clases que proporciona un subproducto de Apache llamado fileupload (http://jakarta.apache.org/commons/fileupload/). Se descarga el fichero jar correspondiente y se incluye en el classpath. Para el funcionamiento correcto de esta clase ser necesario incluir,tambin incluir en el classpath la implementacin de Yakarta commons IO que se puede descargar de http://jakarta.apache.org/commons/io/

import java.io.*; import java.net.*; import javax.servlet.*; import javax.servlet.http.*; import org.apache.commons.fileupload.*; import java.util.*; /** * Subir ficheros al servidor * @author Jos Ramn Mndez Reboredo * @version 1.0 */ public class UploadFichero extends HttpServlet { /** Handles the HTTP <code>POST</code> method. * @param request servlet request * @param response servlet response */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html"); PrintWriter out = response.getWriter(); out.println("<html><head><title>Servlet</title></head><body>"); procesaFicheros(request,out); out.println("</body> </html>"); out.close(); }

....

public boolean procesaFicheros(HttpServletRequest req, PrintWriter out ) { try { DiskFileUpload fu = new DiskFileUpload(); // objeto que es capaz de parsear la pericin fu.setSizeMax(1024*1024*8); // mximo numero de bytes 8 MB fu.setSizeThreshold(4096); // tamao por encima del cual los ficheros son escritos en disco fu.setRepositoryPath("/tmp"); // directorio en el que se escribirn los ficheros con tamao // superior al soportado en memoria List fileItems = fu.parseRequest(req); // ordenamos procesar los ficheros if(fileItems == null) { return false; } out.print("<br>El nmero de ficheros subidos es: " + fileItems.size()); Iterator i = fileItems.iterator();// Iteramos por cada fichero FileItem actual = null; while (i.hasNext()) { actual = (FileItem)i.next(); String fileName = actual.getName(); out.println("<br>Nos han subido el fichero" + fileName); File fichero = new File(fileName); //construimos un objeto file para la ruta completa fichero = new File("c:\\ficherossubidos\\" + fichero.getName()); //obtener el nombre } actual.write(fichero); // escribimos el fichero colgando del nuevo path

} catch(Exception e) { return false; } return true;

Generar imgenes desde servlets

Para codificar la imagen (Objeto Image), se puede usar la clase GifEncoder que se puede descargar gratuitamente de http://www.acme.com/java/software/Acme.JPM.Encoders.GifEncoder. html. GifEncoder permite codificar imgenes en formato GIF. De la misma forma, se podra emplear las clases JPEGCodec, JPEGEncodeParam y JPEGImageEncoder del paquete com.sun.image.codec.jpeg que se distribuye con el propio JavaSE. Es importante recordar que si se escoge esta opcin el tipo de respuesta del servlet ser image/jpeg y que no es necesario descargar ningn software adicional.

Generar imgenes desde Servlets


protected void processRequest(HttpServletRequest req, HttpServletResponse res) throws ServletException, java.io.IOException { ServletOutputStream bufferSalida = res.getOutputStream(); Graphics contextoGrafico=null; try { // Construir un contexto de grficos mediante una buffered image int w = 200; int h = 50; BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_3BYTE_BGR); contextoGrafico=image.getGraphics(); contextoGrafico.setFont(new Font("Arial", Font.BOLD | Font.ITALIC, 20)); contextoGrafico.draw3DRect(0,0,w-1,h-1,true); Date ahora = new Date(); SimpleDateFormat formateador = new SimpleDateFormat("dd-MM-yyyy HH:mm"); contextoGrafico.drawString(formateador.format(ahora), 20, 30); // Encode the off screen graphics into a JPEG and send it to the client res.setContentType("image/jpeg"); JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(bufferSalida); JPEGEncodeParam param = encoder.getDefaultJPEGEncodeParam(image); param.setQuality(1.0f, false); encoder.setJPEGEncodeParam(param); encoder.encode(image); bufferSalida.flush(); bufferSalida.close(); } finally { if (contextoGrafico != null) contextoGrafico.dispose(); } }

Generar imgenes desde Servlets


protected void processRequest(HttpServletRequest req, HttpServletResponse res) throws ServletException, java.io.IOException { ServletOutputStream bufferSalida = res.getOutputStream(); Graphics contextoGrafico=null; try { // Construir un contexto de grficos mediante una buffered image int w = 200; int h = 50; BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_3BYTE_BGR); contextoGrafico=image.getGraphics(); contextoGrafico.setFont(new Font("Arial", Font.BOLD | Font.ITALIC, 20)); contextoGrafico.draw3DRect(0,0,w-1,h-1,true); Date ahora = new Date(); SimpleDateFormat formateador = new SimpleDateFormat("dd-MM-yyyy HH:mm"); contextoGrafico.drawString(formateador.format(ahora), 20, 30); // Encode the off screen graphics into a JPEG and send it to the client res.setContentType("image/jpeg"); JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(bufferSalida); JPEGEncodeParam param = encoder.getDefaultJPEGEncodeParam(image); param.setQuality(1.0f, false); encoder.setJPEGEncodeParam(param); encoder.encode(image); bufferSalida.flush(); bufferSalida.close(); } finally { if (contextoGrafico != null) contextoGrafico.dispose(); } }

Generar imgenes desde Servlets


protected void processRequest(HttpServletRequest req, HttpServletResponse res) throws ServletException, java.io.IOException { ServletOutputStream bufferSalida = res.getOutputStream(); Graphics contextoGrafico=null; try { // Construir un contexto de grficos mediante una buffered image int w = 200; int h = 50; BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_3BYTE_BGR); contextoGrafico=image.getGraphics(); contextoGrafico.setFont(new Font("Arial", Font.BOLD | Font.ITALIC, 20)); contextoGrafico.draw3DRect(0,0,w-1,h-1,true); Date ahora = new Date(); SimpleDateFormat formateador = new SimpleDateFormat("dd-MM-yyyy HH:mm"); contextoGrafico.drawString(formateador.format(ahora), 20, 30); // Encode the off screen graphics into a JPEG and send it to the client res.setContentType("image/jpeg"); JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(bufferSalida); JPEGEncodeParam param = encoder.getDefaultJPEGEncodeParam(image); param.setQuality(1.0f, false); encoder.setJPEGEncodeParam(param); encoder.encode(image); bufferSalida.flush(); bufferSalida.close(); } finally { if (contextoGrafico != null) contextoGrafico.dispose(); } }

JSP

JSP es una tecnologa basada en Java que simplifica el proceso de desarrollo de sitios web dinmicos. Las Java Server Pages son ficheros de texto (normalmente con extensin .jsp) que sustituyen a las pginas HTML tradicionales. Los ficheros JSP contienen etiquetas HTML y cdigo embebido que permite al diseador de la pgina web acceder a datos desde cdigo Java que se ejecuta en el servidor. Es una tecnologa hbrida basada en template systems. Al igual que ASP, SSJS y PHP puede incorporar scripts para aadir cdigo Java directamente a las pginas .jsp, pero tambin implementa, al estilo de ColdFusion, un conjunto de etiquetas que interaccionan con los objetos Java del servidor, sin la necesidad de aparezca cdigo fuente en la pgina. JSP se implementa utilizando la tecnologa Servlet. Cuando un servidor web recibe una peticin de una pgina .jsp, la redirecciona a un proceso especial dedicado a manejar la ejecucin de servlets (servlet container).

Directivas JSP
Establecer atributos de la pgina:
<HTML> <HEAD> <TITLE>La primera pgina con JSP</TITLE> </HEAD> <BODY BGCOLOR="#FFFFFF"> <%@ page info=Probando JSP. %> <%@ page language=java %> <%@ page contentType=text/plain; charset=ISO-8859-1 %> <%@ page import=java.util.*, java.awt.* %> <%@ page session=false %> <%@ page buffer=12kb %> <%@ page autoFlush=true %> <%@ page isThreadSafe=false %> <%@ page errorPage=/webdev/misc/error.jsp %> <%@ page isErrorPage=false %> Hola mundo! </BODY> </HTML>

Directivas JSP

<%@ include file=localURL %> Permite incluir el contenido de otra pgina .html o .jsp. El fichero es identificado mediante una URL y la directiva tiene el efecto de remplazarse a s misma con el contenido del archivo especificado. Puede ser utilizada para incluir cabeceras y pies de pginas comunes a un desarrollo dado. <%@ taglib uri=tagLibraryURI prefix=tagPrefix %> Esta directiva se utiliza para notificar al contenedor JSP que la pgina utilizar una o ms libreras de etiquetas personalizadas. Una librera de etiquetas es una coleccin de etiquetas personalizadas, que pueden ser utilizadas para extender la funcionalidad bsica de JSP. El valor del atributo uri indica la localizacion del TLD (Tag Library Descriptor), mientras que el atributo prefix especifica el identificador del espacio de nombres en XML que ser anexado a todas la etiquetas de esa librera que se utilicen en la pgina .jsp. Por razones de seguridad, la especificacin JSP permite utilizar solamente TLDs del sistema de archivos local.

Declaraciones globales

Las declaraciones se usan para definir variables y mtodos especficos para una pgina .jsp. Las variables y los mtodos declarados son accesibles por cualquier otro elemento de script de la pgina, aunque estn codificados antes que la propia declaracin. La sintaxis es: <%! declaracion (es) %>
<%! public long factorial (long numero) {

if (numero == 0) return 1;
else return numero * factorial(numero 1);

} %> <%! private int x = 0, y = 0; private String unidad=cm; %>

Declaraciones globales

Un uso importante de la declaracin de mtodos es el manejo de eventos relacionados con la inicializacin y destruccin de la pgina .jsp. La inicializacin ocurre la primera vez que el contenedor JSP recibe una peticin de una pgina .jsp concreta. La destruccin ocurre cuando el contenedor JSP descarga la clase de memoria o cuando el contenedor JSP se reinicia. Estos eventos se pueden controlar sobreescribiendo dos mtodos que son llamados automticamente: jspInit() y jspDestroy(). Su codificacin es opcional.

<%! public void jspInit () { // El cdigo de inicializacin ira aqu. } public void jspDestroy() { // El cdigo de finalizacin ira aqu. } %>

Expresiones y Scriptlets

<%= expresin %> Las expresiones estn ligadas a la generacin de contenidos. Se pueden utilizar para imprimir valores de variables o resultados de la ejecucin de algn mtodo. Todo resultado de una expresin es convertido a un String antes de ser aadido a la salida de la pgina. Las expresiones no terminan con un punto y coma (;). <% scriptlet %> Los scriptlets pueden contener cualquier tipo de sentencias Java, pudiendo dejar abiertos uno o ms bloques de sentencias que debern ser cerradas en etiquetas de scritplets posteriores.

Ejemplo: factorial
<!-- factorialestry.jsp --> <HTML><HEAD> <TITLE>La segunda pgina con JSP</TITLE> </HEAD> <BODY BGCOLOR="#FFFFFF"> <%! public long factorial (long numero) throws IllegalArgumentException { if ((numero < 0) || (numero > 20)) throw new IllegalArgumentException("Fuera de Rango"); if (numero == 0) return 1; else return numero * factorial(numero - 1); } %> <% try { long resultado = factorial (x); %> <p align=center> <%= x %>! = <%= resultado %></p> <% } catch (IllegalArgumentException e) { %> <p>El argumento para calcular el factorial esta fuera de rango.</p> <% } %> </BODY> </HTML>

Comentarios

<!-- comentario HTML --> <%-- comentario JSP --%> <% /* comentario de scriptlet */ %> <% // comentario de scriptlet %>

Acciones

<jsp:forward page=localURL /> Se usa para transferir el control de una pgina .jsp a otra localizacin. Cualquier cdigo generado hasta el momento se descarta, y el procesado de la peticin se inicia en la nueva pgina. El navegador cliente sigue mostrando la URL de la pgina .jsp inicial. <jsp:include page=localURL flush=true /> Proporciona una forma sencilla de incluir contenido generado por otro documento local en la salida de la pgina actual. En contraposicin con la etiqueta forward, include transfiere el control temporalmente.

Objetos implcitos

Objetos implcitos

Objeto
page config request response out session application pageContext exception

Clase o Interfaz
javax.servlet.jsp.HttpJspPage javax.servlet.ServletConfig javax.servlet.http.HttpServletRequest javax.servlet.http.HttpServletResponse javax.servlet.jsp.JspWriter javax.servlet.http.HttpSession javax.servlet.ServletContext javax.servlet.jsp.PageContext java.lang.Throwable

Descripcin
Instancia del servlet de la pgina .jsp. Datos de configuracin del servlet. Peticin. Parmetros incluidos. Respuesta. Stream de salida para el contenido de la pgina. Datos especficos de la sesin de usuario. Datos compartidos por todas las pginas. Contexto para la ejecucin de las pginas. Excepcin o error no capturado.

Factoriales
<!-- factoriales.jsp --> <HTML> <HEAD> <TITLE>Clculo de factoriales con JSP</TITLE> </HEAD> <BODY BGCOLOR="#FFFFFF"> <%! public long factorial (long numero) { if (numero == 0) return 1; else return numero * factorial(numero - 1); } %> <H1>TABLA DE FACTORIALES</H1> <table border="1"> <tr><th><i>x</i></th><th><i>x</i>!</th></tr> <% for (long x = 0; x <=20; ++x) { %> <tr><td><%= x %></td><td><%= factorial (x) %></td></tr> <% } %> </table> </BODY> </HTML>

Factoriales
<!-- factoriales.jsp --> <HTML> <HEAD> <TITLE>Clculo de factoriales con JSP</TITLE> </HEAD> <BODY BGCOLOR="#FFFFFF"> <%! public long factorial (long numero) { if (numero == 0) return 1; else return numero * factorial(numero - 1); } %> <H1>TABLA DE FACTORIALES</H1> <table border="1"> <tr><th><i>x</i></th><th><i>x</i>!</th></tr> <% for (long x = 0; x <=20; ++x) { %> <tr><td><%= x %></td><td><%= factorial (x) %></td></tr> <% } %> </table> </BODY> </HTML>

Excepciones
<!-- factorialestry.jsp --> <HTML><HEAD> <TITLE>Clculo de factoriales con JSP y manejo de excepciones</TITLE> </HEAD> <BODY BGCOLOR="#FFFFFF"> <%! int x = 21; %> <%! public long factorial (long numero) throws IllegalArgumentException { if ((numero < 0) || (numero > 20)) throw new IllegalArgumentException("Fuera de Rango"); if (numero == 0) return 1; else return numero * factorial(numero - 1); } %> <% try { long resultado = factorial (x); %> <p align=center> <%= x %>! = <%= resultado %></p> <% } catch (IllegalArgumentException e) { %> <p>El argumento para calcular el factorial esta fuera de rango.</p> <% } %> </BODY>

Tendencias actuales

Modelo Vista Controlador (MVC) es un patrn de arquitectura de software que separa los datos de una aplicacin, la interfaz de usuario, y la lgica de control en tres componentes distintos. El patrn MVC se emplea frecuentemente en aplicaciones web, donde la vista es la pgina HTML XHTML. En web se usa el conocido MVC Model 2 Actualmente:

Tendencias actuales

Ventajas

No es necesario reescribir las vistas Las acciones se programan una sola vez Acciones que se pueden ejecutar sobre los datos y vistas se definen de forma independiente garantizando una mayor independencia de los componentes del software Las acciones sobre los datos se pueden reutilizar fcilmente para construir otro tipo de aplicaciones (Como por ejemplo Swing con el API Action)

Actualmente la persistencia de datos se implementa mediante tecnologas ORM , en algunos casos application scafolding.

ORM implica que los objetos se mapean automticamente a una base de datos (a veces es necesario decir cmo se almacenan los atributos en ficheros de configuracin). Ejemplos: Hibernate que actualmente implementa la Java Persistent API (Extremadamente fcil de manejar) Application scafolding significa generar cdigo de forma automtica a partir de una base de datos. No esta tan flexible como ORM.

Hibernate
package es.ei.uvigo; @Entity @Table( name=users ) public class User implements Serializable{ private String username; @Id @Column(name = "username", nullable = false) private String username; @Column(nullable = false, length = 50, unique = true) private String clave; public String getUsername(){ return username; } public String getClave(){ return clave; } public void setUsername(String username){ this.username=username; } public void setClave(String clave){ this.clave=clave; } }

Fichero de configuracin
<persistence> <!-- Colocalo en el directorio META-INF del fichero .jar y llmalo persistence.xml --> <persistence-unit name="manager1" transaction-type="RESOURCE_LOCAL"> <class>es.ei.uvigo.User</class> <class>es.ei.uvigo.Cars</class> <!-- enumera todas las clases persistentes --> <properties> <property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect"/> <property name="hibernate.connection.driver_class" value="org.hsqldb.jdbcDriver"/> <property name="hibernate.connection.username" value="sa"/> <property name="hibernate.connection.password" value=""/> <property name="hibernate.connection.url" value="jdbc:hsqldb:."/> <property name="hibernate.max_fetch_depth" value="3"/> <!-- cache configuration --> <property name="hibernate.ejb.classcache.org.hibernate.ejb.test.Item" value="read-write"/> <property name="hibernate.ejb.collectioncache.org.hibernate.ejb.test.Item.distributors" value="read-write, RegionName"/> </properties> </persistence-unit> </persistence>

Hibernate
// Use persistence.xml configuration EntityManagerFactory emf = Persistence.createEntityManagerFactory("manager1"); // Retrieve an application managed entity manager EntityManager em = emf.createEntityManager(); User u=new User(); u.setUsername(moncho); u.setClave(xjmon764d); em.persist(u); em.close(); emf.close(); //close at application end