14/05/2007
1
Aplicaciones web y el protocolo HTTP.p y pSoftware de Servidor.Introducción a JSP.Etiquetas JSP.Librería de etiquetas JSTL.Procesamiento de formularios y listados
1
Procesamiento de formularios y listados.Sesión web y cookies.
Petición
Navegador Servidor Web
http://www.um.es/index.html
Respuesta
Hiperenlace
HTMLHTTP
2
Sistema Ficheros
Documento/index.htmlSistema Hipermedia
14/05/2007
2
Aplicación webp
“Sitio web donde las entradas del usuario (navegación y entrada de datos) afectan al estado de un sistema de información”
3
“Una aplicación web usa un sitio web como fachada de una aplicación tradicional”
Las aplicaciones JSP se estructuran como un sitio webi l l convencional, salvo por:
Hay que crear una carpeta llamada “WEB‐INF” en el directorio raíz.
Esta carpeta debe contener al menos un fichero XML con nombre “web.xml” para la configuración de la aplicación.
Si las páginas JSP utilizan alguna librería hay que crear el directorio
4
Si las páginas JSP utilizan alguna librería, hay que crear el directorio “lib” para alojar las librerías.
Si utilizamos código propio, las clases compiladas se alojan en “classes”.
14/05/2007
3
Protocolo de comunicación entre navegador y servidor webModelo Petición/RespuestaModelo Petición/RespuestaEs un protocolo sin estado:
Cada ciclo petición/respuesta es independiente.Tipos de peticiones:
GET: petición de un recursoPOST: envío de datos a un recursoHEAD: petición cabeceras de un recurso...
5
Codificación de datos MIME:text/html, image/gif, ...
URL: identificación universal de recursosprotocolo://maquina[:puerto]/recursoEjemplo: http://www.um.es/index.html
HTTPS: HTTP seguro sobre SSL.
GET /index.html HTTP/1.1Accept: image/gif image/jpeg
PETICIÓNAccept: image/gif, image/jpeg,
application/msword, */*Accept‐Language: esAccept‐encoding: gzipUser‐Agent: Mozilla/4.72Host: dis.um.esConnection: Keep‐Alive(lí bl )
CABECERAS
6
(línea en blanco)CUERPO
CUERPO
14/05/2007
4
HTTP/1.1 200 OKDate: Mon 23 oct 2006 12:24:23 GMT
Código de Estado
Date: Mon, 23 oct 2006 12:24:23 GMTConnection: closeServer: Apache/1.3.24 (Linux)Content‐Length: 2032Last‐Modified: Sun, 22 oct 2006 10:03:11 GMTContent‐Type: text/htmlContent‐Language: esExpires: Sun, 22 oct 2006 12:24:23 GMT
Cabeceras
Cabecera de Entidad
7
(línea en blanco)<HTML><HEAD> ...
Cuerpo
Lenguaje basado en etiquetas utilizado para escribir páginasweb.D fi l t id l f t i lDefine el contenido y el formato visual.Ampliamente difundido:
Facilidad de aprendizaje.Independencia del dispositivo de visualización.
Formularios para la edición de datos.Ha ido evolucionando para superar sus limitaciones iniciales:Hojas de estilo.Server Side Includes (SSI)
8
Server Side Includes (SSI).Lenguajes de script y APIs manipulación documentos:
JavaScript y DOM.HTML dinámico: programación dirigida por eventos
14/05/2007
5
Hiperenlaces:E t bl l i d ióEstablecen relaciones de navegación.Ejecución de páginas de servidor.
Formularios:Fragmento de página que acepta entradas de usuario.Dos parámetros:▪ Action: recurso que procesará el formulario▪ Method: método HTTP envío de datos GET y POST.Elementos:
9
Elementos:▪ Select (listas), TextArea.▪ Input: CheckBox, Text, Password, Radio, Hidden y Submit.
Frames:Dividen el área de visualización de un documento en otras áreas representadas por otros documentos HTML
“Uso coherente e individual de una aplicación web por un usuario”Requisito esencial en las aplicaciones de comercio electrónico Ej Carro de la Requisito esencial en las aplicaciones de comercio electrónico Ej. Carro de la compraProblema: HTTP es un protocolo sin estado.Solución: Cookies.
Pequeños fragmentos de datos que una aplicación envía a un navegador.El navegador los devolverá cada vez que acceda a la aplicaciónLos servidores web los utilizan para implementar un mecanismo de seguimiento
10
Proporcionan APIs para almacenar información asociada a una sesión.Tiempo de vida limitado.
Nuevo problema: desactivación de las cookies.Solución: reescritura de URLs
14/05/2007
6
Tecnologías que permiten a las aplicaciones web ser dinámicas y responder a las entradas de usuario.Protocolo CGI:Estándar para la ejecución de programas de un servidor web.Programas implementados en cualquier lenguaje
11
Programas implementados en cualquier lenguaje PERL es el más utilizado.
Limitaciones:▪ No permite el seguimiento de la sesión.▪ Cada ejecución se realiza en un nuevo proceso
Módulos compilados:C d di á i tCargados dinámicamente.API: contexto llamada, sesión, etc.Tipos: ISAPI, NSAPI, ServletsLimitaciones:▪ Mezcla lógica negocio y salida HTML.▪ Reiniciar servidor ante modificaciones.
Páginas de Script:Páginas HTML con scripts para generar una respuestadinámica
12
Páginas HTML con scripts para generar una respuestadinámica.Tipos: PHP (.php), Cold Fusion (.cfm), ASP (.asp) y JSP(.jsp)Ventajas:▪ Facilitan el desarrollo y despliegue.▪ Facilitan la separación Modelo/Vista.
14/05/2007
7
Motivación:A t l id d d i t d l li t Aumentar la capacidad de procesamiento del cliente (navegador).Mejorar la interface web, especialmente con capacidades de interacción: eventos.Ejemplo: validación de formularios.
Dos estrategias:Compilación: Applets, ActiveX
13
Compilación: Applets, ActiveXInterpretación: JavaScript, VBScript
API DOM:API basada en objetos que permite manipular el contenido, la estructura y el estilo de un documento.
Problema:DOM no define un modelo de eventos ni hojas de estilo.
Solución: HTML DinámicoDOM + Eventos +Hojas de estiloNo es estándar
14
No es estándarModelo de eventos:<input type=”submit” name=”botonAceptar” value=”ok”ONCLICK=”return validarDatos()” >
14/05/2007
8
15
Lenguaje de script que interpretan los navegadores durante la visualización de una páginadurante la visualización de una página.Similar a Java, pero con algunas diferencias (interpretado,orientado a la presentación):
Tipado dinámico.Número limitado de tipos de datos.Basado en objetos no tiene herencia.
Etiqueta HTML Script.
16
q pCódigo trabaja sólo con API DOM.Programación dirigida por eventos:
Definir funciones manejadores de eventos.Otros lenguajes: JScript y VBScript.
14/05/2007
9
“Un Servlet es un componente Java que puede ser instalado en un servidor para ampliar su funcionalidad”:servidor para ampliar su funcionalidad :
Peticiones: HTTPRespuesta: HTML, XML o WML.
Se ejecutan dentro de un contenedor de servlets.
Tecnología Java que sustituye a la programación CGI.Situada en el nivel “módulos ejecutables”.
Hasta JSP, único modo de generar páginas web dinámicas.
17
Hasta JSP, único modo de generar páginas web dinámicas.
Ahora:Controlador en la arquitectura Modelo/Vista/ControlPreprocesamiento de peticiones...
Especificación Servletd fi f k d define un framework de programación Petición/Respuesta.
Especialización protocolo HTTP.
18
Paquetes:javax.servlet.javax.servlet.http.
14/05/2007
10
19
Un solo objeto instanciado por Servlet.
Cada petición se ejecuta en un threaddiferente.
Programación thread‐safe:Uso de variables locales y parámetros.Acceso a atributos en modo consulta.Bloques de sincronización para las
20
Bloques de sincronización para las actualizaciones.
Interface marcaSingleThreadModel
14/05/2007
11
21
Información petición: HttpServletRequest.
Recoger parámetros de la petición:Organizados en un diccionario multivaluado de cadenas.Ejemplos:▪ String nombre = request.getParameter(“nombre”).▪ Enumeration preferencias = request.getParameterValues(“preferencias”);Parámetros petición:▪ getParameterNames(): Enumeration
Recoger cabeceras HTTP:
22
gString referer = request.getHeader(“referer”);
A tener en cuenta:Los parámetros siempre son String.Cuando un parámetro no ha sido definido, devuelve null.▪ Ejemplo: checkbox no marcado.
14/05/2007
12
Información Respuesta: HttpServletResponse.
La salida siempre se genera siguiendo la estructura de una respuestaHTTP:
Código de estado:▪ setStatus(valor)▪ Por defecto, OK (SC_OK).Cabeceras:▪ Tipo MIME: setContentType(), text/html, image/gif▪ Otras: refresco, caché. response.setHeader(“refresh”, “10; index.html”);Respuesta:
23
p▪ Se genera a un stream de salida.▪ Ejemplo:
Respuestas directas:sendError(int sc, String msg)sendRedirect(String url)
El contenedor de servlets implementa un mecanismo de seguimiento de sesionesseguimiento de sesiones.
Información sesión: HttpSession.
El contenedor ofrece al servlet la sesión asociada a la petición:HttpSession sesion = request.getSession();
Manejar información de la sesión:Tabla (String‐Object)
24
( g j )Cliente c = (Cliente) sesion.getAttribute(“cliente”);sesion.setAttribute(“fallos”, new Integer(0));
Tiempo de vida limitado.Configurable en web.xml de la aplicación web.
14/05/2007
13
Problema:El i i t d l ió b d ki d El seguimiento de la sesión basado en cookies puede ser deshabilitado.
Solución: reescritura de URLsAñadir a todas las URLs a módulos ejecutables de la aplicación (servlets, JSP) un parámetro que identifique a la sesión.
Consecuencia:
25
Generación dinámica de URLs.
Reescritura:String nuevaUrl = response.encondeURL(url);El método realiza la reescritura si es necesario.
Problema:El mecanismo de seguimiento está limitado a la sesión del navegador.
Solución:Enviar una cookie y mantener la información de sesión persistente.Útil para personalizar sitios web.
Las cookies se añaden a la respuesta.
26
Las cookies se recuperan de la petición:
14/05/2007
14
Tipos:Un servlet invoca a otro servletUn servlet invoca a otro servlet.Un servlet guarda información para otros servlets.
Invocación de un servlet: RequestDispatcherResquestDispatcher rd=request.getResquestDispatcher(“servlet/Hola”);
Tipos de invocación:forward: reenvío de la llamadard.forward(request, response);include para incluir el contenido de una página (SSI)
27
include: para incluir el contenido de una página (SSI)rd.include(request, response);
A tener en cuenta:Los dos servlets comparten la petición (ServletRequest).La invocación no está restringida a servlets: HTML, JSP, ...
RequestDispatcher (continuación):
Intercambio de información a través de la petición:request.setAttribute(“usuarios”, lista);List usuarios = (List) request.getAttribute(“usuarios”);
Comunicación a través del Contexto.Los servlets comparten un objeto ServletContext.Compartir información:▪ contexto setAttribute(“factoriaDAO” factoriaDAO);
28
▪ contexto.setAttribute( factoriaDAO , factoriaDAO);▪ FactoriaDAO f = (FactoriaDAO) contexto.getAttribute(“factoriaDAO”);
Contexto accesible a través de ServletConfig:ServletContext contexto = getServletConfig().getServletContext();
14/05/2007
15
Tipos de URL:b l h l lh d l lAbsoluta: http://localhost/dai/servlet/Hola
Relativa: ../index.jsp, servlet/HolaRelativa al contexto:Añade el nombre de la aplicación.▪ /dai/servlet/HolaEn la práctica:▪ Utilizar URL relativas.
29
Utilizar URL relativas.Parámetros inicio de un servlet:
Declarados en web.xml.Accesibles a través de ServletConfig▪ String urlBD =getServletConfig().getInitialParameter(“urlBD”);
Motivación:L li i b t i l i fi lLas aplicaciones web se construyen sin conocer al usuario final.Cambios frecuentes
Problema:La generación del interfaz HTML se realiza utilizando código Java out.println(“...”)No podemos usar editores HTML.Costoso tener diseñadores gráficos con conocimientos Java
30
Costoso tener diseñadores gráficos con conocimientos Java.
Consecuencia:El mantenimiento (evolución) de la aplicación está limitado
14/05/2007
16
Objetivo: Separación roles: Diseñador Gráfico y Desarrollador.Nuevo modelo de desarrollo de contenidos dinámicos en el que la lógica de la aplicación se encapsule en componentes portables y reutilizables.
Solución: JSP (Java Server Pages)“Una página HTML normal que puede incluir scripts
31
Una página HTML normal que puede incluir scripts para generar HTML dinámicamente”.En general, puede generar cualquier tipo de contenido dinámico: XML, WML, etc.Código script, por defecto Java (scriptlets).
No representan una nueva tecnología:S á l l lSemánticamente equivalen a los servlets.Sólo facilitan el desarrollo y mantenimiento.
Ciclo de vida:El contenedor de servlets traduce la página JSP a su equivalente servlet la primera vez que se accede.El servlet es compilado y cargado en memoria siguiendo
32
p y g gsu ciclo de vida convencional.Si la página es modificada, el contenedor detecta el cambio y vuelve a repetir el proceso.Ventaja: no se hace necesario reiniciar el servidor Web.
14/05/2007
17
33
Las aplicaciones JSP se estructuran como un sitio webi l l convencional, salvo por:
Hay que crear una carpeta llamada “WEB‐INF” en el directorio raíz.
Esta carpeta debe contener al menos un fichero XML con nombre “web.xml” para la configuración de la aplicación.
Si las páginas JSP utilizan alguna librería hay que crear el directorio
34
Si las páginas JSP utilizan alguna librería, hay que crear el directorio “lib” para alojar las librerías.
Si utilizamos código propio, las clases compiladas se alojan en “classes”.
14/05/2007
18
El servidor Tomcat ofrece a las aplicaciones web fuentes de datospara optimizar el uso de conexionespara optimizar el uso de conexiones.
En la plantilla de aplicación web proporcionada, dentro de la carpeta “META‐INF” tiene el fichero “context.xml” para configurar la base de datos.
Definición de la fuente de datos en el fichero:Nombre lógico: “jdbc/ejemplo”
35
g j / j pURL: “jdbc:mysql://localhost/ejemplo”Clase del Driver: “com.mysql.jdbc.Driver” (MySQL)Identificación: “web/web”
Una página JSP es una plantilla de una página web que tiene bloques de código que generan contenido dinámicamentebloques de código que generan contenido dinámicamente.
El desarrollo de JSP ha tenido dos fases:
Versiones 1.X: se ofrece al programador mucha flexibilidad para el desarrollo.▪ Mantenimiento complejo.▪ Limitación: conocer Java
36
Versiones 2.X: se simplifica el modelo▪ Se utilizan etiquetas al estilo XHTML.▪ No es necesario conocer Java.
14/05/2007
19
Inicialmente en JSP sólo se podían incluir fragmentos de código JavaJava:
<% ... %>El servidor web ofrece a esos fragmentos de código una serie de objetos implícitos propios de la programación web:
request, response, out, session, application, config, ...Al ejecutarse la página, se ejecutan los fragmentos de código y se sustituye el código por la salida del fragmento.Ventajas:
d l d ó
37
Modelo de programación muy potente.Inconvenientes:
Se requieren conocimientos de Java.Difícil mantenimiento de las aplicaciones.
...<body><body>
<p>Esto es HTML normal</p><%out.println("<p>Esto se ha escrito desde código
java</p>");
int i = 10; i++;
out.println("<p>Ejecuta cualquier código Java: " + i + "</p>");
%
38
%>
</body></html>
14/05/2007
20
U á i JSP d i li d d l i d Una página JSP no puede visualizarse desde el sistema de ficheros.
Debe ser ejecutada por un servidor JSP (Tomcat) y el resultado es obtenido a través del protocolo HTTP.
Hay que adaptar el entorno de edición (Dreamweaver, BEA
39
Workshop) para que maneje el concepto de sitio web.
Los creadores de JSP observaron que las páginas JSP con código J i i i difí ilJava tienen un mantenimiento difícil.
Se propuso un modelo de reutilización de código basado en etiquetas:
El programador define una etiqueta con parámetros, al estilo HTML, que al declararse en la página implica la ejecución de un fragmento de código Java.
40
Una misma etiqueta se puede utilizar en cualquier página JSP.Se favorece notablemente la reutilización y mejora el mantenimiento de las páginas.
14/05/2007
21
Sin embargo, en la mayoría de proyectos JSP continuamente se reinventan etiquetas parecidas.Las necesidades de programación web son similares: recorridos, mostrar valores, condiciones, etc.En este contexto, se creó una librería de etiquetas estándar llamada JSTL.JSTL cubre la mayoría de las necesidades de programación web. Pero no todas. A veces hay que introducir código Java …Asimismo, JSTL también define un lenguaje de expresionesindependiente de Java
41
independiente de Java.Como inconveniente, JSTL puede resultar tedioso para escribir estructuras imperativas. Se recomienda usar editores que faciliten la escritura de JSTL como la extensión Visual JSTL de Dreamweaver.
...<body><body>
<p>Esto es HTML normal</p>
<c:set var=“numero” value=“${1 + 1}” /><p>La suma de 1 + 1 es
<c:out value=“${numero}” /></p>
</body></html>
42
14/05/2007
22
Expresión : <%= expresión %>p pEl equivalente XML es <jsp:expression> expression </jsp:expression>. Las variables predefinidas son request, response, out, session, application, config, y pageContext.
Scriptlet <% code%>;
43
Scriptlet <% code%>;El código se inserta en el método serviceEl equivalente XML es: <jsp:scriptlet> code</jsp:scriptlet>.
Declaración <%! code %>El código se inserta en el cuerpo de la clase del servlet, fuera del método service. El equivalente XML es: <jsp:declaration> code</jsp:declaration>.
44
Directiva Page <%@ page att="val" %>Dirige al motor servlet sobre la configuración general.
14/05/2007
23
Directiva PageEl i l t XML j di ti tt " l"\ L El equivalente XML es: <jsp:directive.page att="val"\>. Los atributos legales son (con los valores por defecto en negrita): ▪ import="package.class"▪ contentType="MIME‐Type" ▪ isThreadSafe="true|false" ▪ session="true|false" ▪ buffer="sizekb|none" ▪ autoflush="true|false"
45
▪ extends="package.class" ▪ info="message" ▪ errorPage="url" ▪ isErrorPage="true|false" ▪ language="java"
Directiva Include <%@ include file="url" %>@Un fichero del sistema local se incluirá cuando la página se traduzca a un ServletEl equivalente XML es: <jsp:directive.include file="url"\>. La URL debe ser relativa.
46
Comentario <%‐‐ comment ‐‐%>
14/05/2007
24
Acción jsp:include <jsp:include page="relative URL" flush "true"/>flush="true"/>
Incluye un fichero en el momento en que la página es solicitada.
Acción jsp:useBean <jsp:useBean atributos ..class="bank.Checking" > …</jsp:useBean>
Encuentra o construye un Java Bean. Los posibles ib
47
atributos son: ▪ id="name" ▪ scope="page|request|session|application" ▪ class="package.class"▪ type="package.class" ▪ beanName="package.class"
Acción jsp:setProperty <jsp:setPropertyj p p y j p p yatt=val*/>Los atributos legales son: ▪ name="beanName" ▪ property="propertyName|*" ▪ param="parameterName"
l " l"
48
▪ value="val"
Acción jsp:getProperty <jsp:getPropertyname="propertyName" value="val"/>
14/05/2007
25
Acción jsp:forward <jsp:forwardj p j ppage="relative URL"/>Reenvía la petición a otra página.
Acción jsp:plugin <jsp:pluginattribute="value"*> </jsp:plugin>
49
attribute= value *> ... </jsp:plugin> Genera etiquetas OBJECT o EMBED, apropiadas al tipo de navegador, pidiendo que se ejecute un applet usando el Java Plug‐in.
Current time: <%= new java.util.Date() %>
Simplificación de las expresionesrequest, el HttpServletRequest; response, el HttpServletResponse; session, el HttpSession asociado con el request (si existe), y out el PrintWriter (una versión con buffer del tipo JspWriter)
50
out, el PrintWriter (una versión con buffer del tipo JspWriter) usada para envíar la salida al cliente.
Your hostname: <%= request.getRemoteHost() %>
14/05/2007
26
Tienen acceso a las mismas variables predefinidas que las expresiones
<% String queryData = request.getQueryString();out.println("Attached GET data: " + queryData); %>
El código dentro de un scriptlet se insertará e actamente tá it l i
51
exactamente como está escrito, y cualquier HTML estático (plantilla de texto) anterior o posterior al scriptlet se convierte en sentencias print
<% if (M th d () < ) { %><% if (Math.random() < 0.5) { %>Have a <B>nice</B> day!<% } else { %>Have a <B>lousy</B> day!<% } %>
if (Math.random() < 0.5) { i l ("H B i /B d !") }
52
{ out.println("Have a <B>nice</B> day!");} else { out.println("Have a <B>lousy</B> day!");}
14/05/2007
27
Permiten definir métodos o campos que p qserán insertados dentro del cuerpo principal de la clase servlet (fuera del método serviceque procesa la petición).No generan ninguna salida se usan en conjunción con expresiones JSP o scriptlets
53
<%! private int accessCount = 0; %>Accesses to page since server reboot: <%= ++accessCount%>
Afecta a la estructura general de la clase gservlet. Normalmente tienen la siguiente forma
<%@ directive attribute1="value1" attribute2="value2"
54
attribute2= value2 ... attributeN="valueN" %>
14/05/2007
28
import="package.class" o i t " k l k l N" import="package.class1,...,package.classN".
<%@ page import="java.util.*" %> El atributo import es el único que puede aparecer múltiples veces.
contentType="MIME‐Type" o contentType="MIME Type; charset=Character
55
contentType= MIME‐Type; charset=Character‐Set" Tipo MIME de la salida, por defecto text/html. <%@ page contentType="text/plain" %> es igual que <% response.setContentType("text/plain"); %>
isThreadSafe="true|false". True: múltiples peticiones pueden procesarse simultáneamente con un sólo ejemplar del servletFalse: peticiones enviadas serialmente o con peticiones simultáneas siendo entregadas por ejemplares separados del servelt.
session="true|false"
56
session= true|false . True: La variable predefinida session (del tipo HttpSession) debería unirse a la sesión existente si existe una, si no existe se debería crear una nueva sesión para unirla. False: No se usarán sesiones.
14/05/2007
29
buffer="sizekb|none". Tamaño del buffer (>8 kb)para el JspWriter out.
autoflush="true|false". True (por defecto) indica que el buffer debería descargarse cuando esté lleno. False: se debe lanzar una excepción cuando el buffer
57
False: se debe lanzar una excepción cuando el buffer se sobrecargue.
extends="package.class". Esto indica la superclase del servlet que se va a generar.
info="message". Define un string que puede usarse para ser recuperado mediante el método getServletInfo recuperado mediante el método getServletInfo.
errorPage="url". Especifica una página JSP que se debería procesar si se lanzará cualquier Throwable pero no fuera capturado en la página actual.
isErrorPage="true|false". Indica si la página actual actúa o no como página de error de otra página JSP. El valor por defecto es false.
l "j " E l á d
58
language="java". En algunos momentos, esto está pensado para especificar el lenguaje a utilizar. Por ahora, no debemos preocuparnos por él ya que java es tanto el valor por defecto como la única opción legal.
14/05/2007
30
<!DOCTYPE HTML PUBLIC "‐//W3C//DTD HTML 4.0 Transitional//EN"><HTML><HTML><HEAD><TITLE>ServletTutorial: JavaServer Pages (JSP) 1.0</TITLE><META NAME="author" CONTENT="[email protected]"><META NAME="keywords" CONTENT="..."><META NAME="description" CONTENT="..."><LINK REL=STYLESHEET HREF="Site‐Styles.css" TYPE="text/css"></HEAD>
59
/<BODY><%@ include file="/navbar.html" %><!‐‐ Part specific to this page ... ‐‐></BODY></HTML>
Posibilita cargar barras de navegacióng g
Inserta los ficheros en el momento en que la página es traducida si la barra de navegación cambia, necesitamos re‐traducir todas las páginas JSP que la refieren
60
Si los ficheros incluidos cambian de forma más frecuente, podríamos usar la acción jsp:include en su lugar
14/05/2007
31
Request: HttpServletRequest asociado con la petición, y nos permite i l á t d l ti ió ( di t tP t ) l ti d mirar los parámetros de la petición (mediante getParameter), el tipo de
petición (GET, POST, HEAD, etc.), y las cabeceras HTTP entrantes (cookies, Referer, etc.)
Response: HttpServletResponse asociado con la respuesta al cliente
Out: Este es el PrintWriter usado para envíar la salida al cliente. Sin embargo, para poder hacer útil el objeto response, esta es una versión
61
g , p p j p ,con buffer de PrintWriter llamada JspWriter
Session: HttpSession asociado con la petición.
Application: ServletContext obtenido mediante tS l tC fi () tC t t() getServletConfig().getContext().
Config: Objeto ServletConfig para la página.
PageContext: Encapsula características de uso específicas del servidor como JspWriters de alto rendimiento. La idea es que, si tenemos acceso a ellas a través de esta clase en vez directamente, nuestro código seguirá
62
, g gfuncionando en motores servlet/JSP "normales"
Page: sinónimo de this, pensado para lenguajes distintos de java
14/05/2007
32
Usan construcciones de síntaxis XML para controlar el comportamiento del motor de Servlets
Acción jsp:include Insertar ficheros en una página que está siendo generadainserta el fichero en el momento de la conversión de
63
inserta el fichero en el momento de la conversión de la página JSP a un Servlet Flexibilidad, pero tienen que tener poco contenido JSP “general”
<jsp:include page="relativeURL" flush="true" />
Here is a summary of our four t t t imost recent news stories:
<OL> <LI><jsp:includepage="news/Item1.html" flush="true"/> <LI><jsp:includepage="news/Item2.html" flush="true"/> <LI><jsp:include
" /It ht l"
64
page="news/Item3.html" flush="true"/> <LI><jsp:includepage="news/Item4.html" flush="true"/>
</OL>
14/05/2007
33
Cargar y utilizar un JavaBean en la página JSPPermite utilizar la reusabilidad de las clases Java sin sacrificar la conveniencia de añadir JSP sobre servletsCrea una instancia de class y la asigna a id.
<jsp:useBean id="name" class="package.class" />
Modificación de propiedades mediante scriptlet o
65
Modificación de propiedades mediante scriptlet o jsp:setProperty
<jsp:useBean id="test" l "h ll Si l B " class="hall.SimpleBean" />
<jsp:setPropertyname="test" property="message" value="Hello WWW" /> <H1>Message: <I>
66
<H1>Message: <I><jsp:getPropertyname="test" property="message" />
14/05/2007
34
Id: Nombre de la variable
Class: Paquete del bean
Scope: Disponibilidad: Page, Request, Session,Application.
Type: Tipo de la variable
67
Type: Tipo de la variable
BeanName: Nombre del bean. Type+beanNamecomo alternativa a class
Dar valores a propiedades de beans ya creadosAt ib tAtributosName: Nombre del beanProperty: nombre de la propiedad. ▪ “*” todos los parámetros de la peticiónValue: Conversión del valor automática a tipos baseParam: Parámetro de la petición del que se debería d i l i d d
68
derivar la propiedad▪ <jsp:setProperty name="orderBean" property="numberOfItems" param="numItems" /> Selecciona la propiedad numberOfItems para cualquier valor que tenga el parámetro numItems en la petición
14/05/2007
35
Acción jsp:forwardj p<jsp:forward page="/utils/errorReporter.jsp" /><jsp:forward page="<%= someJavaExpression %>" />
Acción jsp:pluginEsta acción nos permite insertar un elemento
69
OBJECT o EMBED específico del navegador para especificar que el navegador debería ejecutar un applet usando el Plug‐in Java.
1) Escribir el fichero JSP, creando formulario ) ,HTML2) Escribir el bean en el fichero java3) Usar el bean: jsp:useBean, jsp:set/getProperty4) Para realizar más procesos sobre los datos
70
4) Para realizar más procesos sobre los datos de usuario usar el objeto request dentro de un scriptlet
14/05/2007
36
71
Un formulario HTML tiene tres partes pprincipales: Las etiquetas de apertura y cierre <form>Los elementos de entrada El botón Submit que envía los datos al servidor.f h d i URL
72
<form method=get action=someURL>Cada elemento del formulario debe tener un nombre: <input type="text" name="username">
14/05/2007
37
GETObtener datos del servidorDatos como cadena de caracteres: name=jesualdoname&jesualdo+apellido&fernandezLa llamada puede ser vista por el usuario
POST
73
POST Enviar datos al servidorDatos como cuerpo de solicitud de cabecera HTTPLlamada no vista por el usuario
Crear el Bean
Obtener datos desde el formulario
74
14/05/2007
38
Método Definido en Trabajo Realizado
getRequest javax.servlet.jsp.PageContext Devuelve el Objeto request actual
getParameterNames javax.servlet.ServletRequest Devuelve los nombres de los parámetros contenidos actualmente en request
getParameterValues javax.servlet.ServletRequest Devuelve los valores de los parámetros contenidos actualmente en request
De el e el alor de n parámetro
75
getParameter javax.servlet.ServletRequest Devuelve el valor de un parámetro su proporcionamos el nombre
<h1>Hello, <jsp:getProperty name="mybean" , j p g p y yproperty="username"/>!
<jsp:useBean id="mybean" scope="session" class="hello.NameHandler" /><jsp:setProperty name="mybean" property="*"
76
<jsp:setProperty name= mybean property= * />
14/05/2007
39
Excepciones vs páginas de errorp p g
Las excepciones en tiempo de ejecución son fáciles de menejar en una aplicación JSP objeto exception.
U d l bj i á i d
77
Uso del objeto exception en una página de error, donde mostramos el nombre de la clase exception, su seguimiento de pila, y un mensaje informativo para el usuario.
Nuestro Bean lanzará ciertas excepciones bajo ciertas condiciones.
Seguimiento del bean para ayudarnos a obtener información sobre lo que estaba haciendo el usuario cuando la excepción fue lanzada.
El fichero JSP usa una directiva page con errorPage que selecciona el nombre de un fichero JSP que mostrará un mensaje al usuario cuando ocurre una excepción.
E ibi fi h d á i d d di i
78
Escribir un fichero de página de error, usando una directiva pagecon isErrorPage="true".
En el fichero de la página de error, usa el objeto exception para obtener información sobre la excepción.
14/05/2007
40
Usamos mensajes informativos, en nuestra página de error o incluida desde otros ficheros para darle al error o incluida desde otros ficheros, para darle al usuario un mensaje relevantemente informativo sobre lo que el usuario estaba haciendo cuando se lanzó la excepción.
Sólo podemos crear una página de error por JSP.<%@ page isThreadSafe="false" import="java.util.*, email.Map"
errorPage="error.jsp" %>
79
g j p
Cada JSP puede llamar a una página de error diferente
Es conveniente usar al menos 1 en la aplicación
Declaración de página de error<%@ page isErrorPage="true" import="java.util.*, email.Map" %>
Ahora ya podemos usar el objeto exception
80
Ahora ya podemos usar el objeto exception
<%= exception.toString() %><% exception.printStackTrace(); %>
14/05/2007
41
Lenguaje de expresionesAnteriormente sólo estaba disponible en JSTLAnteriormente sólo estaba disponible en JSTL
Páginas JSP en sintaxis XML ( JSP 1.2 también permitía escribir documentos JSP, pero de una manera más incómoda)
Implementar tags a medida utilizando la propia tecnología JSPSe implementan en páginas JSPMás sencillo que el API de extensión de tags (javax.servlet.jsp.tagext),pero menos potenteÚtil para tags orientados a presentación, para tags que hagan uso de librerías
81
Útil para tags orientados a presentación, para tags que hagan uso de librerías existentes y para desarrolladores de páginas JSP que no dispongan de conocimientos de Java
Compatibilidad con JSP 1.xUn contenedor de JSP 2.0 tiene que poder ejecutar aplicaciones con sintaxis JSP 1.xEs posible migrar una aplicación JSP 1.x a sintaxis JSP 2.0 página a página
JSP 1.x
JSP2.0Las expresiones tienen que ir rodeadas por ${ y }.Cualquier valor que no empiece por ${, se considera un literal . Los
82
Cualquier valor que no empiece por ${, se considera un literal . Los literales que incluyen el símbolo ${, han de escaparlo rodeándolo de ${' y '}▪ <xxx:aTag att="This literal includes ${'${'} character"/>Se puede acceder a las propiedades de un JavaBean, y a objetos de un Map, List o vector▪ ${user.firstName} = user.getFirstName()▪ ${user.address.city} = user.getAddress().getCity()
14/05/2007
42
JSP2.0Unifica el tratamiento de los operadores . y []▪ ${user.firstName} es equivalente a ${user["firstName"]}▪ ${user.preferencesMap["shipping"]} es equivalente a▪ ${user.preferencesMap.shipping}
Para determinados casos, es preciso usar el operador []
83
[]▪ ${user.preferencesMap["book.fiction"]} es equivalente a▪ user.getPreferencesMap().get("book.fiction")▪ ${user.preferencesMap[product.category]} es equivalente a▪ user.getPreferencesMap().get(product.getCategory())
JSP2.0Objetos implícitosObjetos implícitos▪ pageScope (Map)▪ requestScope (Map)▪ sessionScope (Map)▪ applicationScope (Map)▪ param (Map que mapea nombres de parámetros univaluados a String)▪ paramValues (Map que mapea nombres de parámetros multivaluados a
String[])
d b f á b l b lí
84
Cuando se usa un objeto sin especificar su ámbito (el objeto implícito en el que está contenido), se busca en los ámbitos page, request, session y application (en este orden)▪ Ejemplo<xxx:if test="${shoppingCart.numberOfProducts > 0}">...</xxx:if>
14/05/2007
43
JSP2.0Tipos de LiteralesTipos de Literales▪ Boolean (true y false)▪ Numéricos▪ Cadenas de caracteres (entre comillas simples o dobles)▪ null
Operadores▪ Aritméticos: +,‐, *, /, div, %, mod▪ Lógicos: &&, and, ||, or, !, not▪ Relacionales: ==, eq, !=, ne, <, lt, >, gt, <=, le, >=, ge▪ empty: permite comprobar si un valor es null
85
▪ empty: permite comprobar si un valor es null▪ Ejemplos
<xxx:if test="${!empty requestScope.previous}">...</xxx:if><xxx:if test="${sessionScope.shoppingCart.numberOfProducts > 0}">...</xxx:if>
▪ Se pueden usar paréntesis
Estándares:bá d bl l á b l fij jEtiquetas básicas disponibles en cualquier página bajo el prefijo jsp.
Ejemplo: <jsp:include page=“pagina.jsp” />Personalizadas:
Definidas por el programador para reutilizar tareas comunes del desarrollo JSP.
Se organizan en librerías.
Para disponer de ellas es necesario incluir la declaración de la librería y su implementación en la carpeta WEB INF
86
implementación en la carpeta WEB‐INF.Para utilizarlas en una página, hay que importar la librería.
JSTL:Librerías de etiquetas estandarizadas: Core, SQL, Internacionalización y Formato, y XML.
14/05/2007
44
Existen varias etiquetas estándares JSP, aunque actualmente su funcionalidad está superada por las etiquetas JSTL.funcionalidad está superada por las etiquetas JSTL.
A modo de ejemplo, veremos la etiqueta <jsp:include>Permite incluir en una página otro documento o página JSP.
<jsp:include page=“cabecera.jsp” />
Si la página JSP que incluye acepta parámetros, se pueden establecer del siguiente modo:
<jsp:include page=“cabecera.jsp”>
87
<jsp:param name=“nombre” value=“Pedro” /></jsp:include>
Otro ejemplo: Etiqueta <jsp:forward> redirige la petición a otra página JSP
JavaBeans nos permiten separar la parte de presentación de á i JSP d l i l t ió d l d una página JSP de la implementación de una regla de
negocioSin embargo, sólo 3 elementos acción en JSP se pueden usar para acceder a un bean:▪ jsp:useBean
▪ jsp:getProperty
▪ jsp:setProperty
Por tanto a menudo tenemos que incluir código en un JSP
88
Por tanto a menudo tenemos que incluir código en un JSPJSP (1.1 en adelante) define custom tags que pueden ser usadas para definir acciones propietarias, de manera que en nuestro JSP únicamente tenemos código de marcado
14/05/2007
45
Clases Java que implementan unos interfaces especiales
Una vez que se han desarrollado y desplegado, sus acciones pueden ser llamadas usando sintaxis XML
BeneficiosPueden reducir o eliminar los scriptlets en nuestras aplicaciones JSP. Cualquier parámetro necesario para la etiqueta puede pasarse como atributo o contenido del cuerpo no se necesita código Java para inicializar o seleccionar propiedades de componentes.Sintaxis muy simple, estilo HTML.
89
Pueden mejorar la productividad de los desarrolladores de contenido que no son programadores, permitiéndoles realizar tareas que no pueden hacer con HTML.Son reutilizables. Ahorran tiempo de desarrollo y de prueba. ▪ Los Scritplets no son reusables, a menos que llamemos reutilización a "copiar‐y‐pegar".
Paquete javax.servlet.jsp.tagext
Un manejador de etiquetas (Tag Handler) es una clase que está ligada a una etiqueta personalizada y es invocada cada vez que el contenedor de JSPs encuentra la etiqueta.
En JSP 1.2, la clase javax.servlet.jsp.tagext tiene 4 interfaces y 12 clases
90
Los dos interfaces más importantes son Tag y BodyTagEstos interfaces dictan el ciclo de vida de un manejador de etiquetas
14/05/2007
46
91
El contenedor JSP llama a los métodos de un handler en el siguiente orden:orden:
Obtiene una instancia del pool de TagHandlers o crea uno nuevo. Después llama a setPageContext que representa a la página donde se encontró la custom tag. ▪ public void setPageContext(PageContextpageContext)
El contenedor de JSP llama a setParent, pasándole el objeto Tag que representa a la etiqueta padre de la etiqueta procesada
92
Tag que representa a la etiqueta padre de la etiqueta procesada▪ public void setParent(Tag parent)
El contenedor de JSP asigna todos los atributos de la etiqueta, usando métodos getter y setter como en JavaBeas. Si se encuentra un atributo temperatura llamará a setTemperatura.
14/05/2007
47
El contenedor llama a doStartTag, que puede devolver Tag.SKIP_BODY(el contenedor no debe procesar el cuerpo de la etiqueta) o Tag EVAL BODY INCLUDE ( l t id d l d b á d )Tag.EVAL_BODY_INCLUDE (el contenido del cuerpo deberá ser procesado)▪ public int doStartTag() throwsjavax.servlet.jsp.JspException
El contenedor llama a doEndTag, que devuelve bien Tag.SKIP_PAGE (no procesar el resto del JSP) o Tag.EVAL_PAGE(procesar el resto del JSP)▪ public int doEndTag throwsjava.servlet.jsp.JspException
l ()
93
Finalmente, el contenedor de JSPs llama al método release(), donde se pueden liberar recurso (cerrar conexiones)▪ public void release()
El contenedor devuelve la instancia del manejador de etiquetas a la pool para uso futuro
1) Crear el controlador de etiquetaqCrear la clase java que implementa el interfaz Tag (MiTag.java)
Creamos un nuevo subdirectorio llamando tags, que es el nombre del paquete que contiene la clase MiTags en el directorio classes del web‐infdel proyecto
94
del proyectoGrabamos HelloTag.java en el subdirectorio tags.Generamos el fichero .class
14/05/2007
48
2) Crear el descriptor de librería de etiquetas) p qFichero XML que define una librería de tags y sus etiquetas. Consta de:
Prólogo XML como todo documento XMLEl elemento raíz <taglib>, que tiene como sub‐elementos:▪ tlib-version versión de la librería de etiquetas▪ jsp-version la versión de JSP actualmente 2 0
95
jsp version la versión de JSP, actualmente 2.0▪ shortname nombre corto para la librería▪ description información para documentación▪ uri enlace a más información sobre tag library▪ tag elemento más importante, puede haber varios y tiene sub‐elementos
2) Crear el descriptor de librería de etiquetasd
p qPara cada tag:
name identificador de la etiqueta (obligatorio)tag-class nombre de la clase completo que realiza el procesamiento de esta etiqueta (obligatorio)tei-class clase de ayuda de esta etiquetabody-content el tipo de cuerpo de una etiqueta:▪ empty no hay cuerpo▪ JSP cuerpo es un conjunto de elementos▪ tagdependent cuerpo debe ser interpretado por la etiquetadescription
96
descriptionattribute: cero o más atributos que puede tener tres subelementos:▪ name (obligatorio)▪ required: true o false (valor por defecto false)▪ rtexprvalue: determina si el valor de este atributo se puede determinar en
tiempo de ejecución…
14/05/2007
49
2) Crear el descriptor de librería de etiquetasCrear fichero .tld, que guardamos en web‐inf/jsp o web‐inf/tlds
97
3) Probar la etiquetaReferenciar la etiqueta. Varias posibilidades:▪ Referenciar el .tld▪ <@ taglib uri="/WEB‐INF/jsp/mytaglib.tld" prefix="first" %>
▪ Referenciar un jar con la librería▪ <@ taglib uri="/WEB‐INF/myJARfile.jar" prefix='first" %>
98
▪ Definir el descriptor de etiquetas en el .tld<taglib>
<taglib‐uri>mytags</taglib‐uri><taglib‐location>/WEB‐INF/jsp/mytaglib.tld</taglib‐location>
</taglib>
14/05/2007
50
3) Probar la etiqueta, siguiendo enfoque 1.3) q , g qCreamos el jsp similar al siguiente
99
Problema: Muchos métodos incluso para petiquetas simplesSolución: Extender la clase abstracta TagSupporten vez de implementar Tag
Etiquetas parametrizadas: Manejo de atributos
100
atributosMétodo setAñadir una nueva etiqueta a mytagslib.tld
14/05/2007
51
.tld
.jsp
101
Extiende el interfaz Tag añadiendo un nuevo gmétodo doAfterBody, que puede devolver:Tag.SKIP_BODY el cuerpo se ignora y el contenedor llama a doEndTagIterationTag EVAL BODY AGAIN
102
IterationTag.EVAL_BODY_AGAINdoAfterBody es llamado de nuevo
14/05/2007
52
import javax.servlet.jsp.*;import javax.servlet.jsp.tagext.*;
public class PowerTag// d {
p g//extends TagSupport {implements IterationTag {
……..public int doStartTag() {
System.out.println("doStartTag");return EVAL_BODY_INCLUDE;
}
public int doAfterBody() {System.out.println("doAfterBody");counter++;result *= number;if (counter >= power)
return SKIP_BODY;else
return EVAL_BODY_AGAIN;}
public int doEndTag() throws JspException {System.out.println("doEndTag");
103
System.out.println( doEndTag );try {
JspWriter out = pageContext.getOut();out.println(number + "^" + power + "=" + result);this.counter = 0;this.result = 1;
}catch (Exception e) {}return EVAL_PAGE;
}}
A veces se necesita evaluar el cuerpo varias veces
Una Evaluación: Si el cuerpo necesita evaluarse sólo una vez, el controlador deetiqueta debería implementar el interface Tag, o extender la clase abstracta TagSupport; el método doStartTag necesita devolver EVAL_BODY_INCLUDE, y si no necesita ser evaluado en absoluto debería devolver BODY_SKIP.
Multiple Evaluación: Si el cuerpo necesita evaluarse varias veces, debería implementarse el interface BodyTag.
Extiende el interface Tag y define métodos adicionales (setBodyContent, doInitBody, y doAfterBody) que le permiten al controlador inspeccionar y posiblemente cambiar su cuerpo.
D f lt ti d t d l l B d T S t i
104
De forma alternativa, podemos extender la clase BodyTagSupport, que proporciona implementaciones por defecto para los métodos del interface BodyTag.
Típicamente, necesitaremos implementar los métodos doInitBody y doAfterBody. ▪ doInitBody es llamado después de que se haya seleccionado el contenido del cuerpo pero antes de que
sea evaluado▪ doAfterBody es llamado después de que el contenido del cuerpo sea evaluado.
14/05/2007
53
Extiende la IterationTag con 2 métodos
l d d l i bTiene un ciclo de vida similar a IterationTag, sin embargo:doStartTag puede devolver SKIP_BODY, EVAL_BODY_INCLUDE (el cuerpo se evalua como con IterationTag) o EVAL_BODY_BUFFERED(un objeto de tipo BodyContent es creado al cuerpo de la etiqueta personalizada)
public void setBodyContent(BodyContentbodyContent)
Llamado después de doStartTag, seguido de doInitBody, pero no se invoca si:▪ La custom tag no tiene cuerpo
105
La custom tag no tiene cuerpo▪ La custom tag tiene cuerpo pero doStartTag devuelve SKIP_BOBY o EVAL_BODY_INCLUDE
public void doInitBody() throwsjava.servlet.jsp.JspException
No se invoca si se cumple alguna de las mismas condiciones que para setBodyContent
Clases que implementan interfaces Tag, IterationTag y BodyTag: public class TagSupport implementsIterationTag, java.io.Serializable
public class BodyTagSupport extendsTagSupport implements Bodytag
106
Ahora sólo es necesario sobre‐escribir los métodos que quieran utilizarse en el procesamiento de custom tags
14/05/2007
54
107
108
14/05/2007
55
Cuando dos o más etiquetas personalizadas q pestán anidadas es posible obtener una referencia a la clase padre a través de findAncestorWithClass
Ejemplo:
109
Ejemplo:OuterTag1 parent1 = (OuterTag1)findAncestorWithClass(this, OuterTag.class);
La clase Tag Extra Info (TEI) se usa para permitir la creación de variables de scriptde variables de script.
Hay que definir en la clase TagExtraInfo el método getVariableInfo
Este método crea un array de objetos VariableInfo▪ Se creará uno de estos objetos por cada variable a definir, especificándose:
▪ Nombre variable▪ Clase de la variable
110
▪ Clase de la variable▪ Boolean indicando si habrá que crear una nueva variable▪ Scope de la variable:
AT_BEGIN variable disponible en interior etiqueta y el resto del JSPNESTED variable disponible en el interior de la etiquetaAT_END variable disponible en el resto del JSP
14/05/2007
56
import java.util.Collection;import java.util.Iterator;import javax.servlet.jsp.*;i t j l t j t t B d T S timport javax.servlet.jsp.tagext.BodyTagSupport;public class IteratorTag
extends BodyTagSupport {private Collection collection;private Iterator iterator;private PageContext pageContext;public void setPageContext(PageContext p) {
System.out.println("setPageContext");pageContext = p;
}public void setCollection(Collection collection) {
this.collection = collection;}
111
}public int doStartTag() throws JspException {
return collection.size() > 0 ? EVAL_BODY_BUFFERED : SKIP_BODY;}public void doInitBody() throws JspException {
iterator = collection.iterator();this.pageContext.setAttribute("item", iterator.next());
}
public int doAfterBody() throws JspException {if (iterator == null) {
iterator collection iterator()iterator = collection.iterator();}if (iterator.hasNext()) {
this.pageContext.setAttribute("item", iterator.next());return EVAL_BODY_AGAIN;
}else {
try {getBodyContent().writeOut(getPreviousOut());
}catch (java.io.IOException e) {
throw new JspException(e.getMessage());}
112
}return SKIP_BODY;
}}public void release() {
collection = null;iterator = null;
}}
14/05/2007
57
import java.util.Collection;import java.util.Iterator;import javax servlet jsp *;import javax.servlet.jsp.*;import javax.servlet.jsp.tagext.*;
public class IteratorTagInfo extends TagExtraInfo {public VariableInfo[] getVariableInfo(TagData data) {
return new VariableInfo[]{
new VariableInfo("item","java.lang.Object",true,VariableInfo.AT_BEGIN)
};}
}
113
}
<?xml version="1.0" encoding="ISO-8859-1"?><!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library
1.2//EN""htt //j /dtd/ b j t lib 1 2 dtd""http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">
<taglib><tlib-version>1.0</tlib-version><jsp-version>1.2</jsp-version><short-name/><tag>
<name>iterate</name><tag-class>IteratorTag</tag-class>
<tei-class>IteratorTagInfo</tei-class><body-content>JSP</body-content>
<!--<variable><name-given>item</name-given><name-from-attribute>item</name-from-attribute><variable-class>java.lang.String</variable-class><declare>true</declare><scope>AT_BEGIN</scope>
</variable>
114
</variable><attribute><name>id</name><required>true</required><rtexprvalue>true</rtexprvalue>
</attribute>--><attribute>
<name>collection</name><required>true</required><rtexprvalue>true</rtexprvalue>
</attribute></tag>
</taglib>
14/05/2007
58
<html><head><title>An Iterator</title></head>
<%@ taglib uri="/myTLD" prefix="it"%><%@ taglib uri= /myTLD prefix= it %><body><%java.util.Vector vector = new java.util.Vector();vector.addElement("one");vector.addElement("two");vector.addElement("three");vector.addElement("four");%>
Iterating over <%= vector %> ...
<p><it:iterate collection="<%=vector%>">
115
Item: <%= item %><br></it:iterate></p></body></html>
Hasta JSTL V i d d d lib í It b l i i i i Variedad de librerías para Iterar sobre colecciones, imprimir valores de propiedades de JavaBeans de forma segura, internacionalización de mensajes, números, fechas, generación de URLs aplicando URL rewriting, acceso a documentos XML, Etc
JSTL: Librería estándar de tagsObjetivo: Simplificar y agilizar el desarrollo de aplicaciones web
116
Requiere conocimientos básicos de Java, JSP y aplicaciones webCualquier aplicación que use JSTL, debe copiar los fichero .tld al directorio WEB‐INFSe debe especificar en el web.xml la ubicación de los ficheros
14/05/2007
59
117
CoreControl de flujoControl de flujoSoporte para URLs
I18nSoporte para internacionalización: establecimiento del Locale, generación de mensajes, formateo de números, cantidades monetarias, fechas, etc.
XMLParsing de un documento XMLFlujo de control para recorrer un documento XML (alternativa a XSL para casos sencillos)Tags para lanzar transformaciones XSL
118
Tags para lanzar transformaciones XSLAcceso a BDs
Permiten lanzar sentencias SQL a BDs relacionales (prototipado rápido o aplicaciones muy simples)
FuncionesJSP 2.0 define un mecanismo para añadir funciones al lenguaje de expresiones
14/05/2007
60
En toda página JSP hay que declarar la biblioteca a la que pertenece cada ti t etiqueta que usemos.
Declaraciones en un fichero aparte, y luego incluir dicho fichero en nuestras páginas JSP.
$CATALINA_HOME/webapps/miAplicacion/taglibs.jsp
119
$CATALINA_HOME/webapps/miAplicacion/index.jsp: importe la anterior usando una directiva include
Antes de JSTL, JSP usaba Java para referenciar atributos dinámicos. Con JSTL ya no es necesario.JSTL ya no es necesario.<%‐‐ con JSP ‐‐%>
<%= request.getParameter("login") %><%‐‐ con JSTL ‐‐%>${param.login}
Podemos usar expresiones en cualquier parte del documento, o como valores de los atributos de etiquetas JSTL, exceptuando los atributos vary scope, que no aceptan expresiones.
P d l d b j l d l ió
120
Para acceder al campo de un bean java, o a un elemento de una colección (array, o Map), se usa el operador punto, o el operador corchete:
${bean.propiedad}${map.elemento}${header['User‐Agent']}
14/05/2007
61
Para utilizar una librería en una página JSP hay que importarla:<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
El atributo uri debe corresponder con alguna de las URIs estándares de JSTL.
El atributo prefix puede establecerse con cualquier valor, aunque para las librerías JSTL existe una convención: c, fmt, sql y xml.
Ya podemos utilizar la etiquetas en la página:
121
p q p g<c:out value=“primer ejemplo” />
La etiqueta c:out incluye caracteres de escape para los símbolos especiales de XML: <, >, &
En los atributos de las etiquetas podemos establecer un valor literal o el resultado de una expresión JSTL:p<c:out value=“${1 + 2}” />Tipos de Expresiones:
Aritméticas : ${ 1 + 2 }Operaciones lógicas: ${(3 >= 2) && (2 > 1)}, ${ ‘a’ < ‘b’}Acceso a variables: ${ nombre == ‘Juan’}Acceso a propiedades de variables: ${usuario.edad}Acceso a colecciones: ${items[3].precio} a partir de 0
122
p pConsultar si existe una variable: ${not empty nombre}
Se realiza automáticamente coerción de tipos si fuera necesario:<c:set var=“nombre” value=“5” /> el tipo es String<c:out value=“${nombre == 5}” /> devolvería true
14/05/2007
62
Resolución de variables:Busca el nombre de la variable, por orden, en los siguientes alcances: page, request, session, application.q , , ppPodemos explícitamente indicar el alcance donde queremos que busque: ${requestScope.usuario}
El acceso a las propiedades de una variable sigue la convención de los componentes Java: JavaBeans
${usuario.edad} la variable “usuario” es un objeto que ofrece un método getEdad() para el acceso a la propiedad.
d d l á d l ó
123
Podemos acceder a los parámetros de la petición:${param.nombre}${paramValues.respuesta[3]} campo multivaluado
124
14/05/2007
63
Accesibles desde cualquier etiqueta JSPq q
125
126
14/05/2007
64
127
128
14/05/2007
65
Etiquetas para iterar sobre datos, q p ,operaciones condicionales e importación de datos de otras páginas
129
Mostrar el resultado de una expresiónp
130
14/05/2007
66
Asignación de valoresg
131
Eliminar una variable
132
14/05/2007
67
133
Tipo “switch”p
134
14/05/2007
68
Arrays de objetos o tipos primitivos.y j p p
Instancias de java.util.Collection, java.util.Map, java.util.Iterator, java.util.Enumeration.
C d d li i d
135
Cadenas delimitadas por comas.
Instancias de javax.servlet.jsp.jstl.sql.Result(resultantes de una consulta SQL con JSTL)
Recorrido de una colección:<c:forEach items=“${paramValues.opciones}” var=“opcion”>
O ió l “${ i }” / /<p>Opción: <c:out value=“${opcion}” /> </p>
</c:forEach>
Podemos controlar el comienzo, final y paso del recorrido con los atributos: begin, end y step.
El atributo varStatus permite definir una variable con la que controlar el estado del recorrido:
varStatus=“estado” …
136
estado.index, estado.count índice en la colección o iteración
estado.first, estado.last indica si es la primera o última iteración
Si sólo se indican los valores de los índices, simula un bucle for.
14/05/2007
69
137
Descomponer una cadena en tokensp
138
14/05/2007
70
Como jsp:include + incluir páginas de otros servidores y guardar texto en i bluna variable
139
Parámetros a pasar al c:importp p
140
14/05/2007
71
Como jsp:forwardj p
141
Mostrar o grabar en una variable una URL, g ,admite c:param
142
14/05/2007
72
Captura de errores.p
143
JSTL ofrece la librería SQL para el acceso a bases de datos relacionales.
En general, se recomienda “no mezclar” el código de la interfaz de una aplicación (HTML, JSP) con la lógica de la aplicación (acceso a bases de datos).
Sin embargo, para aplicaciones sencillas y prototipos resulta interesante su uso.
144
Es recomendable utilizar una fuente de datos ofrecida por el servidor JSP, ya que al menos se garantiza un acceso eficiente a la base de datos.
14/05/2007
73
Definido en server.xml
145
Definido en web.xml de la aplicación
146
14/05/2007
74
Ejemplo
147
sql:datasourceq
148
14/05/2007
75
Etiqueta <sql:query … />
<sql:query dataSource=“jdbc/ejemplo” var=“datos”>SELECT nombre, edad FROM Usuario
</sql:query>
La consulta trabaja con la fuente de datos “jdbc/ejemplo”.
La variable var contiene el resultado de la consulta en las siguientes propiedades:
149
rows: registros cuyas columnas se acceden por nombre.rowsByIndex: registros con acceso por índice.columNames: nombres de las columnas.rowCount: número de registros resultado.
Normalmente, los resultados se procesan en un bucle:
<c:foreach items=“${datos.rows}” var=“registro”>… <c:out value=“${registro.edad}” /> …
</c:foreach>
Listados: En una página que genere un listado, los datos deberían presentarse por páginas
Es necesario controlar los registros resultado de la consulta
150
Solución: la etiqueta <sql:query> ofrece los atributos startRow y maxRows para controlar los registros obtenidos.
14/05/2007
76
151
152
14/05/2007
77
Consulta actualización: etiqueta <sql:update … >/<sql:update dataSource=“jdbc/ejemplo” var=“resultado”>
DELETE FROM Usuario WHERE codigo = 1
</sql:update>
En la variable var se obtiene el número de registros afectados por la consulta.
Consultas con parámetros: Definimos un parámetro en la consulta con ?
153
Definimos un parámetro en la consulta con ?Establecemos un parámetro con:<sql:param value=“…” />Son importantes para que los datos sean formateados correctamente en la consulta, especialmente para fechas y números reales.
154
14/05/2007
78
155
156
14/05/2007
79
fmt:bundle
157
158
14/05/2007
80
Parámetros para fmt:messagep g
159
Cargar mensajes de recursos específicosg j p
160
14/05/2007
81
161
fmt:FormatNumber
162
14/05/2007
82
163
164
14/05/2007
83
Al igual que las fechas, para introducir un valor real a una base de datos conviene procesarlo previamente.p pEn JSTL y Java el punto decimal es “.”, pero en español es “,”La etiqueta <fmt:parseNumber> resuelve el problema:<fmt:parseNumber value=“${param.superficie}”
var=“superficie” />En función del idioma del navegador asume el separador decimal y lo convierte a real.Cuando se establece el parámetro en la consulta, el real se transforma
165
Cuando se establece el parámetro en la consulta, el real se transforma adecuadamente al formato de la base de datos.Para mostrar un valor real, la etiqueta <fmt:formatNumber value=“…” />muestra correctamente el valor.
<fmt:parseNumber
166
<fmt:parseNumbertype="type" pattern="expression"parseLocale="expression"integerOnly="expression"var="name" scope="scope">
body content</fmt:parseNumber>
14/05/2007
84
Es importante procesar los parámetros que contienen fechaspara introducirlos en una consulta parametrizada.L lib í f t f f h La librería fmt ofrece soporte para procesar una fecha y mostrarla.Procesamiento:<fmt:parseDate pattern=“dd’/’MM’/’yyyy”
value=“${param.fecha}” var=“fecha” />La variable “fecha” contiene el resultado.P t l d i bti f h d l b d d t
167
Por otro lado, si se obtiene una fecha de la base de datos podemos mostrarla:<fmt:formatDate value=“${registro.fecha}”
pattern=“’a’ dd ‘de’ MMMM ‘de’ yyyy” />
<fmt:parseDatet "fi ld"type="field"
dateStyle="style" timeStyle="style"
pattern="expression"timeZone="expression"
parseLocale="expression"var="name"
168
var name scope="scope">body content
</fmt:parseDate>
14/05/2007
85
El soporte de XML que lleva a cabo JSTL p qconforma con la especificación XPath.
Xpath provee una sintaxis clara para acceder a partes jerárquicas de un documento.
i ili d i
169
c:import es utilizada para importar un documento, mientras x:parse para genera un árbol DOM a partir de él. x:set crea una variable a partir de un extracto de XML
170
14/05/2007
86
Forma de extender la funcionalidad del lenguaje de expresiones, veremos las de manejo de cadenas
fn: contains: Si una cadena contiene a otra
171
fn:containsIgnoreCaseg
fn:endsWith
172
14/05/2007
87
fn:escapeXML (string) Codifica los caracteres p ( g)que podrían ser interpretados como parte de etiquetas XML
fn:indexOf (string, substring) ‐1 si no está
173
fn:join (array, separator): string
fn: length : integer
fn:replace (inputString, p ( p g,subcadena_a_cambiar, nueva_subcadena) String
fn: split (string, separador): string []
174
fn:startsWith(string, prefix): boolean
fn:substring(string, inicio, fin): string
14/05/2007
88
fn:substringAfter(string, subcadena): stringg ( g, ) g
fn:substringBefore(string, substring): string
fn:toLowerCase(string): string
175
fn:toUpperCase(string): string
fn:trim(string): string
La ejecución de una página JSP puede estar parametrizada.P j l d í t á i JSP ib á t Por ejemplo, se podría tener una página JSP que reciba como parámetro el código de un registro de la base de datos y que visualice sus datosAdemás, la recepción de parámetros es la clave para el procesamiento de formularios:
Los campos de un formulario se pasan como parámetros a una página JSP.Hay dos modos para la recepción de parámetros:
Enviados en el cuerpo de la petición HTTP utilizando el método POST. En general, enviado por formularios.
176
g , pEstablecidos en la URL que invoca a la página JSP:pagina.jsp?codigo=1&nombre=Juan
14/05/2007
89
El lenguaje de expresiones de JSTL permite el acceso a los parámetros a través del objeto “param”:p j p
<c:out value=“${param.codigo}” />
En el caso de parámetros multivaluados, como un grupo de casillas de chequeo, el objeto se llama “paramValues” y se accede a los valores por índice:
177
<c:out value=“${paramValues.interiores[0]}” />
Tradicionalmente, procesar un formulario implica crear una página JSP para:para:
Validar todos los campos en la página JSP (otra vez!)Si todo es correcto, insertar los datos en la base de datos.En caso de error, volver a generar el formulario con los campos rellenos y mostrar mensajes de error.
178
Con esta estrategia es conveniente que el formulario sea una página JSP que se procese a sí mismaAunque esta estrategia es común, resulta poco intuitiva e implica una duplicidad de validaciones.
14/05/2007
90
Una estrategia práctica, aunque no del todo fiable, es controlar si en el navegador se han validado los campos con JavaScriptnavegador se han validado los campos con JavaScript.
Basta con declarar un campo oculto que sea actualizado si la validación antes del envío ha sido correcta.
Al procesar el formulario, si el campo oculto tiene un valor no actualizado, la causa es que no está activo JavaScript.
Por tanto, se muestra un mensaje de error y se ofrece un enlace para
179
, j y pvolver atrás y activar JavaScript para validar y enviar los datos.
Problema: siempre es posible “trucar” un envío HTTP POST y modificar el campo oculto de manera que parezca que se ha validado.
Utilizando las etiquetas <sql:query>, <c:forEach>, etc. es posible construir cualquier listadoconstruir cualquier listado.
No obstante, si el listado debe ser paginado hay que tener en cuenta:La página JSP del listado tendrá un parámetro que representa el índice del primer elemento de la página actual.La consulta <sql:query> ofrece los atributos startRow para indicar el índice del primer elemento y maxRows para limitar los resultados por página.Por último, utilizando el valor rowCount de una consulta no limitada es posible construir el índice de las páginas.
180
p p g
Si el listado debe ser ordenado, basta con añadir un nuevo parámetroque indique el valor del orden, por ejemplo “nif=asc”, y componer la cadena de consulta para que ordene los resultados según los criterios esperados.
14/05/2007
91
Problema:HTTP es un protocolo sin estado.Es decir, cada petición de un recurso a un servidor es independiente.Sin embargo, las aplicaciones web necesitan conocer que usuario(navegador) hace una petición y asociar información al usuario.Por ejemplo, tras una identificación, recordar el identificador.Otro ejemplo, en aplicaciones de comercio electrónico, llevar un carro de la compra.
181
de la compra.Solución:
Los servidores web implementan el concepto de sesión web.
Tradicionalmente, se ha podido controlar el estado de la navegación l d kiutilizando cookies.
Una cookie es un fragmento de texto que una aplicación web envía a un navegador con el compromiso de que lo devuelva en futuras peticiones a la aplicación.De este modo tan primitivo, es posible recordar el estado de una navegación pasado el tiempo.Por ejemplo, muchas aplicaciones web recuerdan la identificación
182
durante días utilizando cookies.Hay dos tipos de cookies:
Las que tienen un tiempo de vida definido.
Las que están vinculadas a la ejecución del navegador (cookies de sesión).
14/05/2007
92
Las tecnologías de soporte web como JSP, PHP o ASP han ili d l ki d ió l ió utilizado las cookies de sesión para crear el concepto sesión
web.Para cada nuevo navegador (usuario) que accede a una aplicación web, se crea una cookie de sesión con un identificador único que se envía al navegador.Cada vez que el navegador hace una petición de una página envía el identificador en la cookie.
183
El navegador maneja una estructura de datos que permite a las páginas JSP almacenar información para la sesión de navegación:
Variables registradas con alcance de sesión.
Problema:Las cookies se ven como un riesgo para la privacidad.Las cookies se ven como un riesgo para la privacidad.La mayoría de los navegadores permiten desactivar las cookies.
Solución:El identificador de sesión que se envía en la cookie, puede ser conseguido se si inserta como parámetro de todas las URL de los vínculos de toda la aplicación (!!).Tradicionalmente, dar soporte a este problema ha sido costoso.A t l t l ti t l d JSTL d b tili
184
Actualmente, la etiqueta <c:url> de JSTL debe utilizarse para componer todas las URL, ya que controla si están activas las cookies para insertar automáticamente el parámetro de sesión.
14/05/2007
93
JSTL no tiene soporte para el envío de cookies.E i i l i l ódi J bl kiEs necesario incluir el código Java para establecer una cookie:<%Cookie cookie = new Cookie(“login”,
session.getAttribute(“login”));cookie.setMaxAge(3600); // en segundosresponse.addCookie(cookie);%>
185
%>Recuperación de cookies en JSTL utilizando el array “cookie” indexado por clave:${cookie[‘login’].value}
Actualmente para el desarrollo web con Java se utiliza Java Server Faces (JSF)Faces (JSF).Aún se siguen utilizando frameworks web como Struts, WebWorko Tapestry que favorecen notablemente el desarrollo web.En una aplicación web no se suele acceder directamente a una base de datos. Se usan frameworks Objeto/Relacional como Hibernate.Si la aplicación requiere servicios como transacciones, seguridad, etc. el framework Spring facilita sensiblemente el desarrollo.
186
p gAdemás, Spring simplifica el acceso a los datos y la integración con frameworks web.Librerías de componentes AJAX: Rico, Prototype, etc.