Thanks for ordering
<I><%= request.getParameter("title") %></I>
Normalmente daremos a nuestro fichero una extensión .jsp, y normalmente lo instalaremos en el mismo sitio que una página Web normal. Aunque lo que escribamos frecuentemente se parezca a un ficheor HTML normal en vez de un servelt, detrás de la escena, la página JSP se convierte en un servlet normal, donde el HTML estático simplemente se imprime en el stream de salida estándard asociado con el método service del servlet. Esto normalmente sólo se hace la primera vez que se solicita la página, y los desarrolladores pueden solicitar la página ellos mismos cuando la instalan si quieren estar seguros de que el primer usuario real no tenga un retardo momentáneo cuando la página JSP sea traducida a un servlet y el servlet sea compilado y cargado. Observa también, que muchos servidores Web nos permiten definir alias para que una URL que parece apuntar a un fichero HTML realmente apunte a un servelt o a una página JSP.
Además de el HTML normal, hay tres tipos de construcciones JSP que embeberemos en una página: elementos de script, directivas y acciones. Los elementos de script nos permiten especificar código Java que se convertirá en parte del servlet resultante, las directivas nos permiten controlar la estructura general del servlet, y las acciones nos permiten especificar componentes que deberían ser usuados, y de otro modo controlar el comportamiento del motor JSP. Para simplificar los elementos de script, tenemos acceso a un número de variables predefinidas como request del fragmento de código anterior.
Nota: este tutorial cubre la versión 1.0 de la especificación JSP 1.0.
| Elemento JSP | Síntaxis | Interpretación | Notas
| Expresión JSP
| <%= expression %> La Expresión es evaluada y situada en la salida.
| El equivalente XML es
| <jsp:expression> expression </jsp:expression>. Las variables predefinidas son request, response, out, session, application, config, y pageContext. Scriptlet JSP
| <% code %> El código se inserta en el método service.
| El equivalente XML es:
| <jsp:scriptlet> code </jsp:scriptlet>. Declaración JSP
| <%! code %> El código se inserta en el cuerpo de la clase del servlet, fuera del método service.
| El equivalente XML es:
| <jsp:declaration> code </jsp:declaration>. Directiva page JSP
| <%@ page att="val" %> Dirige al motor servlet sobre la configuración general.
| El equivalente XML es:
| <jsp:directive.page att="val"\>. Los atributos legales son (con los valores por defecto en negrita):
Directiva include JSP
| <%@ include file="url" %> Un fichero del sistema local se incluirá cuando la página se traduzca a un Servlet.
| El equivalente XML es:
| <jsp:directive.include file="url"\>. La URL debe ser relativa. Usamos la acción jsp:include para incluir un fichero en el momento de la petición en vez del momento de la tradución. Comentario JSP
| <%-- comment --%> Comentario ignorado cuando se traduce la página JSP en un servlet.
| Si queremos un comentario en el HTML resultante, usamos la síntaxis de comentario normal del HTML <-- comment -->.
| Acción jsp:include
| <jsp:include
page="relative URL"
flush="true"/>
Incluye un fichero en el momento en que la página es solicitada.
| Aviso: en algunos servidores, el fichero incluido debe ser un fichero HTML o JSP, según determine el servidor (normalmente basado en la extensión del fichero).
| Acción jsp:useBean
| <jsp:useBean att=val*/>
o
Encuentra o construye un Java Bean.
| Los posibles atributos son:
|
Acción jsp:setProperty
| <jsp:setProperty att=val*/> Selecciona las propiedades del bean, bien directamenteo o designando el valor que viene desde un parámetro de la petición.
| Los atributos legales son:
|
Acción jsp:getProperty
| <jsp:getProperty
name="propertyName"
value="val"/>
Recupera y saca las propiedades del Bean.
|
| Acción jsp:forward
| <jsp:forward
page="relative URL"/>
Reenvía la petición a otra página.
|
| Acción jsp:plugin
| <jsp:plugin
attribute="value"*>
...
</jsp:plugin>
Genera etiquetas OBJECT o EMBED, apropiadas al tipo de navegador, pidiendo que se ejecute un applet usando el Java Plugin.
|
| |
|---|
La única excepción a la regla de que "la plantilla de texto se pasa tal y como es" es que, si queremos tener "<%" en la salida, necesitamos poner "<\%" en la plantilla de texto.
La expresión Java es evaluada, convertida a un string, e insertada en la página. Esta evaluación se ejecuta 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 en que se solicitó la página:<%= expresión Java %>
Para simplificar estas expresiones, hay un gran número de variables predefinidas que podemos usar. Estos objetos implícitos se describen más adelante con más detalle, pero para el propósito de las expresiones, los más importantes son:Current time: <%= new java.util.Date() %>
Finalmente, observa que los autores de XML pueden usar una síntaxis alternativa para las expresiones JSP:Your hostname: <%= request.getRemoteHost() %>
Recuerda que los elementos XML, al contrario que los del HTML, son sensibles a las mayúsculas; por eso asegúrate de usar minúsculas.<jsp:expression> Expresión Java </jsp:expression>
Los Scriptlets tienen acceso a las mismas variables predefinidas que las expresiones. Por eso, por ejemplo, si queremos que la salida aparezca en la página resultante, tenemos que usar la variable out:<% Código Java %>
<%
String queryData = request.getQueryString();
out.println("Attached GET data: " + queryData);
%>
Observa que el código dentro de un scriptlet se insertará exactamente como está escrito, y cualquier HTML estático (plantilla de texto) anterior o posterior al scriptlet se convierte en sentencias print. Esto significa que los scriptlets no necesitan completar las sentencias Java, y los bloques abiertos pueden afectar al HTML estático fuera de los scriplets. Por ejemplo, el siguiente fragmento JSP, contiene una mezcla de texto y scritplets:
<% if (Math.random() < 0.5) { %>
Have a <B>nice</B> day!
<% } else { %>
Have a <B>lousy</B> day!
<% } %>
que se convertirá en algo como esto:
if (Math.random() < 0.5) {
out.println("Have a <B>nice</B> day!");
} else {
out.println("Have a <B>lousy</B> day!");
}
Si queremos usar los caracteres "%>" dentro de un scriptlet, debemos poner "%\>". Finalmenten, observa que el equivalente XML de
<% Código %> es
<jsp:scriptlet> Código </jsp:scriptlet>
Como las declaraciones no generan ninguna salida, normalmente se usan en conjunción con expresiones JSP o escriptlets. Por ejemplo, aquí tenemos un fragmento de JSP que imprime el número de veces que se ha solicitado la página actual desde que el servidor se arrancó (o la clase del servelt se modificó o se recargó):<%! Código Java%>
Como con los scriptlet, si queremos usar los caracteres "%>", ponemos "%\>". Finalmente, observa que el equivalente XML de <%! Código %> es:<%! private int accessCount = 0; %> Accesses to page since server reboot: <%= ++accessCount %>
<jsp:declaration> Código </jsp:declaration>
Sin embargo, también podemos combinar múltiples selecciones de atributos para una sola directiva, de esta forma:<%@ directive attribute="value" %>
<%@ directive attribute1="value1"
attribute2="value2"
...
attributeN="valueN" %>
Hay dos tipos principales de directivas: page, que nos permite hacer cosas como importar clases, personalizar la superclase del servlet, etc. e include, que nos permite insertar un fichero dentro de la clase servlet en el momento que el fichero JSP es traducido a un servlet. La especificación también menciona la directiva taglib, que no está soportada en JSP 1.0, pero se pretende que permita que los autores de JSP definan sus propias etiquetas. Se espera que sea una de las principales contribuciones a JSP 1.1.
Por ejemplo, el equivalente XML de:<jsp:directive.TipoDirectiva atributo=valor />
es:<%@ page import="java.util.*" %>
<jsp:directive.page import="java.util.*" />
La URL especificada normalmente se interpreta como relativa a la página JSP a la que se refiere, pero, al igual que las URLs relativas en general, podemos decirle al sistema que interpreta la URL reltativa al directorio home del servidor Web empezando la URL con una barra invertida. Los contenidos del fichero incluido son analizados como texto normal JSP, y así pueden incluir HTML estático, elementos de scdript, directivas y acciones.<%@ include file="url relativa" %>
Por ejemplo, muchas sites incluyen una pequeña barra de navegación en cada página. Debido a los problemas con los marcos HTML, esto normalmente se implementa mediante una pequeña tabla que cruza la parte superior de la página o el lado izquierdo, con el HTML repetido para cada página de la site. La directiva include es una forma natural de hacer esto, ahorrando a los desarroladores el mantenimiento engorroso de copiar realmente el HTML en cada fichero separado. Aquí tenemos un código representativo:
<!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>
Observa que como la directiva include inserta los ficheros en el momento en que la página es traducida, si la barra de navegación cambia, necesitamos re-traducir todas las páginas JSP que la refieren. Esto es un buen compromiso en una situación como esta, ya las barras de navegación no cambian frecuentemente, y queremos que el proceso de inclusión sea tan eficiente como sea posible. Si, sin embargo, los ficheros incluidos cambian de forma más frecuente, podríamos usar la acción jsp:include en su lugar. Esto incluye el fichero en el momento en que se solicita la página JSP, como se describe en la sección 8.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<TITLE>Using JavaServer Pages</TITLE>
<META NAME="author" CONTENT="Marty Hall -- hall@apl.jhu.edu">
<META NAME="keywords"
CONTENT="JSP,JavaServer Pages,servlets">
<META NAME="description"
CONTENT="A quick example of the four main JSP tags.">
<LINK REL=STYLESHEET
HREF="My-Style-Sheet.css"
TYPE="text/css">
</HEAD>
<BODY BGCOLOR="#FDF5E6" TEXT="#000000" LINK="#0000EE"
VLINK="#551A8B" ALINK="#FF0000">
<CENTER>
<TABLE BORDER=5 BGCOLOR="#EF8429">
<TR><TH CLASS="TITLE">
Using JavaServer Pages</TABLE>
</CENTER>
<P>
Some dynamic content created using various JSP mechanisms:
<UL>
<LI><B>Expression.</B><BR>
Your hostname: <%= request.getRemoteHost() %>.
<LI><B>Scriptlet.</B><BR>
<% out.println("Attached GET data: " +
request.getQueryString()); %>
<LI><B>Declaration (plus expression).</B><BR>
<%! private int accessCount = 0; %>
Accesses to page since server reboot: <%= ++accessCount %>
<LI><B>Directive (plus expression).</B><BR>
<%@ page import = "java.util.*" %>
Current date: <%= new Date() %>
</UL>
</BODY>
</HTML>
Aquí tenemos un resultado típico:
Al contrario que la directiva include, que inserta el fichero en el momento de la conversión de la página JSP a un Servlet, esta acción inserta el fichero en el momento en que la página es solicitada. Esto se paga un poco en la eficiencia, e imposiblita a la página incluida de contener código JSP general (no puede seleccionar cabeceras HTTP, por ejemplo), pero se obtiene una significante flexibilidad. Por ejemplo, aquí tenemos una página JSP que inserta cuatro puntos diferentes dentro de una página Web "What's New?". Cada vez que cambian las líneas de cabeceras, los autores sólo tienen que actualizar los cuatro ficheros, pero pueden dejar como estaba la página JSP principal.<jsp:include page="relative URL" flush="true" />
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<TITLE>What's New</TITLE>
<LINK REL=STYLESHEET
HREF="My-Style-Sheet.css"
TYPE="text/css">
</HEAD>
<BODY BGCOLOR="#FDF5E6" TEXT="#000000" LINK="#0000EE"
VLINK="#551A8B" ALINK="#FF0000">
<CENTER>
<TABLE BORDER=5 BGCOLOR="#EF8429">
<TR><TH CLASS="TITLE">
What's New at JspNews.com</TABLE>
</CENTER>
<P>
Here is a summary of our four most recent news stories:
<OL>
<LI><jsp:include page="news/Item1.html" flush="true"/>
<LI><jsp:include page="news/Item2.html" flush="true"/>
<LI><jsp:include page="news/Item3.html" flush="true"/>
<LI><jsp:include page="news/Item4.html" flush="true"/>
</OL>
</BODY>
</HTML>
Aquí tenemos un resultado típico:
Esto normalmente significa "ejemplariza un objeto de la clase especificada por class, y unelo a una variable con el nombre especificado por id". Sin embargo, también podemos especifar un atributo scope que hace que ese Bean se asocie con más de una sóla página. En este caso, es útil obtener referencias a los beans existentes, y la acción jsp:useBean especifica que se ejemplarizará un nuevo objeto si no existe uno con el el mismo nombre y ámbito.<jsp:useBean id="name" class="package.class" />
Ahora, una vez que tenemos un bean, podemos modificar sus propiedades mediante jsp:setProperty, o usando un scriptlet y llamando a un método explícitamente sobre el objeto con el nombre de la variable especificada anteriormente mediante el atributo id. Recuerda que con los beans, cuando decimos "este bean tiene una propiedad del tipo X llamada foo", realmente queremos decir "Esta clase tiene un método getFoo que devuelve algo del tipo X, y otro método llamado setFoo que toma un X como un argumento". La acción jsp:setProperty se describe con más detalle en la siguiente sección, pero ahora observemos que podemos suministrar un valor explícito, dando un atributo param para decir que el valor está derivado del parámetro de la petición nombrado, o sólo lista las propiedades para indicar que el valor debería derivarse de los parámetros de la petición con el mismo nombre que la propiedad. Leemos las propiedades existentes en una expresión o scriptlet JSP llamando al método getXxx, o más comunmente, usando la acción jsp:getProperty.
Observa que la clase especifica por el bean debe estar en el path normal del servidor, no en la parte reservada que obtiene la recarga automática cuando se modifican. Por ejemplo, en el Java Web Server, él y todas las clases que usa deben ir en el directorio classes o estar en un fichero JAR en el directorio lib, no en el directorio servlets.
Aquí tenemos un ejemplo muy sencillo que carga un bean y selecciona y obtiene un sencillo parámetro String.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<TITLE>Reusing JavaBeans in JSP</TITLE>
<LINK REL=STYLESHEET
HREF="My-Style-Sheet.css"
TYPE="text/css">
</HEAD>
<BODY>
<CENTER>
<TABLE BORDER=5>
<TR><TH CLASS="TITLE">
Reusing JavaBeans in JSP</TABLE>
</CENTER>
<P>
<jsp:useBean id="test" class="hall.SimpleBean" />
<jsp:setProperty name="test"
property="message"
value="Hello WWW" />
<H1>Message: <I>
<jsp:getProperty name="test" property="message" />
</I></H1>
</BODY>
</HTML>
package hall;
public class SimpleBean {
private String message = "No message specified";
public String getMessage() {
return(message);
}
public void setMessage(String message) {
this.message = message;
}
}
Aquí tenemos un resultado típico:
para cargar el Bean, luego usar jsp:setProperty y jsp:getProperty para modificar y recuperar propiedades del bean. Sin embargo, tenemos dos opciones. Primero, podemos usar un formato de contenedor, llamado:<jsp:useBean id="name" class="package.class" />
Para indicar que la porción Body sólo se debería ejecutar cuando el bean es ejemplarizado por primera vez, no cuando un bean existente se encuentre y se utilice. Como se explica abajo, los bean pueden ser compartidos, por eso no todas las sentencias jsp:useBean resultan en la ejemplarización de un Bean. Segundo, además de id y class, hay otros tres atributos que podemos usar: scope, type, y beanName.<jsp:useBean ...> Body </jsp:useBean>
| Atributo | Uso
| id
| Da un nombre a la variable que referenciará el bean. Se usará un objeto bean anterior en lugar de ejemplarizar uno nuevo si se puede encontrar uno con el mismo id y scope.
| class
| Designa el nombre completo del paquete del bean.
| scope
| Indica el contexto en el que el bean debería estar disponible. Hay cuatro posibles valores: page, request, session, y application. El valor por defecto, page, indica que el bean estará sólo disponible para la página actual (almacenado en el PageContext de la página actual). Un valor de request indica que el bean sólo está disponible para la petición actual del cliente (almacenado en el objeto ServletRequest). Un valor de session indica que el objeto está disponible para todas las páginas durante el tiempo de vida de la HttpSession actual. Finalmente, un valor de application indica que está disponible para todas las páginas que compartan el mismo ServletContext. La razón de la importancia del ámbito es que una entrada jsp:useBean sólo resultará en la ejemplarización de un nuevo objeto si no había objetos anteriores con el mismo id y scope. De otra forma, se usarán los objetos existentes, y cualquier elemento jsp:setParameter u otras entradas entre las etiquetas de inicio jsp:useBean y la etiqueta de final, serán ignoradas.
| type
| Especifica el tipo de la variable a la que se referirá el objeto. Este debe corresponder con el nombre de la clase o ser una superclase o un interface que implemente la clase. Recuerda que el nombre de la variable se designa mediante el atributo id.
| beanName
| Da el nombre del bean, como lo suministraríamos en el método instantiate de Beans. Esta permitido suministrar un type y un beanName, y omitir el atributo class.
| |
|---|
<jsp:useBean id="myName" ... />
...
<jsp:setProperty name="myName"
property="someProperty" ... />
En este caso, el jsp:setProperty se ejecuta sin importar si se ha ejemplarizado un nuevo bean o se ha encontrado uno ya existente. Un segundo contexto en el que jsp:setProperty puede aparecer dentro del cuerpo de un elemento jsp:useBean, de esta forma:
<jsp:useBean id="myName" ... >
...
<jsp:setProperty name="myName"
property="someProperty" ... />
</jsp:useBean>
Aquí, el jsp:setProperty sólo se ejecuta si se ha ejemplarizado un nuevo objeto, no si se encontró uno ya existente.
Aquí tenemos los cuatro atributos posibles de jsp:setProperty:
| Atributo | Uso
| name
| Este atibuto requerido designa el bean cuya propiedad va a ser seleccionada. El elemento jsp:useBean debe aparecer antes del elemento jsp:setProperty.
| property
| Este atributo requerido indica la propiedad que queremos seleccionar. Sin embargo, hay un caso especial: 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
| Este atributo opcional 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ándard valueOf en la fuente o la clase envolvente. Por ejemplo, un valor de "true" para una propiedad boolean o Boolean será convertido mediante Boolean.valueOf, y un valor de "42" para una propiedad int o Integer será convertido con Integer.valueOf. No podemos usar value y param juntos, pero si está permitido no usar ninguna.
| param
| Este parámetro opcional designa el parámetro de la petición del que se debería derivar la propiedad. Si la petición actual no tiene dicho parámetro, no se hace nada: el sistema no pasa null al método seleccionador de la propiedad. Así, podemos dejar que el bean suministre los valores por defecto, sobreescribiendolos sólo cuando el parámetro dice que lo haga. Por ejemplo, el siguiente código dice "selecciona el valor de la propiedad numberOfItems a cualquier valor que tenga el perámetro numItems de la petición, si existe dicho parámetro, si no existe no se hace nada"
|
Si omitimos tanto value como param, es lo mismo que si suministramos un nombre de parámetro que corresponde con el nombre de una propiedad. Podremo tomar esta idea de automaticidad usando el parámetro de la petición cuyo nombre corresponde con la propiedad suministrada un nombre de propiedad de "*" y omitir tanto value como param. En este caso, el servidor itera sobre las propiedades disponibles y los parámetros de la petición, correspondiendo aquellas con nombres idénticos.
|
|---|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<TITLE>Reusing JavaBeans in JSP</TITLE>
<LINK REL=STYLESHEET
HREF="My-Style-Sheet.css"
TYPE="text/css">
</HEAD>
<BODY>
<CENTER>
<TABLE BORDER=5>
<TR><TH CLASS="TITLE">
Reusing JavaBeans in JSP</TABLE>
</CENTER>
<P>
<jsp:useBean id="primeTable" class="hall.NumberedPrimes" />
<jsp:setProperty name="primeTable" property="numDigits" />
<jsp:setProperty name="primeTable" property="numPrimes" />
Some <jsp:getProperty name="primeTable" property="numDigits" />
digit primes:
<jsp:getProperty name="primeTable" property="numberedList" />
</BODY>
</HTML>
Aquí tenemos un resultado típico:
<jsp:useBean id="itemBean" ... />
...
<UL>
<LI>Number of items:
<jsp:getProperty name="itemBean" property="numItems" />
<LI>Cost of each:
<jsp:getProperty name="itemBean" property="unitCost" />
</UL>
<jsp:forward page="/utils/errorReporter.jsp" /> <jsp:forward page="<%= someJavaExpression %>" />
| Síntaxis | Propósito
<%-- comment --%> Un comentario JSP. Ignorado por el traductor JSP-a-scriptlet. Cualquier elemento de script, directivas o acciones embebidas son ignorados.
| <!-- comment --> Un comentario HTML. Se pasa al HTML resultante. Cualquier elemento de script, directivas o acciones embebidas se ejecutan normalmente.
| <\% Usado en plantillas de texto (HTML estático) donde realmente queremos "<%".
| %\> Usado en elementos de script donde realmente queremos "%>".
| \' Una sola comilla en un atributo que usa comillas simples. Sin embargo, recuerda que podemos usar comillas dobles o simples, y que otros tipos de comillas serán caracteres regulares.
| \" Una doble comilla un un atributo que usa comillas dobles. Sin embargo, recuerda que podemos usar comillas dobles o simples, y que otros tipos de comillas serán caracteres regulares.
| %\> %> en un atributo.
| <\% <% en un atributo.
| |
|---|