Upload
jorge-guillo
View
759
Download
1
Embed Size (px)
DESCRIPTION
Curso de programación web en Java. Servlets, JSP y JSTL
Citation preview
Programación Web con Java
Jorge Guilló – [email protected]
Contenido
Introducción programación Web
Cliente / Servidor HTTP, HTML
Servlets Conceptos HttpServletRequest HttpServletResponse Sesiones Cookies
JSP Sintaxis básica Expresiones (EL) JSP Beans JSTL Etiquetas
personalizadas
Funcionamiento de una petición web
Navegador
http://www.google.es
Servidor
Servidor WebApache, IIS,...
Recursos
Petición HTTP Traducción
Buscar recurso
Devolverrecurso
index.html
Respuesta HTTP
GET / HTTP/1.0Host: www.google.es
HTTP/1.0 200 OKDate: ...Content-Type: text/htmlContent-Length: ...
<HTML>...
HTTP
HyperText Transfer Protocol Protocolo de las peticiones WWW
Basado en texto Sin estado
Cada petición es independiente Funciona sobre TCP/IP
Petición HTTP
Métodos: GET: Solicita un recurso
No tiene cuerpo POST: Envía información al servidor
El cuerpo contiene la información enviada Otros:
PUT, DELETE, OPTIONS, HEAD, TRACE, CONNECT
POST /buscar.jsp HTTP/1.1Host: www.example.comUser-Agent: Mozilla/4.0
search=Java
POST /buscar.jsp HTTP/1.1Host: www.example.comUser-Agent: Mozilla/4.0
search=Java
Método
URI
Protocolo
Cabeceras
Cuerpo
Cabeceras HTTP
Accept Accept-Language Cache-Control Content-Type Content-Length Date
Expires Host Last-Modified Pragma Referer User-Agent
Contienen información adicional sobre la petición o respuesta HTTP
Respuesta HTTP
HTTP/1.1 200 OKCache-Control: privateContent-Type: text/html; charset=ISO-8859-1Server: GWS/2.1Transfer-Encoding: chunkedDate: Sun, 27 May 2007 19:19:34 GMT
<html><head><title>Ejemplo</title>...
HTTP/1.1 200 OKCache-Control: privateContent-Type: text/html; charset=ISO-8859-1Server: GWS/2.1Transfer-Encoding: chunkedDate: Sun, 27 May 2007 19:19:34 GMT
<html><head><title>Ejemplo</title>...
Protocolo
Código de estado
Cabeceras
Cuerpo
Códigos de estado
1xx – Información 100 – Continuar
2xx – Éxito 200 – OK 202 – Aceptado
3xx – Redirección 301 – Movido
permanentemente 302 – Encontrado
(redirigir) 307 – Redirección
temporal
4xx – Error de cliente 400 – Petición errónea 401 – No autorizado 403 – Prohibido 404 – No encontrado 407 – Proxy requiere
autentificación 5xx – Error de servidor
500 – Error interno 501 – No implementado
Las respuestas HTTP incluyen un código de estado indicando el resultado de la petición
HTML
Lenguaje para definición de contenido
Contiene etiquetas para definir los distintos elementos de una página
También se incluyen etiquetas para definir formularios que permiten enviar datos al servidor
Documento HTML
<html> <!–- Engloba todo el documento --><head> <!–- Cabecera --><title>Título de la página</title><link type="text/css" rel="stylesheet" href="estilos.css"></head><body> <!–- Cuerpo del documento -->
<h1>Página de prueba</h1>Aquí va el texto de la página
</body></html>
<html> <!–- Engloba todo el documento --><head> <!–- Cabecera --><title>Título de la página</title><link type="text/css" rel="stylesheet" href="estilos.css"></head><body> <!–- Cuerpo del documento -->
<h1>Página de prueba</h1>Aquí va el texto de la página
</body></html>
Elementos HTML <!-- ... -->: Comentario <p>...</p> : Párrafo
<p align="center">Párrafo centrado</p> <br>: Salto de línea <img>: Imagen
<img src="imagen.jpg"> <a>...</a>: Enlace
<a href="www.google.es">Google</a> <h1>...</h1>: Títulos (<h2>,<h3>,...)
<h1>Título</h1>
Elementos HTML <b>...</b>: Negrita <i>...</i>: Cursiva <u>...</u>: Subrayado <ul>...</ul>: Lista con viñetas<li>..</li>: Línea con viñeta
<ul><li>Linea 1</li><li>Linea 2</li>
</ul> <span>...</span>: Bloque <div>...</div>: Capa
Elementos HTML
<table>...</table>: Tabla<tr>...</tr>: Fila de tabla<th>...</th>: Cabecera de columna<td>...</td>: Celda de tabla <table border=1 cellpadding=3>
<tr><th>ID</th><th>Nombre</th></tr><tr><td>1</td><td>Juan</td></tr><tr><td>2</td><td>Ana</td></tr>
</table>
Formularios HTML <form>: engloba un
formulario method: Método HTTP action: URL a la que se
envía el formulario <input>: elemento de
entrada name: Nombre del control value: Valor type: Tipo de control
text: Caja de texto (por defecto)
checkbox: Casilla de verificación
radiobutton: Casilla de opción
button: Botón submit: Botón de envío file: Fichero hidden: Valor oculto
<textarea>: Área de texto para varias líneas
rows: Nº de líneas cols: Nº de columnas
<select>: Lista name: Nombre del control
<option>: Elemento de lista value: Valor de la opción Contenido: Texto de la
opción <select name="lista">
<option value="1"> Opcion 1 </option> <option value="2"> Opcion 2 </option></select>
Formulario HTML
<form method="GET" action="http://www.google.es/search">
<input type="hidden" name="hl" value="es">
Buscar en Google: <input name="q"><input type="Submit" value="Buscar">
</form>
<form method="GET" action="http://www.google.es/search">
<input type="hidden" name="hl" value="es">
Buscar en Google: <input name="q"><input type="Submit" value="Buscar">
</form>
Tecnologías Web de Java
Servlets Componentes ejecutables en el
servidor Similar a CGI
JSP Páginas "vivas" Mezcla HTML con código Similar a ASP
Servlets
Son clases de Java Se ejecutan en el servidor web Ventajas sobre CGI:
Eficientes: Proceso único multihilo Convenientes: Comunican con el
servidor Potentes: Toda la API Java al alcance Portables: Bytecode Java Seguros: Infraestructura Java Baratos: Servidores y librerías
gratuitos
Proceso de funcionamiento
Servidor Web
Máquina virtual Java
Servlet
Navegador
_______________________
__________________________
__________
http://.../servlet
Fichero de configuración
Encontrarservlet
para la URL
Proceso de funcionamiento Leer la petición HTTP
Datos enviados por el usuario Cabeceras, cookies, etc...
Procesar los resultados Consulta a base de datos Acceso a servicios
Formateo de los resultados Normalmente en HTML, pero pueden devolver una
imagen, texto, XML, ficheros binarios (PDF),... Preparar la respuesta
Añadir cabeceras, establecer cookies,... Enviar la respuesta al cliente
Mi primer servlet!
import java.io.*;import javax.servlet.*;import javax.servlet.http.*;public class HolaServlet extends HttpServlet {
public void doGet(HttpServletRequest request,HttpServletResponse
response)throws ServletException,
IOException {
String nombre = request.getParameter("nombre");PrintWriter out = response.getWriter();out.println("<HTML><H1>");out.println("Hola " + nombre + "!");out.println("</H1></HTML>");
}}
import java.io.*;import javax.servlet.*;import javax.servlet.http.*;public class HolaServlet extends HttpServlet {
public void doGet(HttpServletRequest request,HttpServletResponse
response)throws ServletException,
IOException {
String nombre = request.getParameter("nombre");PrintWriter out = response.getWriter();out.println("<HTML><H1>");out.println("Hola " + nombre + "!");out.println("</H1></HTML>");
}}
Interface Servlet
javax.servlet.Servlet Define los métodos que debe tener
cualquier servlet, para cualquier protocolo
init(ServletConfig config) service(ServletRequest request,
ServletResponse response) destroy() ServletConfig getServletConfig() java.lang.String getServletInfo()
Clase HttpServlet
javax.servlet.http.HttpServlet Implementa el interface Servlet
específicamente para el protocolo HTTP Normalmente, se deriva directamente de
HttpServlet en lugar de implementar Servlet Añade los métodos
doGet(HttpServletRequest, HttpServletResponse) doPost(HttpServletRequest, HttpServletResponse) ...
Instalación en el servidor El servidor web contiene aplicaciones web
(webapps) Cada aplicación es un directorio con una
estructura determinada Raíz: *.html, *.jsp, imágenes,... WEB-INF/web.xml: Fichero de descripción. XML
indicando los servlets y componentes que forman la aplicación.
WEB-INF/classes/: Clases y recursos de la aplicación, que no estén empaquetados en JAR. Mantiene la estructura de paquetes.
WEB-INF/lib/: Ficheros JAR necesarios para la aplicación
Toda esta estructura se puede empaquetar en un sólo archivo WAR (Web Application Archive)
Los contenidos de WEB-INF están protegidos y no son descargables por el cliente
Fichero web.xml
El fichero web.xml contiene toda la configuración de una aplicación web Servlets instalados Filtros Gestores de eventos de aplicación Seguridad Variables de entorno
Ejemplo fichero web.xml
<?xml version="1.0" encoding="ISO-8859-1"?><!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd"><web-app> <display-name>Pruebas</display-name> <description>Pruebas.</description> <servlet> <servlet-name>HolaServlet</servlet-name> <servlet-class>HolaServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>HolaServlet</servlet-name> <url-pattern>/Hola</url-pattern> </servlet-mapping></web-app>
<?xml version="1.0" encoding="ISO-8859-1"?><!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd"><web-app> <display-name>Pruebas</display-name> <description>Pruebas.</description> <servlet> <servlet-name>HolaServlet</servlet-name> <servlet-class>HolaServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>HolaServlet</servlet-name> <url-pattern>/Hola</url-pattern> </servlet-mapping></web-app>
Configuración de servlets En el fichero web.xml hay que añadir dos
directivas por cada servlet que se quiera instalar
<servlet> <servlet-name>...</servlet-name>
<servlet-class>...</servlet-class></servlet>
Indica la clase que implementa un servlet y el nombre que se le da en la aplicación
<servlet-mapping> <servlet-name>...</servlet-name> <url-pattern>...</url-pattern></servlet-mapping>
Asigna una URL a un servlet
Instalar la aplicación web Hay varias opciones para instalar una
aplicación web en Tomcat Copiar el directorio de la aplicación en el directorio
webapps de Tomcat Copiar el archivo war de la aplicación en el directorio
webapps de Tomcat Tomcat puede descomprimir automáticamente el
archivo Utilizar las páginas y comandos de Tomcat Manager Utilizar tareas Ant de Tomcat Deployer
La manera de instalar aplicaciones varía de un servidor de aplicación a otro
Todos deben aceptar archivos war La mayoría tienen administración por web
Ciclo de vida de un servlet
Durante la ejecución de un servlet se llama a sus distintos métodos en distintos momentos init(): Cuando se crea el servlet service(): Para atender cada
petición. Este método llama a su vez a:
doGet(): Para peticiones GET doPost(): Para peticiones POST
destroy(): Cuando se libera el servlet
Interfaz SingleThreadModel
Normalmente, se crea una sola instancia del servlet y multiples hilos que acceden a dicha instancia Los metodos deben sincronizar los accesos
a variables de la instancia Implementando el interfaz
SingleThreadModel, se asegura que los métodos se acceden por un solo thread
Puede afectar al rendimiento de la aplicación
Obtener parámetros
El objeto HttpServletRequest contiene toda la información enviada por el cliente getParameter(nombre): devuelve el valor
de un parámetro getParameterValues(nombre): devuelve un
array con los valores de un parámetro multivalor
getParameterNames(): devuelve un array con los nombres de los parámetros recibidos
Obtener cabeceras El método getHeader() obtiene el valor de una cabecera
HTTP Además, existen métodos específicos para las
cabeceras más comunes getCookies getContentType getContentLength
Otros métodos: getHeaderNames: Devuelve los nombres de todas las
cabeceras recibidas getHeaders: Devuelve los valores de una cabecera
multivalor getDateHeader: Devuelve el valor de una cabecera de tipo
fecha getIntHeader : Devuelve el valor de una cabecera de tipo
entero
Devolver resultados
El objeto HttpServletResponse permite generar la respuesta para el cliente.
Se puede generar el código de resultado (404, 500, 200,...) con el método setStatus(int code)
Además, se pueden utilizar: sendError(int code, String message)
Envía un código de error (404, 500,...) y una descripción
sendRedirect(String url) Realiza una redirección a otra URL
Cabeceras de respuesta
El método setHeader(name, value) de HttpServletResponse permite enviar cabeceras al cliente
Otros métodos útiles setDateHeader(String name, long millis) setIntHeader(String name, int value) setContentType(String value) setContentLength(int value) addCookie(Cookie value)
Escribir la respuesta
En el objeto HttpServletResponse: getWriter(): devuelve un objeto
PrintWriter para escribir texto en el documento de respuesta
Utilizando el método println() de PrintWriter
getOutputStream(): devuelve el stream de respuesta, en el que se puede escribir en modo binario
Ejercicio: Servlet de imagen 1. Leer los parámetros del servlet 2. Construir una imagen
Utilizar la clase BufferedImage 3. Dibujar en la imagen
Obtener el objeto Graphics de la imagen Utilizar los métodos de Graphics (drawXXX(), fillXXX(),...)
4. Establecer la cabecera Content-Type Usar "image-jpeg"
5. Obtener el stream de salida response.getOutputStream()
6. Escribir la imagen en el stream de salida Utilizar las clases de com.sun.image.codec.jpeg
JPEGCodec: Factoría de JPEGImageEncoder, usando el método createJPEGEncoder(OutputStream stream)
JPEGImageEncoder: Permite guardar imágenes en formato JPEG con el método encode(BufferedImage img)
Configuración de la aplicación El archivo web.xml puede contener varios
tipos de valores de configuración: Parámetros de inicialización de servlet
Configuración propia de un servlet determinado Se accede a través de la configuración del servlet
Parámetros de contexto Configuración global de la aplicación Se accede través del contexto del servlet Sólo de tipo String
Entradas de entorno Configuración global de la aplicación Se accede a través de JNDI Accesibles desde cualquier clase Pueden ser String, Integer, Boolean, Double y Float
Parámetros de inicialización de servlet
Definición en web.xml
Acceso al valor desde código
<servlet> <servlet-name>...</servlet-name> <servlet-class>...</servlet-class> <init-param> <param-name>rutaFicheros</param-name> <param-value>C:\ficheros</param-value> </init-param></servlet>
<servlet> <servlet-name>...</servlet-name> <servlet-class>...</servlet-class> <init-param> <param-name>rutaFicheros</param-name> <param-value>C:\ficheros</param-value> </init-param></servlet>
String ruta = this.getServletConfig().getInitParameter("rutaFicheros");
String ruta = this.getServletConfig().getInitParameter("rutaFicheros");
Parámetros de contexto
Definición en web.xml
Acceso al valor desde código
<context-param><param-name>rutaFicheros</param-name><param-value>C:\ficheros</param-value>
</context-param>
<context-param><param-name>rutaFicheros</param-name><param-value>C:\ficheros</param-value>
</context-param>
String ruta = this.getServletContext().getInitParameter("rutaFicheros");
String ruta = this.getServletContext().getInitParameter("rutaFicheros");
Entradas de entorno
Definición en web.xml
Acceso al valor desde código
<env-entry> <env-entry-name>rutaFicheros</env-entry-name> <env-entry-value>C:\ficheros</env-entry-value> <env-entry-type>java.lang.String</env-entry-type></env-entry>
<env-entry> <env-entry-name>rutaFicheros</env-entry-name> <env-entry-value>C:\ficheros</env-entry-value> <env-entry-type>java.lang.String</env-entry-type></env-entry>
InitialContext ctx = new InitialContext();Context env = ctx.lookup("java:comp/env");String ruta = (String)env.lookup("rutaFicheros");
InitialContext ctx = new InitialContext();Context env = ctx.lookup("java:comp/env");String ruta = (String)env.lookup("rutaFicheros");
Redirigir la petición La petición se puede redirigir a otro servlet o JSP
Se utiliza el objeto RequestDispatcher El cliente (navegador) no es consciente de la redirección
Dos tipos de redirección: forward: La petición se redirige al otro servlet y se
termina el proceso en este servlet include: La petición se redirige al otro servlet y después
vuelve a este servlet
// Se obtiene el RequestDispatcher para la URL// a la que se quiere redirigir (la URL es // relativa al contexto de la aplicación)RequestDispatcher rd = request.getRequestDispatcher("/OtroServlet");rd.forward(request,response);
// Se obtiene el RequestDispatcher para la URL// a la que se quiere redirigir (la URL es // relativa al contexto de la aplicación)RequestDispatcher rd = request.getRequestDispatcher("/OtroServlet");rd.forward(request,response);
Cookies Una cookie es un valor que se proporciona al
navegador y que éste adjunta después en cada petición
Se implementan a través del objeto Cookie Se leen con getCookies() Se escriben con addCookie()
Métodos de Cookie: get/setName() get/setValue() get/setDomain() get/setPath()
Para las cookies que se leen del cliente, sólo se obtienen las propiedades Name y Value
get/setMaxAge() get/setComment() get/setSecure() get/setVersion()
Gestión de sesiones El objeto HttpSession permite almacenar información
asociada a una sesión Se obtiene con request.getSession() Se basa en cookies o reescritura de URL
Métodos: getValue(String nombre)
getAttribute(String nombre) Devuelve un valor asociado a la sesión
putValue(String nombre, Object valor)setAttribute(String nombre, Object valor)
Almacena un valor en la sesión removeValue(String nombre)
removeAttribute(String nombre) Borra un valor de la sesión
getValueNames() (array)getAttributeNames() (enumeración)
Devuelve los nombres de los valores almacenados en la sesión
Comunicación entre servlets Se pueden almacenar valores que se
compartan entre distintos servlets en diversos ámbitos
ServletContext: Los valores son globales para todos los servlets de la aplicación para cualquier usuario
HttpSession: Los valores están asociados a la sesión del usuario
HttpServletRequest: Los valores se asocian a la petición y se pueden acceder desde cualquier servlet que participe en la petición (a través de forward o execute)
Se utilizan los métodos getAttribute(nombre) y setAttribute(nombre,valor)
Se puede guardar cualquier tipo de objeto
JSP (Java Server Pages)
Evolución de los servlets Permite combinar de manera
sencilla contenido estático con contenido dinámico
El motor de JSP compila la página y genera un servlet correspondiente
Elementos de JSP Scriptlets (bloques de código)
<% código %> Se inserta en el método _jspService()
(que es llamado por service()) Expresiones
<%= expresión %> Se inserta en el resultado de la página, incluyendo
llamadas println() en _jspService Declaraciones
<%! código %> Se inserta en el cuerpo del servlet, fuera de los
métodos Comentarios
<%-- comentario --%> No se envían al cliente ni se ejecutan en servidor
Sintaxis XML En JSP se puede usar también una sintaxis XML
Expresiones <jsp:expression>
Expresión</jsp:expression>
Scriptlets <jsp:scriptlet>
Código</jsp:scriptlet>
Declaraciones <jsp:declaration>
Código</jsp:declaration>
Variables predefinidas request
Objeto petición (HttpServletRequest)
response Objeto respuesta
(HttpServletResponse) out
PrintWriter de salida session
Objeto de sesión (HttpSession)
application Objeto de aplicación
(HttpServletContext) config
Objeto ServletConfig pageContext
Contexto de la página page
La propia página (sinónimo de this)
Ejemplo de JSP: Expresiones
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"><HTML><HEAD><TITLE>Expresiones JSP</TITLE></HEAD><BODY><H2>Expresiones JSP</H2><UL><LI>Fecha/hora actual: <%= new java.util.Date() %><LI>Tu nombre de host: <%= request.getRemoteHost() %><LI>Tu ID de sesión: <%= session.getId() %><LI>El parámetro <CODE>prueba</CODE>:<%= request.getParameter("prueba") %></UL></BODY></HTML>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"><HTML><HEAD><TITLE>Expresiones JSP</TITLE></HEAD><BODY><H2>Expresiones JSP</H2><UL><LI>Fecha/hora actual: <%= new java.util.Date() %><LI>Tu nombre de host: <%= request.getRemoteHost() %><LI>Tu ID de sesión: <%= session.getId() %><LI>El parámetro <CODE>prueba</CODE>:<%= request.getParameter("prueba") %></UL></BODY></HTML>
Ejemplo de JSP: Scriptlets<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"><HTML><HEAD><TITLE>Cambio de color</TITLE></HEAD><% String bgColor = request.getParameter("bgColor");boolean tieneParametro;if (bgColor != null) {
tieneParametro = true;} else {
tieneParametro = false;bgColor = "WHITE";
}%><BODY bgcolor="<%=bgColor%>"><H2 align="center">Prueba de color</H2><% if (tieneParametro) { %>Has indicado el color <I><%=bgColor%></I><% } else { %>No has indicado color de fondo, lo muestro en blanco.<br>Usa el parámetro <I>bgColor</I> para indicar el color.<% } %></BODY></HTML>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"><HTML><HEAD><TITLE>Cambio de color</TITLE></HEAD><% String bgColor = request.getParameter("bgColor");boolean tieneParametro;if (bgColor != null) {
tieneParametro = true;} else {
tieneParametro = false;bgColor = "WHITE";
}%><BODY bgcolor="<%=bgColor%>"><H2 align="center">Prueba de color</H2><% if (tieneParametro) { %>Has indicado el color <I><%=bgColor%></I><% } else { %>No has indicado color de fondo, lo muestro en blanco.<br>Usa el parámetro <I>bgColor</I> para indicar el color.<% } %></BODY></HTML>
Ejemplo de JSP: Declaraciones
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD><TITLE>Declaraciones JSP</TITLE></HEAD><BODY><H1>Declaraciones JSP</H1><%! private int accesos = 0; %><H2>
Accesos a la página desde el último reinicio:<%= ++accesos %>
</H2></BODY></HTML>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML><HEAD><TITLE>Declaraciones JSP</TITLE></HEAD><BODY><H1>Declaraciones JSP</H1><%! private int accesos = 0; %><H2>
Accesos a la página desde el último reinicio:<%= ++accesos %>
</H2></BODY></HTML>
Directivas JSP
Las directivas afecta a la estructura del servlet resultante de una página JSP Sintaxis: <%@ directiva atributo="valor" %>
Sintaxis XML:<jsp:directive.directiva
atributo="valor" /> Existen tres directivas en JSP
page: Configuración del servlet include: Inclusión de ficheros taglib: Referencia a librerías de etiquetas
Directiva page Su función depende de los atributos que
presenta <%@ page import="..." %>
Importación de paquetes que se utilicen en el script JSP <%@ page contentType="MIME-Type" %>
Establece la cabecera Content-Type <%@ page isThreadSafe="true|false" %>
Indica si el servlet implementa el interfaz SingleThreadModel (por defecto true)
<%@ page session="true|false" %> Indica si se utilizan sesiones en la página (defecto true)
<%@ page buffer="kbytes|none" %> Tamaño del buffer de la página
Directiva page (II) <%@ page autoflush="true|false" %>
Indica si se vacía el buffer automáticamente (por defecto true)
<%@ page extends="paquete.clase" %> Especifica la clase base del servlet
<%@ page info="mensaje" %> Descripción del servlet
<%@ page errorPage="url-relativa" %> URL de la página a la que se redirige en caso de error
<%@ page isErrorPage="true|false" %> Indica si la página funciona como página de error para
otras páginas <%@ page language="java" %>
Lenguaje de la página (java es el único valor válido)
Inclusión de ficheros En tiempo de compilación:
<%@ include file="..." %> Se incluye el fichero completo y se compila junto con la
página Si se modifica el fichero incluido, hay que actualizar
todas las páginas en las que aparece En tiempo de ejecución:
<jsp:include page="..." flush="true" /> Se incluye el resultado de la ejecución de la página Se le pueden pasar parámetros a la página:
<jsp:include page="saludo.jsp" flush="true" ><jsp:param name="nombre" value="Juan" />
</jsp:include>
Inclusión de applets Para incluir un applet en JSP se utiliza la
etiqueta jsp:plugin <jsp:plugin type="applet"
code="MyApplet.class"width="..." height="...">
<jsp:parameters><jsp:param name=".."
value=".." />...
</jsp:parameters></jsp:plugin>
Esta estructura se transforma en el correspondiente bloque <OBJECT> para Java Plug-in
Paso a otra página
La ejecución de un JSP se puede transferir a otra página La ejecución del JSP se corta Si el JSP ha generado resultados, se pierden
y son sustituidos por los nuevos Se utiliza la etiqueta <jsp:forward page="..." /> Se pueden incluir parámetros como en <jsp:include>
pageContext: Acceso a objetos JSP El objeto PageContext (accesible por la
propiedad pageContext) proporciona acceso a los objetos intrínsecos de JSP ServletRequest getRequest() ServletResponse getResponse() JspWriter getOut() HttpSession getSession() ServletContext getServletContext() ServletConfig getServletConfig() Object getPage() Throwable getException()
pageContext:Almacenamiento de valores PageContext permite almacenar valores en distintos ámbitos
Object getAttribute(String name, int scope) void setAttribute(String name, Object object, int scope) void removeAttribute(String name, int scope)
Los ámbitos donde se pueden almacenar valores son: PageContext.PAGE_SCOPE: El valor es visible en la propia página PageContext.REQUEST_SCOPE: Visible en todas las páginas y
servlets que participen en el procesado de la petición (con forward o include)
PageContext.SESSION_SCOPE: Visible en todas las páginas y servlets mientras dure la sesión del cliente
PageContext.APPLICATION_SCOPE: Visible para todas las páginas y servlets de la aplicación, para cualquier sesión
Otros métodos útiles: Enumeration getAttributeNamesInScope(int scope)
Devuelve el nombre de todos los valores almacenados en un ámbito
public Object findAttribute(String name) Devuelve el valor de un atributo sin especificar el ámbito
public int getAttributesScope(String name) Devuelve el ámbito en el que está almacenado un determinado valor
pageContext:Inclusión y paso de petición
Además, PageContext tiene métodos para la inclusión de ficheros y la transferencia de la petición a otra página (forwarding) public void forward(String url) throws IOException, ServletException
public void include(String url) throws IOException, ServletException
JavaBeans
¿Qué es un JavaBean? Es una clase Java que cumple ciertas reglas Esas reglas permiten que pueda ser
utilizada de forma automatizada Reglas de un JavaBean
Debe tener un constructor vacío No debe tener variables públicas Sus propiedades deben ser accesibles por
métodos getXXX / isXXX / setXXX
Utilizar un JavaBean
La etiqueta <jsp:useBean> crea una instancia de una clase JavaBean, o da acceso a la instancia si ya existe <jsp:useBean id="nombre" class="paquete.Clase" scope="request"/>
Crea una variable nombre de tipo paquete.Clase
La variable es accesible normalmente desde el código
La instancia se almacena en el contexto de la página en el ámbito indicado (por defecto page)
Acceso a propiedades <jsp:getProperty name="bean" property="propiedad"/>
Devuelve el valor de la propiedad bean.propiedad() y lo envía al resultado de la página
Equivale a <%=bean.getPropiedad()%> <jsp:setProperty name="bean" property="propiedad"
value="valor"/> Establece el valor valor en la propiedad bean.propiedad Equivale a <% bean.setPropiedad("valor"); %> Se puede utilizar <%=..%> para establecer un valor dinámico
<jsp:setProperty name="bean" property="propiedad" param="parametro"/>
Establece el valor del parámetro parametro en la propiedad bean.propiedad
<jsp:setProperty name="bean" param="*"/> Establece el valor de las propiedades del JavaBean con el valor de
los parámetros del mismo nombre
Lenguaje de expresiones (EL) El lenguaje de expresiones es un sustituto de
las expresiones <%=..%> Una expresión EL se encierra entre ${..} Tiene acceso directo a todos los valores
almacenados en el contexto como si fuesen variables
${abc} equivale a <%=pageContext.findAttribute("abc")%>
Se puede acceder a las propiedades de los JavaBeans y realizar operaciones aritméticas
${producto.precio * lineaPedido.unidades} A las propiedades se accede directamente por el
nombre, sin usar el método getXXX
Operadores de acceso En EL existen dos operadores de acceso: el punto (.) y los
corchetes ([]) Teniendo en cuenta que var.prop equivale a var["prop"], el
comportamiento es el siguiente: Si var es null, el resultado es null (no hay
NullPointerException) Si prop es null (prop puede ser una expresión y no un literal), el
resultado es null. Si var es un Map, el resultado es var.get(prop), y null si no
existe la clave prop en el Map. Si var es un array o una lista, prop se evalúa como entero. Si no
se puede, se produce un error. Si no, el resultado es el elemento correspondiente al índice prop de la lista/array. Si prop está fuera de los límites de la lista/array, devuelve null.
Si var es un JavaBean y prop corresponde al nombre de una propiedad, el resultado es el valor de dicha propiedad. Si no, da un error.
Objetos implícitos EL pageContext
Objeto pageContext pageScope
Valores almacenados en el ámbito page
requestScope Valores almacenados en
el ámbito request sessionScope
Valores almacenados en el ámbito session
applicationScope Valores almacenados en
el ámbito application
param Valores de los
parámetros paramValues
Valores de los parámetros como arrays de String
header Valores de las cabeceras
headerValues Valores de las cabeceras
como arrays de String cookie
Valores de las cookies
Librerías de tags
JSP se puede extender utilizando librerías de etiquetas
Las etiquetas personalizadas pueden Producir contenido Modificar variables Procesar su propio contenido
Permiten separar el código del HTML
JSP Standard Tag Library JSP define una librería de tags estándar
denominada JSTL (JSP Standard Tag Library) La implementación de referencia es la del
proyecto Apache Jakarta Se compone de cuatro librerías de tags
Core: programación XML: tratamiento de ficheros XML SQL: acceso a BD Fmt: formateo de valores
Además cuenta con una librería de funciones que pueden usarse desde EL
JSTL: Core Se utiliza con la directiva
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<c:out value="..." /> Escribe un valor en la respuesta (similar a <%=..%>) Acepta EL en el atributo value
Más cómodo para obtener propiedades de beans Tiene un atributo escapeXML que añade secuencias de escape a <, >, &,... Si el valor indicado es nulo, se puede dar un valor por defecto para mostrar
<c:out value="bean.propiedad" default="No hay valor"/> <c:out value="bean.propiedad">No hay valor</c:out>
<c:set var="..." value="..." /><c:set var="...">...</c:set>
Asigna un valor a una variable Se le puede indicar el ámbito con scope="..." También se usa para establecer propiedades con la sintaxis:
<c:set target="bean" property="propiedad" value="..:"/> <c:remove var="..." scope="..." />
Elimina una variable de un ámbito determinado Si no se especifica ámbito, elimina la variable del primer ámbitos donde la
encuentre
JSTL: Core (condicionales) <c: catch var="...">...</c:catch>
Encierra las tags que contenga en un try...catch y almacena la excepción en la variable indicada
<c:if test="...">...</c:if> Realiza las acciones dentro del tag si la expresión
test evalúa a true Se puede indicar una variable que recibe el resutlado
de test <c:choose>
<c:when test="...">...</c:when><c:otherwise>...</c:otherwise>
</c:choose> Ejecuta el primer bloque en el que test devuelve true
JSTL: Core (bucles) <c:forEach var="..." start="..." end="...>
</c:forEach> Realiza un bucle for. El valor de la iteración se almacena
en la variable var y toma valores entre start y end <c:forEach var="..." items="...">
</c:forEach> Realiza un bucle sobre una colección
<c:forTokens items="..." delimiters="..." var="..."></c:forTokens>
Separa el valor especificado en items en subcadenas que se hallen separadas por cualquier carácter de delimiters
<c:forTokens items="a,b,c,d,e,f" delimiters="," var="val"></c:forTokens>
JSTL: Core (URLs) <c:url value="/track.jsp" var="trackingURL">
<c:param name="..." value="..."/> </c:url>
Formatea una URL y almacena el resultado en una variable Se le pueden indicar parámetros a añadir a la URL Se puede indicar una URL relativa de otra webapp, indicando el
argumento context="/nombre-webapp" Añade el ID de sesión si el navegador cliente no soporta cookies Si no se indica variable, escribe el resultado en la salida
<c:import url="..." /> Obtiene el resultado de la ejecución de la URL Se le puede indicar var o varReader para almacenar o leer los
contenidos en lugar de escribirlos directamente en la respuesta Acepta parámetros y contexto como <c:url> Se puede indicar un contexto (webapp)
<c:redirect url="..." /> Redirige el navegador a otra página Acepta parámetros y contexto como <c:url>
JSTL: Funciones
fn:contains fn:containsIgnoreCas
e fn:endsWith fn:escapeXml fn:indexOf fn:join fn:length fn:replace
fn:split fn:startsWith fn:substring fn:substringAfter fn:substringBefore fn:toLowerCase fn:toUpperCase fn:trim
JSTL: SQL La directiva para usar los tags de SQL es la siguiente:
<%@ taglib prefix="sql" uri="http://java.sun.com/jsp/jstl/sql"%>
<sql:setDataSource driver=".." url=".." var=".." /> Crea una conexión de BD (DataSource) driver: Clase del driver JDBC url: URL JDBC de conexión var: Variable donde se almacena el DataSource
(si no se indica se almacena como DataSource por defecto) <sql:query sql=".." var=".." dataSource=".." />
Realiza una consulta SQL y almacena el resultado en var El resultado es un RowSet, que se puede usar como JavaBean Puede recibir parámetros con etiquetas <sql:param
value=".." /> <sql:update sql=".." var=".." dataSource=".." />
Ejecuta una sentencia SQL y devuelve el número de filas afectadas Puede recibir parámetros con etiquetas <sql:param
value=".." /> <sql:transaction
dataSource="..">..</sql:transaction> Ejecuta todas las consultas que contenga dentro de una
transacción
Ejemplo JSTL: SQL<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <%@ taglib prefix="sql" uri="http://java.sun.com/jsp/jstl/sql" %> <sql:setDataSource driver="com.mysql.jdbc.Driver" url="jdbc:mysql://localhost/test?user=root" var="ds" /> <sql:query sql="select id, nombre from prueba" var="resultados" dataSource="${ds}"/> <html>
<body> <table border="4">
<tr><th>Id</th><th>Nombre</th></tr> <c:forEach var="row" items="${resultados.rows}">
<tr><td><c:out value="${row.id}"/></td> <td><c:out
value="${row.nombre}"/></td></tr> </c:forEach>
</table> </body>
</html>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <%@ taglib prefix="sql" uri="http://java.sun.com/jsp/jstl/sql" %> <sql:setDataSource driver="com.mysql.jdbc.Driver" url="jdbc:mysql://localhost/test?user=root" var="ds" /> <sql:query sql="select id, nombre from prueba" var="resultados" dataSource="${ds}"/> <html>
<body> <table border="4">
<tr><th>Id</th><th>Nombre</th></tr> <c:forEach var="row" items="${resultados.rows}">
<tr><td><c:out value="${row.id}"/></td> <td><c:out
value="${row.nombre}"/></td></tr> </c:forEach>
</table> </body>
</html>
Creación de librerías de tags
Creación de clases de etiquetas (tag handlers)
Creación del fichero descriptor de la librería (TLD)
Instalación de la librería en una aplicación web
Uso de la librería en las páginas JSP
Creación de clases etiqueta Se crea una clase que implementa el interfaz
Tag Dependiendo de las necesidades se puede
utilizar una de las clases predefinidas y extenderla:
TagSupport: Etiquetas sin contenido BodyTagSupport: Etiquetas con contenido
Se deben implementar dos métodos: doStartTag(): Se invoca cuando se encuentra la
etiqueta de apertura doEndTag(): Se invoca cuando se encuentra la
etiqueta de cierre
Ejemplo de etiqueta
package ejemplos.tags; import javax.servlet.jsp.tagext.*; import javax.servlet.jsp.*; import java.io.*; public class TagHolaMundo extends TagSupport {
public int doStartTag() throws JspException,
IOException {JspWriter out = pageContext.getOut(); out.println("<h1>Hello World!</h1>"); return SKIP_BODY;
} public int doEndTag() { return EVAL_PAGE; }
}
package ejemplos.tags; import javax.servlet.jsp.tagext.*; import javax.servlet.jsp.*; import java.io.*; public class TagHolaMundo extends TagSupport {
public int doStartTag() throws JspException,
IOException {JspWriter out = pageContext.getOut(); out.println("<h1>Hello World!</h1>"); return SKIP_BODY;
} public int doEndTag() { return EVAL_PAGE; }
}
Fichero TLD
Cuando se crea una librería de etiquetas, se debe incluir un fichero TLD (Tag Library Descriptor)
Indica las etiquetas que hay definidas en la librería<?xml version="1.0" encoding="ISO-8859-1"?> <taglib xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation=
"http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"
version="2.0"> <tlib-version>1.0</tlib-version> <short-name>ejemplos</short-name> <description>Ejemplos de tags</description> <tag>
<name>hola</name> <tag-class>ejemplos.tags.TagHolaMundo</tag-class>
<body-content>empty</body-content> </tag>
</taglib>
<?xml version="1.0" encoding="ISO-8859-1"?> <taglib xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation=
"http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"
version="2.0"> <tlib-version>1.0</tlib-version> <short-name>ejemplos</short-name> <description>Ejemplos de tags</description> <tag>
<name>hola</name> <tag-class>ejemplos.tags.TagHolaMundo</tag-class>
<body-content>empty</body-content> </tag>
</taglib>
Instalación en una aplicación Para cada librería de tags que se utilice en una
aplicación, se debe añadir una entrada <taglib> en el fichero web.xml
<taglib> <taglib-uri>/hello</taglib-uri> <taglib-location>
/WEB-INF/tld/hola.tld </taglib-location> </taglib>
Las clases de los tags se deben incluir en el directorio classes (o en lib, en forma de JAR), y el fichero TLD en la ruta indicada en web.xml
Uso en una página JSP Para utilizar una librería de tags en una
página, se incluye una directiva taglib <%@ taglib uri="/hola" prefix="mitag" %>
uri: indica la URL en la que se publica la librería, según se indica en web.xml
prefix: asocia un prefijo a las etiquetas para su uso dentro de la página
En la página se incluyen las etiquetas con el nombre <prefijo:etiqueta>
<html> <body> <mitag:hola/> </body> </html>
El nombre de la etiqueta es el definido en el TLD
Contenidos posibles de un tag
En el TLD, se indica el tipo de contenido de cada tag con <body-content> empty: la etiqueta es siempre vacía tagdependant: el contenido es
interpretado por la propia etiqueta jsp: el contenido es código JSP y
HTML interpretable por el motor JSP
Procesado del contenido Dependiendo del valor devuelto por doStartTag() y
doEndTag(), el contenido de la etiqueta es procesado de manera distinta
doStartTag() SKIP_BODY: El contenido se ignora, y se pasa directamente a
doEndTag() EVAL_BODY_INCLUDE: Envía el contenido a la respuesta y
luego ejecuta doEndTag() EVAL_BODY_BUFFERED: El contenido se procesa con los
métodos doInitBody() y doAfterBody() (BodyTagSupport) doAfterBody()
SKIP_BODY: Se pasa a doEndTag() EVAL_BODY_AGAIN: Se vuelve a procesar el contenido
doEndTag() EVAL_PAGE: Continúa la ejecución de la página JSP
contenedora SKIP_PAGE: Ignora el resto de la página JSP contenedora
Procesado del contenido (II) doInitBody() realiza tareas de inicialización doAfterBody() se lanza después de
interpretar el contenido de la etiqueta (pero sin que éste se haya enviado a la respuesta)
getBodyContent() devuelve un objeto BodyContent para procesar el contenido
El objeto BodyContent contiene los métodos: getString() devuelve el contenido en forma de String getReader() devuelve un Reader para leer el
contenido writeOut(Writer) escribe el contenido en el Writer
especificado getEnclosingWriter() devuelve el Writer asociado
al contenedor
Atributos de las etiquetas Una etiqueta puede presentar atributos
<mitag:hola nombre="Juan" /> Por cada posible atributo:
La clase debe implementar métodos de acceso como en un JavaBean
Se deben especificar con etiquetas <attribute> en el TLD
<tag> <name>hola</name> <tag-class>ejemplos.tags.TagHola</tag-class> <attribute> <name>nombre</name> <required>yes</required> </attribute> <body-content>empty</body-content> </tag>
Al ejecutar doStartTag(), las propiedades han sido inicializadas por el motor JSP
Atributos de las etiquetas (II) La etiqueta <attribute> del TLD tiene los
siguientes componentes <name>...</name>
Nombre del atributo <required>yes|no|true|false</required>
Indica si el atributo es obligatorio <type>...</type>
Tipo de datos del atributo (p.ej. java.lang.Date) <rtexprvalue>yes|no|true|false</rtexprvalue>
Indica si el atributo puede tener un valor evaluado en tiempo de ejecución
Expresión JSP: <%=...%> Expresión EL: {$...}
Interfaz SimpleTag Introducida en JSP 2.0, la interfaz SimpleTag (y
su clase SimpleTagSupport) permiten implementar tags de manera más sencilla
Sólo existe un método doTag() La implementación se basa en objetos JspFragment
Representan fragmentos de código JSP Tienen un método invoke() que recibe un Writer y
ejecuta el fragmento JSP escribiendo la salida en el Writer
Los fragmentos JSP no deben contener scriptlets ni expresiones JSP, únicamente tags y expresiones EL
Por ejemplo, getJspBody() devuelve el contenido de la etiqueta como un JspFragment
En el TLD, se debe especificar <body-content>scriptless</body-content>
Atributos en SimpleTag
Los atributos se pueden implementar como JspFragment El tipo de datos del atributo es JspFragment En el TLD se añade la etiqueta <fragment>
al atributo: <attribute> <name>atributo</name> <required>no</required> <fragment>true</fragment> </attribute>
Ficheros .tag (Tag Files) Se pueden crear tags personalizadas creando un fichero
JSP con extensión .tag Permite crear tags personalizadas sin usar Java
El fichero .tag se debe incluir En el directorio WEB-INF/tags
No necesita TLD Empaquetado en un JAR, en el directorio WEB-INF/lib
El fichero .tag debe residir en el directorio META-INF/tags del archivo JAR
Debe incluir un TLD Las etiquetas definidas en ficheros tag se importan con:
<%@ taglib prefix="tags" tagdir="/WEB-INF/tags" %>
Se llaman
Directivas de ficheros .tag
En un fichero .tag se incluyen directivas similares a las de las páginas JSP <%@ tag ... %>
Análogo a la directiva <%@page %> de JSP Permite hacer import, definir una descripción para
el tag,... <%@ attribute ... %>
Define un atributo para la etiqueta Tiene los mismos parámetros que la etiqueta
<attribute> del TLD <%@ variable ... %>
Define una variable que se exporta al JSP contenedor y puede utilizarse en variables EL cuando se llama al tag
Acciones de ficheros .tag En los ficheros .tag, se utilizan dos acciones JSP
especiales: <jsp:doBody />
Evalua el contenido de la etiqueta <jsp:invoke fragment="atributo" />
Evalúa un atributo de tipo fragment Ambas acciones pueden recibir los siguientes
parámetros var="nombreVariable"
Recoge el resultado del fragmento JSP y lo almacena en una variable de tipo String con el nombre indicado
varReader="nombreVariable" Crea una variable Reader con el nombre indicado para leer el resultado del fragmento JSP
scope="page|request|session|application"Ámbito en el que se crea la variable indicada en var o varReader
Si no reciben un parámetro var o varReader, vuelcan el resultado en la respuesta JSP
Ejemplo de fichero .tag
<%@ attribute name="imagen" %> <%@ attribute name="titular" fragment="true" %>
<table border="0"><tr>
<td><h1> <jsp:invoke fragment="titular"/> </h1>
</td><tr><tr>
<td valign="top"><img src="${imagen}"></td> <td>
<jsp:doBody /> </td>
</tr> </table>
<%@ attribute name="imagen" %> <%@ attribute name="titular" fragment="true" %>
<table border="0"><tr>
<td><h1> <jsp:invoke fragment="titular"/> </h1>
</td><tr><tr>
<td valign="top"><img src="${imagen}"></td> <td>
<jsp:doBody /> </td>
</tr> </table>
Inclusión de fichero .tag
<%@ taglib prefix="tags" tagdir="/WEB-INF/tags" %>
<tags:noticia imagen="img/noticia.jpg"> <jsp:attribute name="titular"> Nuevo tipo de <i>tags</i> </jsp:attribute>
<jsp:body> Ahora puedes crear tags de una nueva manera.<br> Bienvenido a los <b>Ficheros .tag</b>! </jsp:body></tags:noticia>
<%@ taglib prefix="tags" tagdir="/WEB-INF/tags" %>
<tags:noticia imagen="img/noticia.jpg"> <jsp:attribute name="titular"> Nuevo tipo de <i>tags</i> </jsp:attribute>
<jsp:body> Ahora puedes crear tags de una nueva manera.<br> Bienvenido a los <b>Ficheros .tag</b>! </jsp:body></tags:noticia>
Crear funciones EL
Desde EL se puede utilizar cualquier función Java
Definir una función estática Añadirla al fichero TLD// Funciones.java
package mypkg;public class Funciones {
public static String trim(String s) { return s.trim(); }}
// Funciones.javapackage mypkg;public class Funciones {
public static String trim(String s) { return s.trim(); }}
<!–- TLD -->...<function> <name>trim</name> <function-class>mypkg.Funciones</function-class> <function-signature>
java.lang.String trim(java.lang.String) </function-signature></function> ...
<!–- TLD -->...<function> <name>trim</name> <function-class>mypkg.Funciones</function-class> <function-signature>
java.lang.String trim(java.lang.String) </function-signature></function> ...
<!–- JSP --><% taglib prefix="fun" uri="..." %>...${fun:trim(nombre)} ...
<!–- JSP --><% taglib prefix="fun" uri="..." %>...${fun:trim(nombre)} ...
Buenas prácticas En las páginas JSP se debe evitar en la medida
de lo posible la mezcla de HTML con scriptlets Utilizar acciones JSP (<jsp:XXX />) Sustituir las expresiones <%=..%> por sintaxis EL Utilizar JavaBeans para almacenar los datos de los
parámetros Separar el procesado, acceso a datos, etc.. en
servlets y dejar las páginas JSP sólo para mostrar el resultado, accediendo a JavaBeans almacenados en el ámbito request
Crear etiquetas personalizadas para definir elementos reutilizables entre distintas páginas
Cabecera, menú, pie Utilizar tags JSTL para realizar bucles, condiciones,
etc...
Arquitecturas para web
Modelo 1: La petición se atiende en un JSP que construye un JavaBean y accede a objetos de negocio
Cliente JSP
JavaBean u otros servicios
Objetos de
negocio
petición
respuesta
Arquitecturas para web Modelo 2: La petición se atiende en un servlet
encargado de todo el proceso y acceso a objetos de negocio. El servlet construye un JavaBean y pasa la ejecución a un JSP que se encarga de la presentación
Cliente
Servlet JavaBean u otros servicios
Objetos de
negocio
petición
respuesta JSP
Ventajas del modelo 2 Permite separar las tareas de presentación del
procesado de datos Se basa en el patrón modelo-controlador-vista
Modelo: Contiene los datos que describen Corresponde a los JavaBeans y objetos de negocio
Vista: Muestra los datos Corresponde al JSP
Controlador: Componente que realiza operaciones con el modelo y conecta la vista con el modelo
Corresponde al servlet Da una mayor flexibilidad y facilita la
reutilización Controladores genéricos Distinta vista dependiendo del usuario
Patrones de diseñoMVC: Modelo-Vista-Controlador
Las responsabilidades se separan en tres roles Modelo: Contiene los datos de la aplicación Vista: Presenta los datos al usuario Controlador: Accede a los datos del modelo
y selecciona la vista a presentar Normalmente se implementa:
Controlador: Servlet que recibe la petición Modelo: Objetos de negocio Vista: Páginas JSP
Patrones de diseñoBusiness Facade
Ofrece métodos de negocio simplificados que encapsulan las distintas operaciones necesarias Ejemplo: añadirAlCarrito(usuario,producto)
Comprueba stock Inserta el producto en el carrito Decrementa stock
Un servlet controlador normalmente utilizará un objeto de negocio que implementa Business Facade
Patrones de diseñoDAO: Data Access Object Ofrece las operaciones de acceso a la
base de datos ocultando los detalles de implementación Tipo de base de datos Creación de conexiones, statements, etc.
Ofrece métodos de tipo: Carga Inserta Actualiza Lista Borra
Patrones de diseñoDTO: Data Transfer Objects
Objetos sencillos que almacenan los datos que se traspasan entre distintas capas
Suelen implementarse como JavaBeans Constructor vacío Métodos get/set
Los métodos de los Business Facade, DAO, etc. reciben y devuelven DTOs
Modelo
Arquitectura completa
Cliente
Servletcontrolador
DTOJavaBean
BusinessFacadepetición
respuestaJSP
vista
forward
DAO
BD
Flujo de proceso El servlet controlador recibe la petición Guarda los parámetros en un DTO y llama al
Business Facade El Business Facade realiza las operaciones de
negocio solicitadas utilizando los DAO correspondientes, y construyendo los DTO que necesite
El Business Facade compone un DTO de respuesta para el controlador
El controlador guarda los datos necesarios como atributos del objeto request y redirige la petición a la página JSP que implementa la vista correspondiente
La página JSP muestra los datos de respuesta
En Internet: http://jakarta.apache.org/
Página de la implementación de referencia de JSP
Libros: "Servlets y Java Server Pages“
Marty Hall - Pearson Educación “Java for the Web with Servlets, JSP, and
EJB” Budi Kurniawan - New Readers
Enlaces y Bibliografía