¿Qué es una JSP?
Las JavaServer Pages (JSP) nos permiten separar la parte
dinámica de nuestras páginas web del código estático.
Para ello simplemente escribimos el HTML (o XML) regular de
la forma normal, usando cualquier herramienta de construcción de págnas Web y
encerramos el código de las partes dinámicas en unas etiquetas especiales, la
mayoría de las cuales empiezan con “<%” y terminan con “%>”.
Funcionamiento
<html>
<head>
<title>Ejemplo Hola Mundo
JSP</title>
</head>
<body>
<% out.println("Hola
mundo"); %>
</body>
</html>
Funcionamiento
Elementos
Elementos de script JSP y su notación XML
Los elementos de script nos permiten insertar código Java
dentro del servlet que se generará desde la página JSP actual. Hay varias
formas:
- Expresiones de la forma <%= expresión %> que son evaluadas e insertadas en la salida.
- Scriptlets de la forma <% código %> que se insertan dentro del método service() del servlet.
- Declaraciones de la forma <%! Código %> que se insertan en el cuerpo de la clase del servlet, fuera de cualquier método existente.
- Directivas de la forma <%@ directive atributo1=”valor1”… atributoN=”valorN” %> que afectan a la estructura general del servlet generado.
- Acciones de la forma <jsp:acción /> que permiten realizar operaciones como acceso a JavaBeans, inclusión de páginas, …
Expresiones JSP
Una expresión JSP se usa para insertar valores Java
directamente en la salida. Tiene la siguiente forma:
<%= expresión Java %>
La expresión Java es evaluada, convertida a un string, e
insertada en la página. Esta evaluación se realiza durante la ejecución (cuando
se solicita la página) y así tiene total acceso a la información sobre la
solicitud. Por ejemplo, esto muestra la fecha y hora, del servidor, en que se
solicitó la página:
Current time: <%= new java.util.Date()
%>
Notación XML:
<jsp:expression> Expresión Java
</jsp:expression>
Ejemplo
Expresiones.jsp:
<!DOCTYPE
HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<TITLE>Ejemplo1: Expresiones</TITLE>
</HEAD>
<BODY>
<H2>Ejemplos de expresiones
JSP</H2>
<UL>
<LI>Hora actual en el servidor:
<%= new java.util.Date() %>
<LI>Nombre del host: <%=
request.getRemoteHost() %>
<LI>Identificador de sesion:
<%= session.getId() %>
<LI>Valor del parametro
testParam:
<%=
request.getParameter("testParam") %>
</UL>
</BODY>
</HTML>
Scriptlets JSP
Si queremos hacer algo más complejo que insertar una simple
expresión, los Scriptlets JSP nos
permiten insertar código Java arbitrario dentro del método servlet que será
construido al generar la página. Los scriptlets tienen la siguiente forma:
<% Código Java %>
El código dentro de un scriptlet se insertará exactamente
como está escrito, y cualquier HTML estático anterior o posterior al scriptlet
se convierte en sentencias print(). Por tanto no
se necesita completar las sentencias Java, y los bloques abiertos pueden
afectar al HTML estático fuera de los scriptlets.
Notación XML:
<jsp:scriptlet>Código</jsp:scriptlet>
Ejemplo BGColor.jsp:
<!DOCTYPE
HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<TITLE>Color de Fondo</TITLE>
</HEAD>
<%
String bgColor =
request.getParameter("bgColor");
boolean hasExplicitColor;
if (bgColor != null) {
hasExplicitColor = true;
} else {
hasExplicitColor = false;
bgColor = "WHITE";
}
%>
<BODY BGCOLOR="<%= bgColor %>">
<H2 ALIGN="CENTER">Color de Fondo</H2>
<%
if (hasExplicitColor) {
out.println("Establecido
el color de fondo:" + bgColor + ".");
} else {
out.println("Usando los
colores de fondo por defecto.");
}
%>
</BODY>
</HTML>Declaraciones JSP
Una declaración JSP nos permite definir método o atributos
que serán insertados dentro del cuerpo principal de la clase servlet (fuera del
método service() que procesa la petición).
Tiene la siguiente forma:
<%! Código Java %>
Como las declaraciones no generan ninguna salida,
normalmente se usan en conjunción con expresiones JSP o Scriptlets.
Notación XML:
<jsp:declaration>Código</jsp:declaration>
Ejemplo
ContadorDeAccesos.jsp
<!DOCTYPE
HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<TITLE>Ejemplo3: Declaraciones
JSP</TITLE>
</HEAD>
<BODY>
<H1>Declaraciones JSP</H1>
<%! private int accessCount = 0; %>
<H2>Número de accesos
al servidor desde que se inició:
<%= ++accessCount %></H2>
</BODY>
</HTML>
Comentarios
- è Comentarios ocultos JSP. Estos comentarios no son visibles en la página generada y tienen la forma
<%-- texto --%>
- è Comentarios visibles JSP: Estos comentarios son visibles en la página generada, incluso se pueden mezclar con expresiones JSP:
<!—texto [<%=expresión JSP%>] -->
Directivas
Una directiva JSP afecta a la estructura general de la clase
servlet que resulta de la compilación de la JSP. Normalmente tienen la
siguiente forma:
<%@ directive atributo1=”valor1”
atributo2=”valor2”… atributoN=”valorN” %>
Notación XML:
<jsp:directive.TIPO_DE_DIRECTIVA
atributo1=”valor1” atributo2=”valor2”… atributoN=”valorN” />
Hay tres tipos de directivas:
- page, que nos permite hacer cosas como importar clases, personalizar la superclase del servlet, establecer el tipo de contenido, etc.
- include, que nos permite insertar un fichero dentro de la clase servlet en el momento que el fichero JSP es traducido a un servlet.
- taglib, que nos permite definir etiquetas personalizadas.
Directiva page
La directiva page
dirige al motor Servlet’s sobre la configuración general de la página.
Nos permite definir uno o más de los siguientes atributos
aplicables a toda la página.
<%@
page [import=“{paquete.class |
paquete.*},…”]
[session=“true|false”]
[contentType=“tipoMime”[;charset=Character-Set]” |
“text/html;charset=ISO-8859-1”]
[pageEncoding="characterSet |
ISO-8859-1“]
[errorPage=“URL”]
[isErrorPage=“true|false”]
[isThreadSafe=“true|false”]
[language=“java”]
[extends=“paquete.class”]
[buffer=“none”|8kb|sizekb”]
[autoFlush=“true|false”]
[info=“texto”]
%>
Atributo import
El atributo import
nos permite especificar los paquetes que deberían ser importados. Si no se
especifica nada en el servlet se importan los siguientes paquetes por defecto:
- java.lang.*
- javax.servlet.*
- javax.servlet.jsp.*
- javax.servlet.http.*
Puede aparecer de una de las siguientes formas:
<%@ page
import=”paquete.clase”%>
<%@ page import=”paquete.clase1,
…, paquete.claseN”%>
El atributo import
es el único que puede aparecer más de una vez dentro de una JSP.
Ejemplo
AtributoImport.jsp:
<!DOCTYPE
HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<TITLE>Ejemplo1: Directiva
page. Atributo import</TITLE>
</HEAD>
<BODY>
<H2>Ejemplo1: Directiva
page. Atributo import </H2>
<%@ page
import="java.util.*,servletsyjsps.*"
%>
<%-- Declaraciones
JSP --%>
<%!
private String randomID() {
int num = (int)(Math.random()*10000000.0);
return("id" + num);
}
private final String NO_VALUE = "<I>No
Value</I>";
%>
<%-- Scriptlet
JSP --%>
<%
Cookie[] cookies
= request.getCookies();
String oldID =
ServletUtilities.getCookieValue(cookies,
"userID", NO_VALUE);
String newID;
if
(oldID.equals(NO_VALUE)) {
newID =
randomID();
} else {
newID =
oldID;
}
LongLivedCookie
cookie = new LongLivedCookie("userID", newID);
response.addCookie(cookie);
%>
<%-- Expresiones
JSP --%>
La última
vez que se accedió a esta página fue
<%= new Date() %> con un
id de
usuario <%= oldID %>.
</BODY>
</HTML>
Atributo sesión
El atributo session
indica si la página JSP participa o no en una sesión HTTP.
Puede tomar los valores:
<%@page
session=”true|false”%>
Un valor true
(valor por defecto) indica que la variable predefinida session (del tipo
HttpSession) debería unirse a la sesión existente si existe una, y si no existe
se debería crear una nueva sesión para unirla.
Un valor de false
indica que no se usarán sesiones.
Atributo contentType
El atributo contentType
especifica el tipo MIME de la salida. El valor por defecto es text/html e ISO-8859-1.
Puede aparecer de una de las siguientes formas
<%page
contentType=”tipoMime”[;charset=Character-Set]”%>
Ejemplo Excel.jsp
<%@ page contentType="application/vnd.ms-excel"
%>
<%-- Hay que poner tabuladores entre
los datos no espacios. --%>
1997 1998 1999 2000 2001 (Anticipated)
12.3 13.4 14.5 15.6 16.7
Atributo pageEncoding
El atributo pageEncoding
especifica el juego de caracteres que usará la página JSP para el response.
El atributo puede aparecer de las formas:
<%@page pageEncoding=”characterSet |
ISO-8895-1”%>
El valor por defecto es ISO-8859-1.
Atributos errorPage,
isErrorPage
El atributo errorPage
espeficica una página JSP que se debería procesar si se lanzará cualquier
Throwable pero no fuera capturado en la página actual.
Si el Path empieza con “/”, el path es relativo
al directorio raíz de documentos de la aplicación JSP y es resulto por el
servidor Web. Si no, el path es relativo al fichero JSP actual.
El atributo isErrorPage
indica si la página actual actúa o no como página de error de otra página JSP.
El atributo puede tomar los valores:
<%@page isErrorPage=”true|false”%>
Si es true,
podemos usar el objeto exception,
que contiene una referencia a la excepción lanzada, en el fichero JSP.
Si es false
(valor por defecto), significa que no podemos usar el objeto exception en el fichero JSP.
Ejemplo Velocidad.jsp
<!DOCTYPE
HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<TITLE>Ejemplo 3: Directiva
page</TITLE>
</HEAD>
<BODY>
<%@ page
errorPage=“VelocidadError.jsp"
%>
<%!
// Observa que se
lanzará un excepcion NumberFormatException si el valor es nulo o
// esta mal
formateado
private double toDouble(String
value) {
return(Double.valueOf(value).doubleValue());
}
%>
<%
double espacio =
toDouble(request.getParameter("espacio"));
double tiempo =
toDouble(request.getParameter("tiempo"));
double speed = espacio/tiempo;
%>
<UL>
<LI>Espacio: <%= espacio %>.</LI>
<LI>Tiempo: <%= tiempo %>.</LI>
<LI>Velocidad: <%= speed %></LI>
</UL>
</BODY>
</HTML>
Atributo extends
El atributo extends
indica el nombre, totalmente cualificado, de la superclase del servelt que
resulta de compilar la página JSP.
<%@ page extends=”paquete.class” %>
Sun recomienda que usemos este atributo con cautela, ya que
puede limitar la habilidar del motor del JSP.
Directiva include
La directiva include
nos permite incluir ficheros en el momento en que la página JSP es compilada a
un servlet. La directiva include tiene la forma:
<%@ include file=”relativeURL”%>
Observar que la directiva include incluye el fichero en el momento de la compilación. Por
tanto, si la página incluida cambia después de la compilación, los cambios no
se verán reflejados en la página actual hasta que se vuelva a compilar.
Ejemplo directias:
- è Fichero Velocidad.jsp
<html>
<head>
<title>Ejemplo de un include</title>
</head>
<body bgcolor="white">
<font color="blue">
Fecha y
hora actual: <%@
include file=“Date.jsp" %>
</font>
</body>
</html>
- è Fichero Date.jsp
<%@
page import="java.util.*"
%>
<%= (new Date() ).toLocaleString() %>
Directiva taglib
Gracias a la directiva taglib
podemos definir nuestros propios tags JSP, y a un conjunto de tags JSP lo
llamaremos librería de tags.
Para definir un tag necesitamos definir cuatro componentes:
- Una clase que defina el comportamiento del tag.
- Un fichero TLD (Tag Library Descriptor) para hacer visible la clase en el servidor.
- Un fichero web.xml para hacer visible el tag en el servidor.
- Un fichero JSP que use el tag.
Objetos implícitos
Para simplificar el código en las expresiones y scriptlets
JSP, tenemos 9 variables definidas automáticamente:
request. Este es el objeto de la clase
HttpServletRequest asociado con la petición, y nos permite mirar los parámetros
de la petición (mediante el método getParameter),
el tipo de petición (GET, POST, HEAD, etc.),
y las cabeceras HTTP entrantes (cookies, referer, etc.). Estrictamente
hablando, se permite que la petición sea una subclase de ServletRequest distinta de HttpServletRequest, si el protocoolo de
la petición es distinto del HTTP, aunque esto casi nunca se lleva a la
práctica.
response. Este es el objeto de la clase
HttpServletResponse asociado con la
respuesta al cliente. Observa que, como el stream de salida (ver out más abajo)
tiene un buffer, es legal seleccionar los código de estado y cabeceras de
respuesta, aunque no está permitido en los Servlets normales una vez que la
salida ha sido enviada al cliente.
out. Este es el PrintWriter usado para enviar la salida al cliente. Sin embargo,
para poder hacer útil el objeto response (ver punto anterior), esta es una
versión con buffer de PrintWriter
llamada JSPWriter. Podemos ajustar
el tamaño del buffer, o incluso desactivar el buffer, usando el atributo buffer
de la directiva page. out se usa casi exclusivamente en
scriptlets ya que las expresiones JSP obtienen un lugar en el stream de salida,
y por eso raramente se refieren explícitamente a out.
session. Este es el objeto de la clase HttpSession asociado con la petición.
Las sesiones se crean automáticamente. Por esto esta variable se una incluso si
no hubiera una sesión de referencia entrante. Como veremos, la única excepción
es usar el atributo session de la
directiva page para desactivar las
sesiones, en cuyo caso los intentos de referenciar la variable session causarán un error en el momento
de traducir la página JSP a un servlet.
application. Es el objeto de la clase ServletContext obtenido mediante getServletConfig().getContext().
config. Es el objeto de la clase ServletConfig para la página actual.
pageContext. Es el objeto de la clase PageContext. Este objeto es usado por
el motor de Servlet’s para administrar características como páginas de error y
los parámetros para hacer include o forwards de páginas.
exception. Es un objeto de la clase Throwable. Solo se crea en el caso en
el que usemos la directiva <%@page
ErrorPage=”true”%>
Estas variables reciben el nombre de objetos implícitos en una JSP.
JavaBeans y JSP
Las acciones que restan hacen referencia a la reutilización
de componentes JavaBeans.
Características de un JavaBean:
- Una clase Bean no debería tener variables de instancia públicas.
- En la clase Bean tienen que aparecer métodos getXxx/setXxx para establecer u obtener los valores de sus propiedades.
Acción useBean
La acción <jsp:useBean>
nos permite localizar o instanciar un JavaBean en la página JSP. La sintaxis
más simple para especificar que se debería usar un Bean es:
<jsp:useBean id=”nombre”
class=”paquete.clase”/>
Con esto conseguimos localizar o instanciar un objeto, de la
clase especificada por “class”, y
enlazarlo con una variable, con el nombre especificado en “id”.
También se puede especificar un atributo “scope” que hace que el bean se asocie
con más de una página. En este caso, es útil obtener referencias a los beans
existentes, y la acción jsp:useBean especifica que se instanciará un nuevo
objeto si no existe uno con el mismo nombre y ámbito.
La sintaxis completa de la acción <jsp:useBean> es:
<jsp:useBean id=“nombreDeInstanciaDelBean"
scope="page|request|session|application"
{
class="paquete.clase"
[ type="paquete.clase"
] |
beanName="{paquete.clase
| %= expression %}"
type="paquete.clase"
|
type="paquete.clase"
}
{ /> | > otros elementos
</jsp:useBean> }
Atributos
El atributo id es
el nombre de la variable que identifica al bean en un determinado ámbito (page,
request, session, application).
El atributo scope=”page|request|session|application”
determina el ámbito en el que el bean existe.
- page: El bean solo está disponible para la página actual (valor por defecto)
- request: El bean solo está disponible para la petición actual del cliente.
- session: El bean está disponible para todas las páginas durante el tiempo de vida de la sesión.
- application: El bean está disponible para todas las páginas que comparten el mismo ServletContext.
El atributo class nos
dice el nombre de la clase del bean que se instancia. La clase no debe ser
abstracta y debe tener un constructor vacío.
El atributo type
hace que se instancia el bean con un tipo diferente al que se crea. El valor de
type debe ser el nombre de una
superclase del bean o el nombre de una interface que implemente la clase del
bean. Si usamos Type sin class o beanName el bean no se instancia.
El atributo beanName
da el nombre del bean, como lo suministraríamos en el método instantiate de Beans. Está permitido suministrar un type y un beanName, y
omitir el atributo class.
Acción setProperty
Usamos jsp:setProperty
para establecer los valores de las propiedades de los beans que se han
referenciado anteriormente con la acción jsp:useBean.
Además valor de id en jsp:useBean debe coincidir con el valor
de name en jsp:setProperty. La sintaxis completa de la acción es:
<jsp:setProperty name="nombreDeInstanciaDelBean"
{
property="*"|
property="nombrePropiedad"[param="nombreParametro"]|
property="nombrePropiedad"
value="{stringLiteral
| %=expresion %}"
}
/>
Atributos
El atributo name
designa el bean cuya propiedad va a ser establecida. El elemento jsp:useBean debe aparecer antes del
elemento jsp:setProperty.
El atributo property=”*”
almacena todos los valores de los parámetros de la petición en propiedades del
bean. Para ello, los nombres de las propiedades del bean deben coincidir con
los nombres de los parámetros de la petición.
Si un parámetro de la request es null o está vacío, la propiedad
equivalente no se establece a ningún valor, y si el bean tiene una propiedad
que no corresponde con ningún parámetro de la petición, la propiedad no se
establece a ningún valor.
Property=”nombrePropiedad”
[param=”nombreParametro”]
Con estos atributos podemos establecer una
propiedad del bean con uno de los parámetros de la request.
Si los valores de property y param
coinciden, podemos omitir el atributo param,
y si el parámetro de la request tiene un valor vacío o null, el valor de la
propiedad del bean equivalente no se establece.
Property=”nombrePropiedad”
value=”{stringLiteral | %= expresión %}”
Con este atributo podemos establecer la
propiedad de un bean con un valor específico.
Si el valor es de tipo String, se convertirá
al tipo de la propiedad del bean siguiendo las normas de la tabla mostrada
abajo.
Si el valor es una expresión, el tipo de la
expresión debe coincidir con el tipo de la propiedad del bean
Acción getProperty
La acción jsp:getProperty
obtiene el valor de una propiedad de un bean, usando el método getter del bean,
e inserta su valor en la respuesta.
Antes de usar esta acción debe aparecer una acción jsp:useBean para instanciar o localizar
el bean.
La sintaxis completa de la acción es:
<jsp:getProperty
name="nombreDeInstanciaDelBean"
property="nombrePropiedad"/>
Atributos
El atributo name designa el bean cuya propiedad va
a ser seleccionada. El elemento jsp:useBean
debe aparecer antes del elemento jsp:setProperty
y el valor de id en jsp:useBean debe coincidir con el valor
de name en jsp:setProperty.
El atributo property indica el nombre de la
propiedad del bean que queremos obtener. Si al obtener el valor de la propiedad
resulta que es null, se lanza una
excepción de tipo NullPointerException.
EJEMPLO STRINGBEAN:
StringBean.java
package servletsyjsps;
public class StringBean {
private String mensaje = “Mensaje
vacio";
public String getMensaje()
{
return(mensaje);
}
public void setMensaje(String mensaje) {
this.mensaje = mensaje;
}
}
StringBean.jsp
<!DOCTYPE
HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<TITLE>Ejemplo 1: StringBean</TITLE>
</HEAD>
<BODY>
<jsp:useBean id="stringBean"
class=“servletsyjsps.StringBean" />
<OL>
<LI>Valor inicial
(getProperty):
<I><jsp:getProperty name="stringBean"
property="mensaje" /></I>
<LI>Valor inicial
(Expresion JSP):
<I><%= stringBean.getMensaje()
%></I>
<LI><jsp:setProperty name=“stringBean”
property=“mensaje”
value=“Valor actualizado con
setProperty”
/>
Valor después
de establecer la propiedad con setProperty:
<I><jsp:getProperty name="stringBean"
property="mensaje" /></I>
</OL>
</BODY>
</HTML>
Taglibs
Gracias a la directiva tablib podemos definir nuestros propios
tags JSP.
A un conjunto de tags JSP
lo llamaremos librería de tags.
Para definir un tag
necesitamos definir cuatro componentes:
- Una clase que defina el comportamiento del tag.
- Un fichero TLD (Tag Library Descriptor) para hacer visible la clase en el servidor.
- Un fichero web.xml para hacer visible el tag en el servidor.
- Un fichero JSP que use el tag.
La sintaix completa de la directiva taglib es:
<%@ taglib uri=”URIForLibrary” prefix=”tagPrefix”
%>
El atributo uri
define donde se localiza el fichero TLD, y puede ser una URL, un URN o un PATH
absoluto o relativo.
Si la URI es una URL, entonces el TLD es localizado por
medio del mapping definido dentro del fichero web.xml.
Si la URI es un path, entonces es interpretado como un
acceso relativo a la raí de la aplicación y debería resolverser en un fichero
TLD directamente, o un fichero .jar que contiene el fichero TLD.
Ejemplo Hola Mundo
Hola.jsp
<HTML>
<HEAD>
<%@ taglib
uri=“Hola.tld” prefix=“test” %>
<TITLE><test:HolaMundo /></TITLE>
</HEAD>
<BODY>
<H1> <test:HolaMundo /></H1>
</BODY>
</HTML>
Hola.tld
<?xml version="1.0" encoding="ISO-8859-1"
?>
<!DOCTYPE
taglib PUBLIC"-//Sun Microsystems, Inc.//DTD JSP Tag Library
1.1//EN" “http://java.sun.com/j2ee/dtds/web-jsptaglib_1_1.dtd" />
<taglib>
<jspversion>1.1</jspversion>
<tlibversion>1.0</tlibversion>
<shortname>simplehola</shortname>
<urn></urn>
<info>Mi primera librería de
tags</info>
<tag>
<name>HolaMundo</name>
<tagclass>Hola</tagclass>
<body-content>empty</body-content>
<info>Mi Hola Mundo Tag</info>
</tag>
</taglib>
Web.xml
<?xml version="1.0" encoding="ISO-8859-1"
?>
<!DOCTYPE
taglib PUBLIC"-//Sun Microsystems, Inc.//DTD Web Application
2.2//EN" “http://java.sun.com/j2ee/dtds/web-app_2_2.dtd">
<web-app>
<display-name> Aplicación Hola Mundo
</ display-name>
<description> Librerías de tags de
la aplicación </description>
<taglib>
<taglib-uri>/Hola.tld </taglib-uri>
<taglib-location>/WEB-INF/Hola.tld </taglib-location>
</taglib>
</web-app>
Hola.java
import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*;
import java.io.*;
public class Hola extends TagSupport {
public int doStartTag() {
try {
JspWriter
out = pageContext.getOut();
out.print(“Hola
Mundo”);
} catch (IOException ioe) {
System.out.println(“Error
en Hola Mundo”);
}
return (SKIP_BODY);
}
}
Y el resultado final sería
este:
0 comentarios:
Publicar un comentario