1. Curso:
Programación Web con Tecnología Java
Enero 2008 V1.0
2. CORT412: Programación Web con Tecnología Java
Índice
1. Introducción
2. Contenedores Web
3. Entorno de trabajo
4. Tecnología Java Servlets
5. Sesiones
6. Modelo Vista Controlador
7. Tecnología JavaServer Pages
8. Opciones Avanzadas
3. CORT412: Programación Web con Tecnología Java
1. Introducción
1.1. Objetivos del curso
1.2. Un poco de historia
1.2. El protocolo HTTP
1.3. Concepto de URL
1.4. Componentes para capa de presentación y
lógica de negocio.
4. 1. Introducción
1.1. Objetivos del curso
Lo que pretendemos con este curso es ser capaces de:
· Desarrollar aplicaciones Web usando tecnología Java: Servlets y JSP’s.
· Conocer los principios del patrón de diseño MVC y desarrollar aplicaciones robustas que sean
capaces de gestionar sesiones y controlar eficazmente los errores.
· Desarrollar aplicaciones seguras cuando sea necesario.
· Desarrollar aplicaciones que puedan ser usadas a la vez por múltiples usuarios.
Además, durante el curso aprenderemos:
· Cómo trabajar con el entorno de desarrollo Eclipse.
· Cómo trabajar con el servidor de aplicaciones Web Tomcat.
· Cómo trabajar con bases de datos cuando desarrollamos en tecnología Java.
· Cómo desarrollar una aplicación web siguiendo el patrón de MVC.
5. 1. Introducción
1.2. Un poco de Historia
La arquitectura de software de los últimos años ha ido evolucionando a la vez que la tecnología
informática.
Se comenzó con los sistemas monolíticos donde el sistema sólo conocía su entorno de operación.
Con la aparición de las redes, surgió el sistema Cliente – Servidor, que es el que permite que un sistema
interactúe con otros sistemas.
6. 1. Introducción
1.2. Un poco de Historia (II)
Con Internet llegó el desarrollo de software por componentes, lo que permitía tener una aplicación
distribuida con varios servidores y clientes ligeros, pero el contenido de las páginas era estático.
Para solucionar el problema del dinamismo aparecieron los Servlets y jsp, permitiendo separar las
funciones de negocio con las de presentación.
Aparece la programación en capas, con objeto de incluir la mayor parte de lógica posible en el servidor,
para que la funcionalidad del cliente sea simplemente de presentación.
El objetivo es dividir la funcionalidad en capas lógicas que se encapsulan como componentes que
interactúan entre ellos a alto nivel.
La programación en capas más utilizada es la de tres capas:
• Funciones de BBDD en la capa de Base de Datos.
• Lógica de operación en la capa de Negocio.
• Funciones de interfaz de usuario en la capa de Presentación.
8. 1. Introducción
1.2. Un poco de Historia (IV)
Ventajas del sistema de capas:
• Realización de cambios sin tener que modificar toda la aplicación.
• Mayor portabilidad de las aplicaciones.
• Mayor escalabilidad a la aplicación.
Inconvenientes:
• Mayor esfuerzo de diseño.
• Mayor complejidad entre los componentes y la interacción entre ellos.
9. 1. Introducción
1.2. El protocolo HTTP
Es el protocolo de comunicación más utilizado en las aplicaciones web.
Es un protocolo de alto nivel, que se asienta sobre TCP/IP.
Se desarrolla con la intención de realizar intercambios de información basados en enlaces (hipertexto e
hipermedia) y en marcas de presentación (tags).
Las comunicaciones HTTP tienen dos partes: la petición y la respuesta. Una respuesta HTTP puede ser un
documento de cualquier tipo, aunque lo más habitual es que sea una página HTML.
No es un protocolo permanente. Esto quiere decir que una vez que se transmite una petición, la
conexión se destruye, e igualmente ocurre cuando se transmite una respuesta.
Los Métodos que definen este protocolo son:
• HTTP Request
• HTTP Response
10. 1. Introducción
1.3. Concepto de URL
Una URL es una cadena con un formato especial que nos permite localizar un recurso en cualquier
ordenador accesible mediante el protocolo TCP/IP.
Fijémonos en la siguiente URL:
http://www.servidor.org:7654/contexto/ruta/recurso?param1=valor1¶m2=valor2
Las partes que la componen son las siguientes:
· El protocolo: http
· El ordenador: www.servidor.org
· El puerto: 7654
· El contexto/aplicación: contexto
· La ruta de acceso al recurso: ruta
· El nombre del recurso: recurso
· Parámetros que pasamos al recurso: param1=valor1¶m2=valor2
11. 1. Introducción
1.4 Componentes para la capa de presentación y lógica de
negocio (I)
Un servlet es un componente web manejado por un contenedor que genera un contenido dinámico.
Es un programa que se ejecuta en un servidor Web y genera una página Web dinámicamente.
Un servlet es la respuesta java a la tecnología CGI.
La construcción de páginas web dinámicamente es muy útil en los siguientes casos:
• El contenido de la página es a petición del cliente.
• Los datos cambian constantemente.
• La página web utiliza la base de datos corporativa u otras fuentes.
12. 1. Introducción
1.4 Componentes para la capa de presentación y lógica de
negocio (II)
La principal diferencia entre Servlet y CGI es que un servlet siempre tiene una copia de la clase
instanciada y N thread que acceden a él. En el caso del CGI se instancia una copia de la clase cada vez
que se invoca al programa.
Las ventajas de los servlets sobre los CGIs son:
• Eficiencia
• Flexibilidad
• Portabilidad
13. 1. Introducción
1.4 Componentes para la capa de presentación y lógica de
negocio (III)
JSP (Java Server Pages) es una página que combina código HTML o XML con código Java para conseguir
páginas dinámicas.
Cada página se compila como si fuese un servlet cuando se invoca y a continuación se ejecuta.
Las ventajas de un Jsp son:
• Sobre ASP: La parte dinámica está escrita en Java y es portable a otros sistemas operativos,
mientras que ASP está escrito en Visual Basic.
• Sobre Servlets: Es más cómodo de modificar porque está escrito con HTML.
• Sobre JavaScript: El lenguaje JavaScript permite dar un dinamismo a la página web, pero sólo a
nivel del cliente. No puede acceder a la parte del servidor, por lo que es imposible que acceda a la
base de datos y otros recursos.
14. CORT412: Programación Web con Tecnología Java
2. Contenedores Web
2.1. Métodos del protocolo HTTP
2.2. Contenedores y Aplicaciones Web
2.3. Estructura de una aplicación Web
2.4. Deployment Descriptor
2.5. Tipos de contenedores web
15. 2. Contenedores Web
2.1. Métodos del protocolo HTTP (I)
Los métodos principales de HTTP Request son:
• Get: Es el método más simple y más utilizado para la petición de los recursos estáticos.
Cuando se utiliza para pedir recursos que se generan dinámicamente se le pasan parámetros
de entrapara para obtener la respuesta.
Transmite los parámetros como cadena concatenada en la URL.
La forma de la URL con el método get es:
http://www.dominio.com?parametro1=valor1
El inconveniente es que algunos navegadores limitan el tamaño de la URL.
• Post: Es el más usado para obtener recursos generados de forma dinámica, subir ficheros al
servidor, etc.
Los parámetros se pasan en el cuerpo de la petición y ofrece una mayor elección del
contenido de la petición.
16. 2. Contenedores Web
2.1. Métodos del protocolo HTTP (II)
El método HTTP Response, contiene el estado de la respuesta y la información que describe la
respuesta.
La cabecera de la respuesta lleva el estado.
El cuerpo de la respuesta lleva el contenido.
En HTTP, servidores y clientes usan MIME (Multi-Purpose Internet Mail Extension) para indicar el
tipo de contenido en la petición y la respuesta.
Ejemplo: text/html
La primera parte indica el tipo de respuesta.
La segunda parte indica la extensión estándar.
Los servidores HTTP emplean cabeceras MIME al inicio de cada transmisión.
Los navegadores emplean dicha información para decidir como mostrar el resultado de la petición.
17. 2. Contenedores Web
2.2. Contenedores y Aplicaciones Web (I)
Para generar aplicaciones web tenemos los siguientes elementos:
• Servlets y Jsp’s: Son los componentes web básicos para crear una aplicación web.
• Aplicaciones Web: Es un conjunto de componentes web y de recursos estáticos.
• Contenedor Web: Es un entorno de ejecución creado en java, en el que están contenidos
todos los componentes web y las librerías necesarias para que funcione la aplicación.
• Descriptor de despliegue: Es un fichero xml que contiene la descripción de configuración
de cada aplicación web.
18. 2. Contenedores Web
2.2. Contenedores y Aplicaciones Web (Servlets) (II)
Los servlets son pequeños programas, independientes de la plataforma, que residen en un servidor
y que permiten extender la funcionalidad de un servidor web mediante programación.
Están escritos 100% en java.
Se definen en la especificación Java Servlet API 2.2 / 2.3 que se encuentra en
http://java.sun.com/products/servlet.
Un servlet se invoca por el contenedor web en el que esté desplegada la aplicación.
El contenedor web es el que enlaza las peticiones web del usuario con los servlets desplegados.
19. 2. Contenedores Web
2.2. Contenedores y Aplicaciones Web (JSP) (III)
Los Jsp’s son los encargados de generar contenido dinámico basado en plantillas.
Los Jsp’s son documentos basados en texto. Se componen de dos partes:
1. HTML o XML que forman el contenido estático
2. Etiquetas JSP y pequeños scripts escritos en Java para el contenido dinámico.
La principal ventaja sobre los servlets es que permiten separar la parte lógica de negocio que es
100% java (Servlet), de la parte lógica de presentación (HTML).
20. 2. Contenedores Web
2.3. Estructura de una aplicación Web
Una Aplicación Web se crea con los siguientes componentes:
1. Un directorio Público.
1. Contiene los recursos públicos tal como HTML, imágenes, páginas Jsp o documentos
que maneja la aplicación.
2. Un directorio /WEB-INF. Directorio privado al que no puede acceder el usuario.
1. El fichero web.xml.
2. Un directorio classes que contiene las clases compiladas.
3. Un directorio lib con todas las librerías de la aplicación.
21. 2. Contenedores Web
2.4. Deployment Descriptor (I)
Es el fichero que define la configuración del despliegue de una aplicación web.
En los contenedores web es un fichero llamado web.xml, que se almacena en el directorio
/WEB-INF de la aplicación.
El descriptor de despliegue se utiliza para:
• Inicialización de parámetros, tanto de servlets como de la aplicación.
• Definición de Servlets y Jsps.
• Mapeo de Servlets y Jsps.
• Tipos MIME.
• Seguridad.
22. 2. Contenedores Web
2.4. Deployment Descriptor (II)
El fichero web.xml contiene la configuración de la aplicación.
A continuación describiremos los elementos más importantes según la versión 2.4 de la especificación:
ELEMENTO DESCRIPCIÓN
<web-app> Elemento raíz de la aplicación.
<display-name> Define un nombre que identifica la aplicación. Es opcional.
<description> Incluye una descripción de la aplicación. Es opcional.
<context-param> Define, opcionalmente, parámetros de inicialización del contexto. Se puede repetir.
<filter> Define un filtro. Tantos <filter> como filtros hayamos definido.
<filter-mapping> Indica cada filtro sobre qué recursos se aplica.
<servlet> Define un servlet.
<servlet-mapping> Indica qué URL’s se utilizarán para invocar a un servlet determinado.
<session-config> Define parámetros de la sesión.
<mime-mapping> Indica en una aplicación tipos MIME distintos a los que el contenedor tiene configurados.
<welcome-file-list> Establece la lista de ficheros que se utilizarán como páginas de bienvenida.
<error-page> Define manejo de errores a nivel del contenedor.
<jsp-config> Define librerías de tag.
24. 2. Contenedores Web
2.5. Tipos de contenedores web
Existen tres maneras de configurar un Contenedor Web:
1. Contenedor Web en un servidor de Aplicaciones Web.
2. Contenedor Web desarrollado en el Servidor Web.
3. Contenedor Web en un entorno de ejecución separado.
25. CORT412: Programación Web con Tecnología Java
3. Entorno de trabajo
3.1. Herramientas que vamos a utilizar
3.2. Instalación del SDK de Java (JDK)
3.3. Instalación de Tomcat
3.4. Instalación de OracleEX
3.5. Instalación de Eclipse
3.6. Primera aplicación web
26. 3. Entorno de trabajo
3.1. Herramientas que vamos a utilizar
Durante el curso utilizaremos las herramientas que indicamos a continuación:
Como máquina virtual y compilador Java utilizaremos:
· Java 2 SDK Standard Edition v1.5.0 revisión 06 (JDK)
Como entorno de desarrollo integrado utilizaremos Eclipse con algunos plug-ins:
· Eclipse IDE v3.2
Como servidor de aplicaciones Web utilizaremos:
· Apache Tomcat v5.5 (con el módulo de compatibilidad con JDK 1.5.x)
Y finalmente, como motor de base de datos:
· OracleEX
27. 3. Entorno de trabajo
3.2. Instalación del SDK de Java (JDK)
Para instalar el SDK de Java simplemente debemos ejecutar el fichero jdk-1_5_0_06-windows-i586-p y
seguir las instrucciones en pantalla.
Debemos tomar nota del directorio en que instalamos el SDK pues deberemos crear una variable de
entorno de nombre JAVA_HOME cuyo valor sea el directorio donde está instalado el SDK. Por ejemplo,
podemos instalar el JDK en la ruta c:javajdk-1.5.0 o en la ruta por defecto.
28. 3. Entorno de trabajo
3.3. Instalación de Tomcat
Para instalar Tomcat debemos descomprimir el fichero apache-tomcat-5.5.25 en un directorio de
nuestra elección. Podemos utilizar, por ejemplo, el directorio c:tomcat5.5 de forma que la instalación
se realice en el directorio c:tomcat5.5jakarta-tomcat-5.5.25.
Una vez descomprimido el fichero deberemos crear una variable de entorno de nombre CATALINA_HOME
cuyo valor sea el directorio donde está instalado Tomcat. Esta versión lo crea por defecto.
Modificamos el puerto por el que va a escuchar el servidor, ya que la administración de BBDD que vamos
a instalar escucha en el mismo puerto.
Para ello modificamos el fichero server.xml que está en el directorio C:tomcat5.5apache-tomcat-
5.5.25conf . Modificamos las siguientes líneas:
<Connector port="8080" maxHttpHeaderSize="8192"
por
<Connector port="8085" maxHttpHeaderSize="8192"
29. 3. Entorno de trabajo
3.4. Instalación de OracleEX
Como motor de base de datos vamos a utilizar OracleEX.
Hacemos doble clic sobre el programa y le indicamos la ruta donde queremos instalarlo.
Nos pide introducir una contraseña. Esta password es la que se va a utilizar con el usuario System.
A continuación pulsamos Aceptar y comienza la instalación de la BBDD.
La página de la administración de la BBDD es: http://127.0.0.1:8080/apex
30. 3. Entorno de trabajo
3.5. Instalación de Eclipse (I)
Para instalar Eclipse debemos descomprimir el fichero wtp-all-in-one-sdk-R-1.5.5-200708291442-
win32 a un directorio de nuestra elección. Por ejemplo, podemos utilizar el directorio c:eclipse de
forma que la instalación se realice en el directorio c:eclipse.
Este fichero lleva todos los plug-ins estándar de Eclipse necesarios para permitirnos gestionar tanto el
servidor web que hemos instalado como la BBDD.
Si lo deseamos, podemos crear un acceso directo en el escritorio al fichero eclipse.exe que se encuentra
donde hemos descomprimido Eclipse.
El paso siguiente es configurar el servidor web y la BBDD dentro de Eclipse.
31. 3. Entorno de trabajo
3.5. Instalación de Eclipse (II)
Asignar el servidor web a Eclipse:
32. 3. Entorno de trabajo
3.5. Instalación de Eclipse (III)
Asignar de la BBDD a Eclipse:
33. CORT412: Programación Web con Tecnología Java
4. Tecnología Java Servlets
4.1. El API Java Servlets
4.2. El Ciclo de vida de un Servlet
4.3. Configuración de un servlet
4.4. Contexto de un Servlet
4.5. Otras clases de interés
4.6. La clase HttpServlet
4.7.Concurrencia
4.8. Interacción entre HTML y Servlets
4.9. Colaboración entre servlets
34. 4. Tecnología Java Servlets
4.1. El API Java Servlets (I)
El API Java Servlets es el conjunto de clases e interfaces que nos permite interactuar con peticiones
HTTP y generar las respuestas.
Con el API podremos crear clases que actuarán como servlets, acceder a la información de la petición y
controlar la respuesta que estamos generando.
Si queremos consultar o descargar las especificaciones, o los API’s, podemos hacerlo en la web:
http://java.sun.com/products/servlets
http://java.sun.com/products/jsp
La API Java Servlets se especifica en dos paquetes que son:
javax.servlet
javax.serlvet.http
35. 4. Tecnología Java Servlets
4.1. El API Java Servlets (II)
Tabla de clases e interfaces principales del API Java Servlet:
PROPOSITO CLASE/INTERFACE
Implementación de servlet javax.servlet.Servlet
javax.servlet.SingleThreadModel
javax.servlet.GenericServlet
javax.servlet.http.HttpSerlvet
Configuración del servlet javax.servlet.ServletConfig
Servlet Exceptions javax.servlet.ServletException
javax.servlet.UnavailableException
Peticiones y Respuestas javax.servlet.ServletRequest
javax.servlet.ServletResponse
javax.servlet.ServletInputStream
javax.servlet.ServletOutputStream
javax.servlet.http.HttpSerlvetRequest
javax.servlet.http.HttpServletResponse
Gestión de la sesión javax.servlet.http.HttpSession
javax.servlet.http.HttpSessionBindingListener
javax.servlet.http.HttpSessionBindingEvent
Contexto del Servlet javax.servlet.ServletContext
Colaboración entre Servlets javax.servlet.RequestDispatcher
36. 4. Tecnología Java Servlets
4.1. El API Java Servlets (III)
La tabla anterior divide las clases e interfaces principales del API Java Servlet en las siguientes
categorías:
• API para la implementación de servlets.
Lo más común es que un servlet extienda de las clases javax.servlet.GenericServlet o
javax.servlet.http.HttpSerlvet
• Configuración de servlets.
Permitir acceder al objeto ServletConfig
• Excepciones lanzadas por los servlets.
Las excepciones son javax.servlet.ServletException y javax.servlet.UnavailableException
• API para peticiones y respuestas.
Permiten leer los datos de entrada y generar una respuesta al cliente
• Contexto del servlet.
La interfaz javax.servlet.ServletContext permite compartir datos entre servlets.
• Colaboración entre servlets.
Permite a un servlet invocar a otro servlet.
37. 3. Tecnología Java Servlets
4.1. El API Java Servlets (IV)
Cómo crear una clase Java para que se comporte como un servlet.
1. Crear una clase que extienda a la clase javax.servlet.http.HttpServlet.
2. Sobreescribir el método doGet(javax.servlet.http.HttpServletRequest,
javax.servlet.http.HttpServletResponse).
El proceso general que seguiremos al diseñar un método doGet() es el siguiente:
• Primero leemos los datos de la petición.
• Escribimos las cabeceras de la respuesta.
• Obtenemos el objeto donde escribimos la respuesta y escribimos los datos de la
respuesta.
Es recomendable siempre informar la cabecera con el tipo MIME del contenido; de esta forma el
navegador puede escoger la mejor manera de presentar el documento de respuesta.
38. 4. Tecnología Java Servlets
4.2. El ciclo de vida de un servlet (I)
El ciclo de vida de un servlet lo controla el servlet container y tiene tres fases principales:
1. El contenedor carga e inicializa el servlet
2. El contenedor maneja cero o más peticiones de cliente.
3. El contenedor elimina el servlet.
39. 4. Tecnología Java Servlets
4.2. El ciclo de vida de un servlet (II)
El ciclo de vida de un servlet se compone de los siguientes estados:
• Instanciación.
• Inicialización.
• Servicio.
• Destrucción.
• Inexistente.
40. 4. Tecnología Java Servlets
4.2. El ciclo de vida de un servlet (III)
Los métodos principales de la interface javax.servlet.Servlet son:
1. El método init():
Es el primer método que se llama para instanciar un servlet.
Solo se le llama una vez.
Su único argumento es una referencia a un objeto de la interface ServletConfig
2. El método service():
Método abstracto que debe ser definido por el programador.
Se invoca con cada petición que realiza el cliente.
Recibe dos parámetros, un objeto de la interface ServletRequest y un objeto de la interface
ServletResponse
1. El método destroy():
Elimina la instancia de un servlet que ya no se va a ejecutar.
41. 4. Tecnología Java Servlets
4.3. Configuración de un servlet (I)
La interface javax.servlet.ServletConfig declara los cuatro métodos que nos permiten acceder a
la configuración del servlet:
• getInitParameterNames():
Este método devuelve una enumeración con los nombres de todos los parámetros definidos
para el servlet en el fichero web.xml.
• getInitParameter(String):
Este método devuelve el valor dado a un parámetro en el fichero web.xml.
• getServletName():
Este método devuelve una cadena con el nombre del servlet.
• getServletContext():
Este método devuelve un objeto de tipo javax.servlet.ServletContext con la
información del contexto.
String valorParametro;
public void init(ServletConfig config) {
valorParametro = config.getInitParameter(nombreParametro);
}
42. 4. Tecnología Java Servlets
4.3. Configuración de un servlet (II)
Los parámetros de inicialización y el nombre del servlet pueden especificarse en el fichero descriptor de
despliegue (web.xml), como muestra el siguiente ejemplo:
<web-app>
<welcome-file-list>
<welcome-file>techsupp.html</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>techSupport</servlet-name>
<servlet-class>TechSupportServlet</servlet-class>
<init-param>
<param-name>driver</param-name>
<param-value>oracle.jdbc.driver.OracleDriver</param-value>
</init-param>
<init-param>
<param-name>protocol</param-name>
<param-value>jdbc:oracle:thin:@BLCZZ1002:1521:INNOVA</param-value>
</init-param>
</servlet>
</web-app>
43. 4. Tecnología Java Servlets
4.4. Contexto de un servlet
El contexto es un área común compartida por todos los servlets de una misma aplicación Web.
Debe implementar el interfaz javax.servlet.ServletContext.
Algunos de sus métodos son:
METODO DESCRIPCIÓN
getInitParameterNames() Devuelve una enumeración con los nombres de todos los parámetros de inicialización del contexto definidos en el
fichero web.xml mediante el elemento <context-param>.
getInitParameter(String) Devuelve el valor dado a un parámetro de inicialización del contexto en el fichero web.xml.
getAttributeNames() Devuelve una enumeración con los nombres de todos los atributos definidos en el contexto
getAttribute(String) Devuelve un objeto que está vinculado como valor al atributo dado como parámetro
setAttribute(String, Object) Almacena un objeto como atributo del contexto
removeAttribute(String) Elimina el atributo de la memoria del servidor.
getContext(String) Devuelve el contexto asociado a la ruta que pasamos como parámetro.
getResource(String) Devuelve un objeto de tipo java.net.URL apuntando al recurso cuya ruta pasamos como parámetro.
getResourceAsStream(String) Devuelve un objeto de tipo java.io.InputStream.
getRequestDispatcher(String) Devuelve el objeto de tipo javax.servlet.RequestDispatcher asociado a la ruta indicada.
getNamedDispatcher(String) Como el anterior, pero el parámetro es el nombre del servlet
getServletContextName() Este método devuelve el nombre del contexto tal y como se define en el fichero web.xml en el elemento <display-
name>.
44. 4. Tecnología Java Servlets
4.5. Otras clases de interés
Otras clases principales son:
• La interface javax.servlet.SingleThreadModel:
Permite hacer más sencillo el desarrollo de servlets.
Implementado en un servlet hace que el servidor procese todas las peticiones de servicio
dentro de un mismo thread.
Facilita el desarrollo de servlets pero obstaculiza el rendimiento.
• Las clases de excepciones de servlets son:
javax.servlet.ServletException:
Se utiliza cuando ocurre un fallo general en el servlet.
javax.servlet.UnavailableException:
Indica que el servlet no se encuentra disponible.
45. 4. Tecnología Java Servlets
4.6. La clase HttpServlet (I)
Extiende de la clase GenericServlet y provee una implementación de la interface Servlet específica del
protocolo HTTP.
Es una clase abstracta y hay que redefinir sus métodos, al menos los métodos doGet o doPost.
No define el método service() como abstract, sino como protected, al igual que los métodos init(),
destroy(), doGet(), doPost(), etc., de forma que ya no es necesario escribir una implementación de
service() en un servlet que herede de dicha clase.
Es una clase capaz de decir al cliente cual de sus métodos está redefinido y se puede utilizar.
Por ejemplo:
Si en un servlet sólo se ha redefinido el método doPost(), si el cliente realiza una petición de
tipo HTTP GET el servidor lanzará automáticamente un mensaje de error similar al siguiente:
501 Method GET Not Supported
Todos los métodos de clase HttpServlet que debe o puede redefinir el programador (doGet(), doPost(),
doPut(), doOptions(), etc.) reciben como argumentos un objeto HttpServletRequest y otro
HttpServletResponse.
46. 4. Tecnología Java Servlets
4.6. La clase HttpServlet (II)
Recapitulado, las diferencias entre Get y Post son:
• El método doGet() debería:
1. Leer los datos de la solicitud, tales como los nombres de los parámetros y sus valores.
2. Establecer el header de la respuesta (longitud, tipo y codificación).
3. Escribir la respuesta en formato HTML para enviarla al cliente.
• El método doPost() debería:
1. Obtener input stream del cliente y leer los parámetros de la solicitud.
2. Realizar aquello para lo que está diseñado (actualización de bases de datos, etc.).
3. Informar al cliente de la finalización de dicha tarea o de posibles imprevistos. Para ello
hay que establecer primero el tipo de la respuesta, obtener luego un PrintWriter y enviar
a través suyo el mensaje HTML.
47. 4. Tecnología Java Servlets
4.7. Concurrencia(I)
Dentro del contenedor Web, cada petición HTTP es procesada por una hebra diferente dentro de la VM
del contenedor.
Por defecto, el contenedor sólo construye una instancia de cada servlet, por lo que en cualquier
momento pueden existir múltiples hebras accediendo a la misma instancia de clase.
Si un servlet realiza operaciones sobre recursos compartidos, pueden aparecer problemas de
concurrencia ya que distintos hilos pueden estar modificando a la vez las mismas variables.
En relación a las variables, en función de su ámbito, podremos concretar los problemas que pueden
presentarse y cómo resolverlos.
Los ámbitos principales son:
• Variables locales.
Se definen en el ámbito del método service() o doGet(), y pueden utilizarse de forma
segura ya que cada hilo tendrá definida sus propias variables dentro del ámbito de ejecución.
• Variables no estáticas de la instancia.
Son las compartidas por todos los hilos de ejecución, son variables que almacenan parámetros
de inicialización. Para usarlas como variables de lectura/escritura se deben usar en bloques
synchronized para evitar el acceso simultáneo al bloque de código.
48. 4. Tecnología Java Servlets
4.7. Concurrencia (II)
• Variables estáticas de la instancia.
Se comparten por todas las instancias de una misma clase, por lo que deben tenerse en
cuenta las mismas consideraciones que para las variables no estáticas excepto cuando además de ser
estáticas son finales. En este caso, al ser valores de solo lectura, sí pueden utilizarse de forma segura.
• Atributos de la petición.
Son atributos que están encapsulados en el objeto de tipo ServletRequest,por lo que son
propios de cada petición y pueden utilizarse de forma segura entre diferentes hilos.
• Atributos de la sesión.
Son compartidos por diferentes peticiones realizadas por el mismo cliente a la aplicación, por
lo que son compartidos entre los diferentes hilos que simultáneamente pueden estar accediendo a un
servlet.
• Atributos del contexto.
Son compartidos por todos los servlets de la misma aplicación, por lo que aplican las mismas
consideraciones que para los atributos de sesión. Es decir, no podemos utilizar con seguridad los
atributos del contexto entre múltiples hilos.
49. 4. Tecnología Java Servlets
4.8. Interacción entre HTML y servlets
Los campos de entrada de datos en un formulario HTML pueden ser de los siguientes tipos:
TIPO DE CAMPO TAG DESCRIPCIÓN
Campo de texto <INPUT TYPE="text" …> Campo de texto libre; se puede añadir una línea únicamente.
Botón submit <INPUT TYPE="submit" …> Al pulsar este botón se envía el formulario al recurso definido como ACTION.
Botón reset <INPUT TYPE="reset" …> Al pulsar este botón se limpian todos los campos del formulario.
Check-box <INPUT TYPE="checkbox" …> Campo de selección booleano.
Radio-button <INPUT TYPE="radio" …> Campo de selección excluyente.
Campo contraseña <INPUT TYPE="password" …> Campo de texto utilizado para introducir contraseñas; la información que se
escribe en este campo no es visible al usuario.
Campo oculto <INPUT TYPE="hidden" …> Es un campo que no se muestra en el formulario pero cuyo valor es enviado al
servidor.
Lista desplegable <SELECT …><OPTION …></SELECT> Permite elegir una o más opciones de las que se muestran en una lista.
Área de texto <TEXTAREA …>…</TEXTAREA> Campo de texto libre; se puede añadir texto en varias líneas.
50. 4. Tecnología Java Servlets
4.9. Colaboración entre servlets (I)
Existen casos en los que un servlet envía la respuesta a una página jsp que se crea dinámicamente, o a
otro servlet que es encargado de darnos la respuesta.
Hay dos soluciones para realizar esto:
• Encadenar servlets (Servlet chaining):
Se diseñan varios servlets, cada uno con una tarea.
Se configura el contenedor para especificar la cadena de servlets a invocar para un alias de
una determinada URL.
Su uso no es recomendado ya que nunca se ha incluido en las especificaciones del API servlet.
• Envío de la respuesta (Request Dispatching):
Para enviar la petición a un segundo servlet, sólo hace falta tener la referencia del servlet
que invocamos.
Para esto el API de Java para Servlet ha desarrollado una interface especial llamada
javax.serlvet.RequestDispatcher.
51. 4. Tecnología Java Servlets
4.9. Colaboración entre servlets (II)
La interface javax.serlvet.RequestDispatcher permite enviar peticiones a otros servlets o Jsp’s.
Los dos métodos del interfaz son:
• forward():
Permite remitir la petición a otro servlet o página JSP, o un fichero HTML del servidor.
• include():
Incluye el contenido producido por otro recurso en la respuesta del servlet que invoca al
recurso.
Se puede obener un objeto RequestDispatcher para un recurso con los siguientes métodos:
• getRequestDispatcher() de la interface javax.servlet.ServletContext que requiere un path
absoluto.
• getNamedDispatcher() de la interface javax.servlet.ServletContext que acepta el nombre
asociado con el servlet, el cual se especifica en el fichero descriptor de despligue en el elemento
<servlet-name>.
• getRequestDispatcher() de la interface javax.servlet.ServletRequest que acepta tanto el path
absoluto como el path relativo.
52. CORT412: Programación Web con Tecnología Java
5. Sesiones
5.1. Introducción
5.2. Cookies
5.3. Sesiones (Session tracking)
5.4. Reescritura de URLs
53. 5. Sesiones
5.1. Introducción
El protocolo HTTP no está acoplado, esto es, no mantiene conectadas peticiones continuadas sobre un
mismo recurso o aplicación. Dos peticiones HTTP son mutuamente independientes.
Para suplir esta carencia, el contenedor Web debe proveer mecanismos que permitan almacenar
información importante concerniente a distintas peticiones de un mismo usuario. Esta información es lo
que denominaremos una sesión.
Un ejemplo de aplicación con sesión es la típica tienda on-line, donde el componente principal es el
carrito de la compra. La aplicación provee interfaces para consultar un catálogo, añadir productos al
carrito de la compra, y generar una orden de compra a partir del contenido del carrito.
Para implementar este tipo de aplicaciones necesitamos cumplir dos requerimientos básicos:
1. Conservar la sesión. El servidor ha de ser capaz de identificar la peticiones de un cliente y
asociarlas a su sesión de trabajo.
1. Conservar el estado. El servidor tiene que recordar toda la información relativa a peticiones
anteriores o decisiones de negocio tomadas a partir de esas peticiones
54. 5. Sesiones
5.2. Cookies (I)
Existe una extensión al protocolo HTTP que permite a un servidor Web almacenar información en la
máquina cliente. A cada pieza de información que se guarda en cliente se llama cookie.
Se utiliza para que un servidor HTTP reconozca a un cliente como alguien que ya se había conectado
anteriormente.
Las cookies se identifican por un dominio y una ruta y se intercambian en cada petición y respuesta
HTTP en la sección de cabeceras.
Varias cookies pueden compartir el mismo nombre y se almacenan en un directorio o fichero
predeterminado en el disco duro del cliente.
Tienen un determinado tiempo de vida y es responsabilidad del navegador limpiar las cookies que han
expirado.
Se envían añadiendo campos adicionales al header de un mensaje HTTP., de la forma clave/valor.
Las cookies en Java son objetos de la clase javax.servlet.http.Cookie.
Toda la información almacenada en cookies lo es en forma de String, por lo que será preciso convertir
cualquier valor a String antes de añadirlo a una cookie.
55. 5. Sesiones
5.2. Cookies (II)
Es necesario crear la cookie antes de acceder al Writer del objeto HttpServletResponse, ya que las
cookies son enviadas al cliente en el header del mensaje.
String IdObjetoAComprar = new String("301");
if(IdObjetoAComprar!=null)
Cookie miCookie=new Cookie("Compra", IdObjetoAComprar);
Los siguientes métodos permiten establecer los valores de una cookie y sus atributos:
MÉTODO DESCRIPCIÓN
setComment(String) Asigna un comentario a la Cookie
setDomain(String) Establece el patrón de dominio a quien permitir el acceso a la información contenida en la
cookie.
setMaxAge(int) Establece el tiempo de caducidad de la cookie en segundos.
setPath(String) Establece la ruta de acceso del directorio de los servlets que tienen acceso a la cookie.
setSecure(boolean) Indica al browser que la cookie sólo debe ser enviada utilizando un protocolo seguro (https).
setValue(String) Establece el valor de la cookie
setVersion(int) Establece la versión del protocolo de la cookie.
56. 5. Sesiones
5.2. Cookies (III)
Enviar una cookie: Recoger las cookies:
...
public void doGet(HttpServletRequest req, Cookie miCookie = null;
HttpServletResponse resp) throws ServletException, Cookie miCookie2= null;
IOException { Cookie miCookie3= null;
...
Cookie miCookie=new Cookie("Nombre","Valor"); Cookie[] arrayCookies = req.getCookies();
miCookie.setMaxAge(-1);
miCookie.setComment("Esto es un comentario"); miCookie = arrayCookies[0];
resp.addCookie(miCookie); miCookie2 = arrayCookies[1];
PrintWriter out=resp.getWriter(); miCookie3 = arrayCookies[2];
...
}
Obtener el valor de una cookie:
...
String libroABorrar = req.getParameter("Borrar");
...
if (libroABorrar != null) {
Cookie[] arrayCookies = req.getCookies();
for (i=0; i<arrayCookies.length; i++) {
Cookie miCookie = arrayCookies[i];
if (miCookie.getName().equals("compra")
&&miCookie.getValue.equals("libro1") {
miCookie.setMaxAge(0); // Elimina la cookie
} // fin del if
} // fin del for
} // fin del if
...
57. 5. Sesiones
5.3. Sesiones. (Session tracking) (I)
Una sesión es una conexión continuada de un mismo browser a un servidor durante un período prefijado
de tiempo que depende habitualmente del servidor.
Las sesiones son compartidas por todos los servlets de un mismo servidor.
Las sesiones son creadas automáticamente por el contenedor cuando el cliente se conecta por primera
vez y se pueden destruir de dos formas diferentes:
• El usuario no realiza una petición pasado el tiempo de inactividad
• La sesión se invalida a través del código.
La manera de acceder a los objetos de sesión es a través del interfaz
javax.servlet.http.HttpSession.
Podemos acceder a la sesión utilizando los métodos:
public HttpSession getSession(boolean crear);
public HttpSession getSession();
58. 5. Sesiones
5.3. Sesiones. (Session tracking) (II)
Algunos métodos de este interfaz y con los que podemos interactuar con la sesión son los siguientes:
METODO DESCRIPCIÓN
getId(): Devuelve una cadena con el identificador de la sesión.
isNew(): Indica si la sesión es o no de nueva creación.
invalidate() Invalida una sesión
getAttributeNames() Devuelve una enumeración con los nombres de todos los atributos que están definidos
para la sesión actual.
getAttribute(String) Devuelve un objeto con el valor asociado al atributo indicado.
setAttribute(String, Object): Añade un atributo a la sesión. Si un atributo con el mismo nombre existiera, su valor se
perdería.
removeAttribute(String) Elimina de la sesión el atributo cuyo nombre indicamos.
getCreationTime(), getLastAccessedTime(), Permiten obtener más información de la sesión y modificar el tiempo máximo de
getMaxInactiveInterval() inactividad de la misma.
setMaxInactiveInterval()
59. 5. Sesiones
5.4. Reescritura de URLs (I)
Se utiliza para poder emplear sesiones con clientes, que o bien no soportan cookies o bien las rechazan.
Para emplear está técnica se incluye el código identificativo de la sesión (sessionId) en el URL de la
petición.
Los métodos que se encargan de reescribir el URL son de la interface HttpServletResponse:
encodeURL(): lee un String que representa un URL y si fuera necesario la reescribe añadiendo
el identificativo de la sesión
encodeRedirectURL(): realiza lo mismo que el anterior, sólo que con URLs de redirección, es
decir, permite reenviar la petición del cliente a otra URL .
...
HttpSession miSesion=req.getSesion(true);
CarritoCompras compra =
(CarritoCompras)miSesion.getAttribute(miSesion.getId());
if (compra == null) {
compra = new CarritoCompras();
miSesion.setAttibute(miSesion.getId(), compra);
}
...
PrintWriter out = resp.getWriter();
resp.setContentType("text/html");
...
out.println("Esto es un enlace reescrito");
out.println("<a href""+
resp.encodeUrl("/servlet/buscador?nombre=Pedro")+""</a>");
...
60. CORT412: Programación Web con Tecnología Java
6. Modelo Vista Controlador
6.1. El patrón de diseño MVC
62. 1. Introducción
1.4. El patrón de diseño MVC (II)
El patrón MVC señala tres capas básicas en la aplicación:
• La capa de presentación o Vista. Típicamente serán las páginas de entrada de datos y páginas de
respuesta o los documentos que se generan como resultado de la interacción con el usuario.
• La capa de control o Controlador. Típicamente son los componentes que se encargan de recibir
peticiones, ver a qué caso de uso corresponden, ver si el usuario está autorizado para hacer esa
acción y redirigen a la lógica de negocio adecuada.
• La capa de lógica de negocio o Modelo. Son los componentes que contienen la lógica de negocio
propiamente dicha: realizarán cálculos, procesarán información contenida en una BD o se
integrarán con otras aplicaciones. Esta capa habitualmente se divide a su vez en 3 capas:
· Lógica de negocio de alto nivel.
· Lógica de acceso a datos.
· Información encapsulada en objetos Java.
Utilizando patrones de diseño en varias capas conseguimos, por ejemplo, que un cliente Java por Web,
un cliente Java Swing o un cliente .Net sean capaces de acceder a la misma lógica de negocio. Es decir,
reaprovechamos el Controlador y el Modelo y creamos tantas Vistas como sea necesario.
63. 1. Introducción
1.4. El patrón de diseño MVC (III)
Clase Modelo:
1. Contiene la funcionalidad de la aplicación.
2. Lleva un registro de las vistas y controladores del sistema.
3. Notifica los cambios en los datos a los componentes.
Clase controlador:
1. Acepta los eventos de entrada.
2. Traduce los eventos de entrada a peticiones al modelo o a las vistas.
3. Implementa el procedimiento actualizar si es necesario.
Clase vista:
1. Crea e inicializa su controlador asociado.
2. Muestra información al usuario.
3. Actualiza la información.
4. Recoge datos del modelo.
64. CORT412: Programación Web con Tecnología Java
Práctica del curso
II.1. La aplicación Agenda
II.2. Modelo de datos de la aplicación
II.3. Creación de VO’s, DAO’s y BO’s
II.4. Probando la capa de acceso a datos
II.5. Creación de la capa Web (controlador+vista)
II.6. Soluciones
65. Practica del curso
1. La aplicación Agenda
En este laboratorio vamos a crear una aplicación completa, llamada Agenda, que nos permitirá mantener
una pequeña base de datos de direcciones y teléfonos.
Esta aplicación tendrá dos capas separadas: la de acceso a datos, y la capa Web, que incluirá el
controlador y la vista. Nuestro objetivo principal es que la capa de acceso a datos esté totalmente
aislada y se reutilice al 100% sin cambios en un modelo de tres capas (ver el Laboratorio II).
Como objetivos secundarios nos marcamos que la aplicación tenga un control de acceso y tratamiento de
errores.
Como guión general, seguiremos los siguientes pasos para la creación de la aplicación:
· Creación de los objetos de acceso a datos: VO’s, DAO’s y BO’s, tratando de crear
componentes comunes que faciliten la implementación de múltiples clases similares.
· Creación de servlets de prueba que nos permitan probar los objetos de acceso a datos.
· Creación de la capa Web, primero creando páginas HTML siempre que una interfaz estática
pueda ser utilizada y posteriormente creando servlets que procesen las peticiones y generen las vistas
dinámicas.
66. Laboratorio II
II.2. Modelo de datos de la aplicación
El modelo de datos de la aplicación consiste en dos tablas: USUARIOS, donde guardamos los usuarios
autorizados a entrar en la aplicación y sus contraseñas, y AGENDA, donde guardamos las direcciones y
teléfonos administrados por la aplicación.
Las tablas las creamos en la base de datos :
CREATE TABLE USUARIOS (
USERNAME VARCHAR(10),
PASSWORD VARCHAR(10)
);
CREATE TABLE AGENDA (
NAME VARCHAR(50),
ADDRESS VARCHAR(150),
TELEPHONE VARCHAR(15),
LASTUPDATED TIMESTAMP
);
ALTER TABLE AGENDA
ADD CONSTRAINT PK_AGENDA
PRIMARY KEY (NAME);
67. Laboratorio II
II.3. Creación de VO’s, DAO’s y BO’s
Los Value Objects o VO’s, son JavaBeans que se construyen como imagen de un registro en base de
datos, por lo que su definición se corresponde con la definición de la tabla a la que dan respaldo, con las
equivalencias lógicas entre tipos de datos.
Los Data Access Objects o DAO’s, son objetos donde realizamos el acceso a los datos. Cada DAO recibirá
al instanciarse una conexión que utilizará para el acceso. Esta conexión estará inicializada
correctamente y estará incluida en una transacción si funcionalmente es necesario. Los métodos de un
DAO arrojan excepciones de tipo java.sql.SQLException, y no tratan esas excepciones, ni cierran
conexiones, pero sí deben cerrar los objetos que ellos creen.
Los Business Objects o BO’s, son objetos que encapsulan la lógica de negocio de alto nivel o lógica del
proceso. Se apoyan en DAO’s para realizar los accesos a los datos necesarios, las operaciones necesarias
a realizar sobre los datos para devolver los resultados y se encargan además de gestionar transacciones y
accesos distribuidos
Los BO’s recibirán al instanciarse la información de contexto necesaria para su correcta inicialización. En
nuestro caso, utilizaremos el contexto de la aplicación para inicializar la conexión a la base de datos.
Mediante un listener de la aplicación, crearemos la conexión y la guardaremos en el contexto para que
sea accesible a los BO’s.
68. Laboratorio II
II.4. Probando la capa de acceso a datos
Una vez que hemos terminado de desarrollar la capa de acceso a datos, vamos a desarrollar un par de
componentes de prueba que nos permitan probarlos.
Con estos componentes podremos asegurarnos que la capa de acceso a datos funciona correctamente sin
tener que completar la capa Web para capturar los datos y ejecutar la lógica de negocio.
Cada componente de prueba será un servlet que recibirá desde la petición los parámetros necesarios
para ejecutar la lógica de negocio. A continuación, instanciará el BO de la entidad que queremos probar,
instanciará un VO que inicializaremos con los datos leidos desde la petición, y por último ejecutará la
lógica contenido en el BO pasando el VO como parámetro.
Los resultados los mostraremos de forma sencilla, por consola o salida del servlet. En este punto no
vamos a crear la vista, sólo verificar que los datos son correctos.
También se capturarán las excepciones de la aplicación y se mostrará la información de la misma.
69. Laboratorio II
II.5. Creación de la capa Web (controlador+vista)
En la creación de la capa Web vamos a desarrollar dos tipos de componentes: páginas HTML con
formularios de captura de datos, que son estáticos y podemos desarrollar de esta forma, y servlets que
cumplirán una doble función: la de controlador, ejecutando la lógica de negocio contenida en los BO’s, y
la de vista, generando las páginas de resultados, que al ser dinámicas no pueden generarse con páginas
HTML.
Las páginas HTML de captura de datos serán tres:
· Una para el login;
· Una para introducir criterios de búsqueda, y;
· Una para dar de alta nuevos registros en la agenda.
Los servlets necesarios serán 5:
· Uno que valide los datos del login y en caso de que dichos datos correspondan a un usuario
autorizado, redirigir a la página de criterios de búsqueda;
· Uno que valide los criterios, ejecute la consulta y cree la página de resultados de forma
dinámica, junto con acceso a la ventana de alta y a la modificación y a la consulta;
· Uno que valide los datos de un alta y la ejecute y cree una página de confirmación del alta;
· Uno que genere dinámicamente la ventana de confirmación de la baja, ejecute la misma y
luego muestre un mensaje que indique si la baja se realizó o no.
· Uno que genere dinámicamente la ventana de modificación, ejecute la misma y luego
muestre un mensaje que indique si la modificación se realizó o no.
70. CORT412: Programación Web con Tecnología Java
7. Tecnología JavaServer Pages
7.1. JSP
7.2. Elementos disponibles en una página JSP
7.3. Sintaxis JSP’s
7.4 . La directiva JSP page
7.5 . La directiva JSP include
7.6. Acciones
71. 7. Tecnología JavaServer Pages
7.1. JSP
La tecnología JavaServer Pages, JSP, está basada en la tecnología de servlets.
Permite generar páginas de forma dinámica y separar la lógica de presentación de la lógica de negocio.
El contenido de un JSP se compone de código HTML, además de tags especiales JSP que permiten a la
página interactuar con la información que tenemos en el servidor, además de darnos la posibilidad de
incluir código Java.
Puesto que el código HTML es interpretado correctamente por el intérprete/compilador de un JSP, todo
fichero HTML puede ser convertido en un JSP únicamente cambiando su extensión.
Cada página JSP es convertida, mediante compilación, en un servlet por el motor JSP. La creación y
compilación automática del servlet ocurre la primera vez que se accede a la página JSP.
73. 7. Tecnología JavaServer Pages
7.3. Elementos disponibles en una página JSP’s (I)
En una página JSP hay cinco tipos de elementos disponibles:
• Elementos HTML (incluidos las cadenas de texto, la definición de estilos y el código JavaScript).
• Elementos de scripting (incluidos entre las cadenas “<%” y “%>”).
Los elementos de scripting nos permiten controlar ciertos aspectos de la generación de la
página, además de incluir código Java directamente. Hay cinco tipos de elementos de scripting:
• Comentarios: delimitados por las cadenas “<%--” y “--%>”.
• Directivas: delimitadas por las cadenas “<%@” y “%>”.
• Declaraciones: delimitadas por las cadenas “<%!” y “%>”.
• Código Java (scriptlets): Los bloques de código Java están delimitados por las cadenas “<%”
y “%>”.
• Expresiones: delimitadas por las cadenas “<%=“ y “%>”.
74. 7. Tecnología JavaServer Pages
7.3. Elementos disponibles en una página JSP’s (II)
<%-- código en el JSP --%>
<%
if (i > 100) {
%>
<b>i</b> es un número grande.
<%
} else {
%>
<b>i</b> es un número pequeño.
<%
}
%>
// código en el servlet
if (i > 100) {
pw.println(“<b>i</b> es un número grande.”);
} else {
pw.println(“<b>i</b> es un número pequeño.”);
}
75. 7. Tecnología JavaServer Pages
7.3. Elementos disponibles en una página JSP’s (III)
• Elementos JSP (también conocidos como acciones estándar JSP).
Estos elementos son tags definidos por el API JavaServer Pages y se traducen en código Java
que nos permite interactuar con JavaBeans, realizar redirecciones del flujo de la página o permitir
la inclusión de unos JSP’s dentro de otros. Estos elementos empiezan todos por la cadena “<jsp:”.
Ejemplo:
<%-- código en el JSP --%>
<jsp:forward page=“DetalleUsuarios.jsp”>
// código en el servlet
RequestDispatcher view =
request.getRequestDispatcher(“DetalleUsuarios.jsp”);
view.forward(request, response);
return;
• Tags personalizados (incluida la librería de tags estándar JSP o JSTL).
Se traducen en código HTML según se define en clases Java construidas según el API
JavaServer Pages. Estos tags se agrupan en librerías.
76. 7. Tecnología JavaServer Pages
7.3. Elementos disponibles en una página JSP’s (IV)
• Variables implícitas.
Son variables que dan acceso a los siguientes objetos :
• request: El HttpServletRequest.
• response: El HttpServletResponse.
• out: El objeto de tipo JspWriter asociado con el stream de salida de la respuesta.
• session: El HttpSession asociado con el request (si existe).
• application: El objeto de tipo ServletContext asociado al contexto de la
aplicación donde está contenida la página JSP.
• config: El objeto de tipo ServletConfig asociado a la configuración del servlet
que se genera al interpretar la página.
• pageContext: Este objeto encapsula el entorno de una petición para la página JSP.
• page: Esta variable es equivalente al uso de la variable this en código Java.
• exception: Excepción que se produce en el código.
77. 7. Tecnología JavaServer Pages
7.4. La directiva JSP page
Permite importar clases, personalizar la superclase del servlet, etc. Su sintaxis y atributos son:
<%@ page (atributo=“valor”)* %>
ATRIBUTO DESCRIPCIÓN
import="package.class" o Permite especificar los packages que deberían ser importados. Es el único que puede
import="package.class1,...,package.classN" aparecer múltiples veces.
contentType="MIME-Type" o Especifica el tipo MIME de la salida. El valor por defecto es text/html.
contentType="MIME-Type; charset=Character-Set".
isThreadSafe="true|false" Indica si el servlet generado implementará la interfaz SingleThreadModel. Su valor por
defecto es “true” e indica que no lo implementa.
session="true|false" El valor de este atributo indica si la página participa o no en una sesión. Su valor por
defecto es “true” e indica que implementa una sesión.
buffer="sizekb|none" Especifica el tamaño del buffer para el JspWriter out.
autoflush="true|false" Indica si la salida se vuelca cuando el buffer se llena o se arroja una excepción.
extends="package.class" Indica la superclase del servlet que se va a generar
info="message". Define una cadena informativa acerca de la página
errorPage="url". Especifica la página JSP que se debería procesar si se lanzará cualquier Excepción.
isErrorPage="true|false" Indica si la página actual actúa o no como página de error de otra página JSP.
language="java" Especifica el lenguaje a utilizar.
pageEncoding Define el tipo de codificación usado en el stream de salida. Por defecto su valor es
“ISO-8859-1”.
78. 7. Tecnología JavaServer Pages
7.5. La directiva JSP include
Permite incluir ficheros en el momento en que la página JSP es traducida a un servlet. Su es:
<%@ include file="url relativa" %>
La URL especificada normalmente se interpreta como relativa a la página JSP a la que se refiere.
Los contenidos del fichero incluido son analizados como texto normal JSP, y así pueden incluir HTML
estático, elementos de script, directivas y acciones.
Ejemplo:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<TITLE>Servlet Tutorial: JavaServer Pages (JSP) 1.0</TITLE>
<META NAME="author" CONTENT="webmaster@somesite.com">
<META NAME="keywords" CONTENT="...">
<META NAME="description" CONTENT="...">
<LINK REL=STYLESHEET
HREF="Site-Styles.css"
TYPE="text/css">
</HEAD>
<BODY>
<%@ include file="/navbar.html" %>
<!-- Part specific to this page ... -->
</BODY>
</HTML>
79. 7. Tecnología JavaServer Pages
7.6. Acciones (I)
Las acciones JSP usan construcciones de sintaxis XML para controlar el comportamiento del motor de
Servlets.
Las acciones disponibles son:
ACCIÓN DESCRIPCIÓN
jsp:include Permite insertar ficheros en una página que está siendo generada. La sintaxis es la siguiente:
<jsp:include page="relative URL" flush="true" />
Inserta el fichero en el momento en que la página es solicitada.
jsp:useBean permite cargar y utilizar un JavaBean en la página JSP. La sintaxis más simple es:
<jsp:useBean id="name" class="package.class" />
Usamos esta instrucción para cargar el Bean, jsp:setProperty y jsp:getProperty para modificar y recuperar
propiedades del bean.
ATRIBUTO USO
id Da un nombre a la variable que referenciará el bean.
Class Designa el nombre completo del paquete que contiene el bean.
scope Indica el contexto en el que el bean debería estar disponible. Hay cuatro posibles
valores: page, request, session, y application.
type Especifica el tipo de la variable a la que se referirá el objeto.
beanName Da el nombre del bean.
80. 7. Tecnología JavaServer Pages
7.6. Acciones (II)
ACCION DESCRIPCION
jsp:setProperty Asignar valores a las propiedades de los beans que se han referenciado anteriormente.
ATRIBUTO USO
name Designa el bean cuya propiedad va a ser seleccionada.
property Indica la propiedad que queremos seleccionar. Un valor de "*" significa que todos los
parámetros de la petición cuyos nombres correspondan con nombres de propiedades
del Bean serán pasados a los métodos de selección apropiados.
value Atributo opcional que especifica el valor para la propiedad. Los valores string son
convertidos automáticamente a números, boolean, Boolean, byte, Byte, char, y
Character mediante el método estándar valueOf en la fuente o la clase envolvente.
param Parámetro opcional que designa el parámetro de la petición del que se debería derivar
la propiedad.
jsp:getProperty Recupera el valor de una propiedad del bean, lo convierte a un string, e inserta el valor en la salida. Los dos
atributos requeridos son name, el nombre de un bean referenciado anteriormente y property, la propiedad cuyo
valor debería ser recuperado.
jsp:forward Permite reenviar la petición a otra página. Tiene un sólo atributo, page, que debería consistir en una URL relativa.
jsp:plugin Permite insertar un elemento OBJECT o EMBED específico del navegador para indicar que el navegador debería
ejecutar un applet usando el Plug-in Java.
81. CORT412: Programación Web con Tecnología Java
8. Opciones Avanzadas
8.1. Tratamiento de errores
8.2. Seguridad en una aplicación web
8.3. Filtros
8.4. Concurrencia de la BBDD
8.5. Creación de tags parsonalizados
82. 8. Opciones Avanzadas
8.1. Tratamiento de errores (I)
En una aplicación Web pueden producirse dos tipos de errores:
• Errores HTTP: Cada respuesta HTTP que el servidor envía de vuelta al cliente incluye un código
de estado, indicando al navegador si la petición se procesó correctamente o si hubo un error.
ERROR DESCRIPCION
400 Petición inválida (bad request)
401 No autorizado (unauthorized)
403 Acceso prohibido (forbidden)
404 Recurso no encontrado (not found)
405 Método no permitido (method not allowed)
415 Tipo no soportado (unsupported media type)
500 Error interno (internal server error)
501 No implementado (not implemented)
503 Servicio no disponible (service unavailable)
• Excepciones en los servlets: Son excepciones Java que se producen durante el ciclo de vida de
los servlets.
83. 8. Opciones Avanzadas
8.1. Tratamiento de errores (II)
Una página de error puede ser tanto un fichero HTML estático como un servlet y debe proporcionar a los
usuarios información bien formateada de un error producido durante el uso de una aplicación
Las páginas de error creadas pueden ser activadas de dos formas:
• Declarativamente, en el fichero web.xml.
• En código, capturando excepciones y redirigiendo el flujo según sea necesario.
Si la página de error la genera un servlet, se accede a la información con los atributos:
• javax.servlet.error.exception: El valor es el objeto Exception arrojado por el servlet.
• javax.servlet.error.request_uri: Este atributo contiene una cadena con la URL del recurso que
originó el error tal y como el usuario lo solicitó.
Ejemplo:
En el caso de que estemos capturando un error HTTP, la sintaxis será como sigue:
<error-page>
<error-code>404</error-code>
<location>/errores/error404.html</location>
</error-page>
En el caso de que estemos capturando una excepción Java, la sintaxis será así:
<error-page>
<exception-type>java.lang.ArithmeticException</exception-type>
<location>/errores/ErrorServlet</location>
</error-page>
84. 8. Opciones Avanzadas
8.1. Tratamiento de errores (III)
Habitualmente, cada vez que se produce un error en código suele quedar registrado en un log de
actividad como el que todo contenedor Web nos ofrece.
A este log podemos acceder usando los métodos log() de la clase servlet o del contexto.
Existen dos métodos log():
• Primer tipo: Almacena el mensaje.
• Segundo tipo: Almacena la causa de error.
En la práctica, este log no es utilizado pues su control lo tiene el contenedor.
Es por esto que habitualmente los logs de actividad se realizan accediendo directamente a librerías de
terceros, como es el caso de log4j.
85. 8. Opciones Avanzadas
8.2. Seguridad en una aplicación web (I)
La seguridad es un aspecto crítico en cualquier aplicación Web.
El objetivo de un desarrollador debe ser, por un lado, crear aplicaciones robustas, y por otro, mantener
la seguridad en los equipos en la mejor forma posible.
Las formas de gestionar la seguridad de una aplicación más habituales son:
• Utilizando el protocolo SSL sobre HTTP, también conocido como HTTPS.
• Utilizando un certificado digital que es expedido por una entidad certificadora (CA.
• Realizar una auditoría de la aplicación manteniendo un log de accesos y operaciones.
Se denomina código malicioso a toda pieza de software diseñada para dañar un sistema. En aplicaciones
Web, código malicioso es aquél código en el servidor diseñado con la intención de dañarlo o evitar su
funcionamiento normal.
Se denomina ataque Web al acceso externo a un servidor con el fin de crear una situación de denegación
del servicio, robar contraseñas o información confidencial.
86. 8. Opciones Avanzadas
8.2. Seguridad en una aplicación web (II)
Desde una aplicación web las formas de garantizar la seguridad son:
• Autenticación: Proceso por el cuál se valida la identidad de un usuario. Los métodos más comunes
de validar la identidad de un usuario son los siguientes:
• Incluir una página de validación de usuario y contraseña.
• Utilizar un certificado digital por parte del cliente y usar sus claves pública y privada para
mantener con el servidor un intercambio de información encriptado.
• Utilizar un sistema de tarjetas inteligentes y un lector para suministrar su identificación.
La autentificación es un proceso que podemos configurar en un contenedor Web.
METODO DESCRIPCION
BASIC El navegador solicita al usuario su identificador y su contraseña y envía esa información de forma
abierta al servidor el cual valida el par.
DIGEST El navegador solicita al usuario su identificador y su contraseña y envía esa información de forma
encriptada al servidor el cual valida el par.
FORM La aplicación Web utiliza un formulario HTML que es enviado al navegador para recoger la
información de identificación del usuario.
CLIENT-CERT El contenedor utiliza un certificado digital para verificar la identidad del usuario. La comunicación
en este caso se realiza con SSL sobre HTTP.
87. 8. Opciones Avanzadas
8.2. Seguridad en una aplicación web (III)
• Autorización: Proceso por el cuál la funcionalidad de una aplicación es accesible o no en función
de perfiles de usuario (roles).
El mapeo entre una lista de recursos en nuestra aplicación y un rol de usuario, denominado un
dominio de seguridad, es configurable dentro del contenedor Web.
Seguridad declarativa es la posibilidad de incluir configuración de autentificación y de autorización en
una aplicación Web sin tener que modificar el código de la misma.
Autentificación declarativa.
Para habilitar alguno de los mecanismos de autentificación declarativa, hacemos uso del elemento
<login-config> del fichero web.xml. Este elemento incluirá un elemento <auth-method> cuyo contenido
podrá ser uno de los cuatro métodos de autentificación que proporciona el servidor: BASIC, DIGEST,
FORM o CLIENT-CERT.
<login-config>
<auth-method>FORM</auth-method>
<form-login-config>
<form-login-page>/login/login.html</form-login-page>
<form-error-page>/login/error.html</form-error-page>
</form-login-config>
</login-config>
88. 8. Opciones Avanzadas
8.2. Seguridad en una aplicación web (III)
Autorización declarativa.
Hay que identificar las colecciones de recursos de la aplicación, identificar los roles, relacionar los
recursos con los roles e identificar a los usuarios. Una vez encontrada una relación, haremos uso del
elemento <security-constraint> en el fichero web.xml:
<security-constraint>
<web-resource-collection>
<web-resource-name>Recursos restringidos</web-resource-name>
<url-pattern>/Parametros.html</url-pattern>
<url-pattern>/PrimerForm.html</url-pattern>
<http-method>GET</http-method>
<http-method>POST</http-method>
</web-resource-collection>
<auth-constraint>
<role-name>CursoServletsRole</role-name>
</auth-constraint>
</security-constraint>
También debemos indicar todos los roles que serán utilizados en la aplicación usando el elemento
<security-role> en el fichero web.xml una vez por cada rol que utilicemos:
<security-role>
<role-name>CursoServletsRole</role-name>
</security-role>
89. 8. Opciones Avanzadas
8.3. Filtros
Un filtro en la tecnología Java Servlets es una clase que, a partir de la versión 2.3 de la especificación, e
implementando el interfaz javax.servlets.Filter, se sitúa delante de uno o varios recursos de
nuestra aplicación Web, modificando la petición y/o la respuesta.
Los filtros son componentes que, se emplean para:
• Construir componentes de autentificación no basados en la seguridad declarativa.
• Construir componentes de log y auditoría.
• Construir componentes que realicen conversiones en el formato de imágenes.
• Construir componentes que compriman y descompriman la información que se transmite.
• Construir componentes de encriptación/desencriptación de información.
Un filtro contiene tres métodos: init(), destroy() y doFilter(). Los dos primeros se comportan de
forma análoga a los de un servlet, y también se pueden definir parámetro de inicialización para los
filtros.
Puesto que pueden existir distintos filtros superpuestos para un mismo recurso, la manera de seguir con
la ejecución hacia abajo es mediante la invocación del método doFilter() del objeto de tipo
javax.servlet.FilterChain que es el tercer parámetro del método doFilter(). En el caso de
que no se cumpla el criterio de filtrado, podemos no pasar al siguiente eslabón de la cadena y redirigir a
otro componente, por ejemplo una página de error o de login.
90. 8. Opciones Avanzadas
8.4. Concurrencia de la BBDD
Uno de los principales problemas relacionados con la concurrencia consiste en el acceso a recursos que,
por su naturaleza, son compartidos
Utilizando transacciones, logramos que se atomicen operaciones complejas, que no se queden datos
corruptos, pero en ningún caso evitamos que un registro borrado por un usuario deje de estar disponible
para otros.
Las situaciones más comunes que deberemos controlar al trabajar de forma concurrente con BBDD son:
• Un registro consultado por un usuario, durante su visualización, ha sido modificado por otro
usuario.
• Un registro consultado por un usuario, durante su visualización, ha sido eliminado por otro
usuario.
Nuestro código deberá, por tanto, antes de actualizar o eliminar un registro, verificar:
• Que no haya sido modificado mientras tanto por otro usuario.
• Que no haya sido borrado mientras tanto por otro usuario.
La primera verificación la realizamos añadiendo a nuestras tablas los llamados campos de auditoría.
La segunda verificación la hacemos por PK.
91. 8. Opciones Avanzadas
8.5. Tags personalizados (I)
Un tag personalizado es un tag XML utilizado dentro de una página JSP y que representa alguna acción
dinámica o de generación de contenido en tiempo de ejecución.
Los tags personalizados se utilizan para eliminar la necesidad de código Java dentro de la página, o para
encapsular elementos HTML que se utilizan de forma recurrente.
Además de eliminar código Java de las páginas, son componentes totalmente reutilizables y que
podemos compartir fácilmente en muchas páginas en incluso en diferentes aplicaciones.
Todo tag personalizado debe cumplir lo siguiente:
• Un tag estándar tendrá la siguiente estructura:
<prefix:name {attribute={“value”|’value’}}*>
body
</prefix:name>
• Un tag vacío tendrá la siguiente estructura:
<prefix:name {attribute={“value”|’value’}}*/>
Los prefijos, los nombres de los tags y los de sus atributos distinguen entre mayúsculas y minúsculas.
92. 8. Opciones Avanzadas
8.5. Tags personalizados (II)
Una librería de tags ya existente se compone de dos elementos:
• Fichero JAR con las clases Java que implementan los tags
• Fichero XML denominado descriptor de la librería (Tag Library Descriptor, TLD).
Para poder utilizar una librería de tags ya existente, debemos declarar el TLD en el fichero web.xml de
la aplicación utilizando el elemento <taglib>. También deberemos tener en cuenta que, a partir de la
versión 2.4 de la especificación de Servlets, el elemento <taglib> se incluye dentro del elemento <jsp-
config>.
<jsp-config>
<taglib>
<taglib-uri>
http://www.coritel.es/csdc/curso-servlets-taglib
</taglib-uri>
<taglib-location>
/WEB-INF/curso-servlets.tld
</taglib-location>
</taglib>
</jsp-config>
93. 8. Opciones Avanzadas
8.5. Tags personalizados (III)
Normalmente el TLD se guarda en el directorio WEB-INF, mientras que el fichero JAR con la librería se
guarda en el directorio WEB-INF/lib. El mapeo que realizamos en el fichero web.xml empareja un TLD
situado en una localización física a una URI utilizada como identificador lógico de la librería.
A partir de la versión 2.4 de la especificación de Servlets, no es necesario declarar el TLD pues su
localización es obligatoriamente el directorio WEB-INF.
Para utilizar la librería en un JSP, debemos usar la directiva taglib utilizando la URI de la librería tal y
como la hemos declarado en el fichero web.xml:
<%@ taglib uri=“http://www.coritel.es/csdc/curso-servlets-taglib”
prefix=“csdc” %>
Y con el prefijo que definimos, accedemos a los tags que componen la librería:
<csdc:tabla nombre=“ConsultaUsuarios”>
<csdc:iterar nombre=“elemento”>
<csdc:campo nombre=“username”/>
</csdc:iterar>
</csdc:tabla>
94. 8. Opciones Avanzadas
8.5. Tags personalizados (IV)
Para desarrollar tags personalizados, dentro de la especificación se incluye un API denominada Tag
Handler.
Se crea una clase que implementa el interfaz javax.servlet.jsp.tagext.Tag. Este interfaz declara
una serie de métodos que el servlet asociado al JSP ejecuta cuando encuenta, en tiempo de ejecución,
el tag de apertura y el de cierre del elemento.
El método doStartTag() es ejecutado cuando el tag de apertura es procesado. Análogamente, el
método doEndTag() es ejecutado cuando el tag de cierre es procesado.
Para facilitar el desarrollo de tags, el API incluye la clase javax.servlet.jsp.tagext.TagSupport
que proporciona una implementación por defecto del interfaz Tag. Esta clase proporciona una variable
de tipo javax.servlet.jsp.PageContext con la que podemos acceder a las variables implícitas.
Para desarrollar tags más complejos, el API incluye las interfaces IterationTag (para tags que deben
iterar su contenido) y BodyTag (para tags que deben manipular el resultado de evaluar su contenido).
95. 8. Opciones Avanzadas
8.5. Tags personalizados (V)
Para procesar los tags de una forma diferente, se incluye la interfaz SimpleTag, la cuál únicamente
declara el método doTag(), el cuál se evaluará una sola vez cuando el tag se procesa en tiempo de
ejecución y si lo precisa, se encargará de evaluar el contenido o de iterar sobre él. La clase
SimpleTagSupport puede utilizar como base para construir nuevos tags, de forma análoga a la clase
TagSupport sobre el interfaz Tag.
Un tag con contenido opcional evalúa, en el método doStartTag(), la condición que generamos a
partir de los atributos del tag, y en el caso de cumplirse, devuelve la constante EVAL_BODY_INCLUDE.
Si la condición no se cumple, devuelve la constante SKIP_BODY.
Los tags iteradores implementan al interfaz IterationTag. Este interfaz introduce el método
doAfterBody(), que es el que utilizaremos para verificar si procede una nueva iteración del contenido
del tag o no, lo que se consigue devolviendo EVAL_BODY_AGAIN o SKIP_BODY.
Los elementos fundamentales de un tag personalizado respecto a una página JSP son tres:
• Tag de apertura: invoca al método doStartTag().
• Contenido: Si el valor que devuelve la invocación al método anterior es igual a la constante
Tag.EVAL_BODY_INCLUDE, la página JSP puede procesar el contenido del tag.
• Tag de cierre: invoca al método doEndTag().
96. CORT412: Programación Web con Tecnología Java
Referencias
· Las especificaciones oficiales de la norma Java EE
(antiguamente J2EE) y de las API’s de Servlets y
JavaServer Pages pueden descargarse de la web de Sun:
http://java.sun.com/javaee/reference/index.jsp
http://java.sun.com/products/servlets
http://java.sun.com/products/jsp
· El tutorial oficial contiene mucha información acerca
de cómo trabajar con Servlets y JSP’s:
http://java.sun.com/j2ee/1.4/docs/tutorial/doc
http://java.sun.com/javaee/5/docs/tutorial/doc
· Para descargar y obtener documentación sobre Tomcat
y sobre Eclipse, el mejor punto de partida son las webs
oficiales de ambos productos:
http://tomcat.apache.org
http://www.eclipse.org
97. CORT412: Programación Web con Tecnología Java
Referencias (II)
· El sitio Web TheServerSide contiene mucha
información sobre tecnologías Web, los últimos
productos, librerías y tendencias, además de tutoriales y
libros que podemos descargar de forma gratuita:
http://www.theserverside.com
· El sitio Web JavaWorld también es una fuente
importante de información sobre tecnología Java y Web.
En este sitio se publican artículos y tutoriales muy
útiles:
http://www.javaworld.com
· Y, por supuesto, el portal de SDC dedicado a la
Capability de Java:
https://tseme.accenture.com/sites/SDC/Java