Beruflich Dokumente
Kultur Dokumente
Introducción
Los servlets y Java Server Pages (JSPs) son dos métodos de creación de páginas Web
dinámicas en servidor usando el lenguaje Java. En ese sentido son similares a otros métodos o
lenguajes tales como el PHP, los CGIs (Common Gateway Interface), programas que generan
páginas Web en el servidor, o los ASP (Active Server Pages), un método específico de Microsoft.
Sin embargo, se diferencian de ellos en que los JSPs y servlets se ejecutan en una máquina virtual
Java, lo cual permite que, en principio, se puedan usar en cualquier tipo de ordenador, siempre que
exista una máquina virtual Java para él. Cada servlet (o JSP, se pueden usar de forma indistinta)
se ejecuta en su propia hebra, es decir, en su propio contexto; pero no se comienza a ejecutar
cada vez que recibe una petición, sino que persiste de una petición a la siguiente, de forma que no
se pierde tiempo en invocarlo (cargar programa + intérprete). Su persistencia le permite también
hacer una serie de cosas de forma más eficiente: conexión a bases de datos y manejo de
sesiones, por ejemplo.
Ambos necesitan un programa que los contenga, y sea el que envíe efectivamente páginas Web al
servidor, y reciba las peticiones, las distribuya entre los servlets, y lleve a cabo todas las tareas de
gestión propias de un servidor Web. Mientras que servidores como el Apache están especialmente
pensados para páginas Web estáticas CGIs, y programas ejecutados por el servidor, tales como el
PHP, hay otros servidores específicos para servlets y JSPs llamados contenedores de servlets
(servlet containers) o servlet engines. Los principales son los siguientes:
package quiniela;
public class Partido {
String juegaEnCasa;
String juegaFuera;
boolean[] pronostico = new boolean[3];
String unoequisdos="1X2";
public String getJuegaEnCasa() {
return this.juegaEnCasa;
}
public void setJuegaEnCasa( String _newVal) {
this.juegaEnCasa = _newVal ;
}
public String getJuegaFuera() {
return this.juegaEnCasa;
}
public void setJuegaFuera( String _newVal) {
this.juegaFuera = _newVal ;
}
public boolean[] getPronostico() {
return this.pronostico;
}
public void setPronostico(boolean[] _newVal) {
this.pronostico = pronostico;
}
public void setPronosticoAsString(String _newVal) {
for ( int i=0; i < 3; i++ ) {
if
( _newVal.indexOf(this.unoequisdos.charAt(i)) >= 0 ) {
this.pronostico[i] = true;
} else {
this.pronostico[i] = false;
}
}
}
public String getAsString() {
String str=this.juegaEnCasa + "-" +
this.juegaFuera + ": ";
for ( int i = 0; i < 3; i ++ ) {
if ( this.pronostico[i] ) {
str +=
this.unoequisdos.charAt(i);
}
}
return str;
}
public String getFormatted() {
String str= "<tr><td>" + this.juegaEnCasa +
"</td><td>" + this.juegaFuera + "</td>";
for ( int i = 0; i < 3; i ++ ) {
if (this. pronostico[i] ) {
str += "<td>" +
unoequisdos.charAt(i)+ "</td>";
} else {
str += "<td
bgcolor=black> </td>";
}
}
str += "</tr>";
return str;
}
}
Los beans se pueden usar fácilmente desde los JSPs, usando
etiquetas. El JSP anterior se puede poner de la forma siguiente,
usando beans (resultado.jsp; el resultado en acción es prácticamente
igual al caso anterior):
http://localhost:8080/jmerelo/resultadoDyn.jsp?juegaEnCasa=Osasuna&juegaFuera
=Villareal&pronosticoAsString=X; se llamarán a las tres propiedades
correspondientes, y se les asignará el valor indicado. La sintaxis que
se sigue en esas llamadas es nombredel.jsp?variable=valor&variable=valor, y
así sucesivamente. Es la sintaxis normal para pasar valores a los
programas que se ejecutan en el servidor, tal como los JSPs. El
resultado se puede ver en la imagen
Al usar los parámetros que se pasan al JSP, estamos utilizando en
realidad un objeto implícito del JSP, el objeto request, una instancia de
la clase javax.servlet.http.HttpServletRequest, exactamente igual que se usa
en los servlets (y es que, en realidad, se tratan de la misma cosa).
Podemos acceder a él tal como se hace en el siguiente ejemplo
(resultadoDyn2.jsp), que sólo varía unas líneas con respecto al anterior:
<tr><td colspan='5'><em>Comentario</em><% if
(request.getParameter("pronosticoAsString") == "X" )
{ %>
Empate
<% } else if (request.getParameter("pronosticoAsString")
== "1" ) { %>
Gana el de casa
<% } else { %>
Gana visitante
<% } %> </td></tr>
Aquí estamos usando el objeto implícito request, llamando a su método
getParameter para obtener el valor del parámetro de llamada
pronosticoAsString. Este objeto tiene los mismos métodos que el
equivalente de servlets, así que no nos extendemos más en él. Los
más útiles son el anterior, getParameterNames y getParameterValues; otros,
tales como getCookies, se usarán para obtener las cookies del cliente.
En este caso, se incluirán en la salida diferentes cadenas
dependiendo del valor del pronóstico; si es un resultado múltiple, no
se incluirá nada.
Hay otros objetos implícitos; probablemente los más usados sean
session, que maneja las variables de sesión, y application, con métodos
relativos al contexto dónde se está ejecutando el servlet al que
corresponde el JSP.
¿Qué puede ocurrir si alguno de los parámetros pasados tiene un
valor inválido? Por ejemplo, se podían validar que los equipos
correspondieran a la misma división, o que los pronósticos estén
siempre compuestos de 1, equis o doses; hasta el momento, no se
hace ningún tipo de comprobación. Para ello, tendremos que
modificar ligeramente el bean, haciendo que el método
setPronosticoAsString tire una excepción si se encuentra con un carácter
inválido en la cadena que se le pasa. Después de cambiarle el
nombre a la clase ( quiniela/PartidoValidado.java):
public void setPronosticoAsString(String _newVal) throws
RuntimeException{
if (_newVal.length() > 3)
throw new RuntimeException
( "Pronóstico más largo de la cuenta" );
if (_newVal.length() == 0)
throw new RuntimeException ( "No
hay pronóstico" );
for ( int j = 0; j < _newVal.length(); j ++ ) {
if ( _newVal.charAt(j) != '1' &&
_newVal.charAt(j) != 'X'
&& _newVal.charAt(j) != '2' )
{
throw new RuntimeException
( "Carácter raro en cadena:"+ _newVal.charAt(j) + " en la
posición " + j );
}
}
for ( int i=0; i < 3; i++ ) {
if
( _newVal.indexOf(this.unoequisdos.charAt(i)) >= 0 ) {
this.pronostico[i] = true;
} else {
this.pronostico[i] = false;
}
}
}
Con respecto a la versión anterior, se han añadido una serie de
comprobaciones de longitud excesiva, demasiado pequeña, o si hay
algún carácter que no sea 1X2. Capturar la excepción en un programa
en Java es fácil (con las sentencias try y catch), pero, en un JSP nos
encontraremos algo así:
java.lang.reflect.InvocationTargetException:
java.lang.RuntimeException: Pronóstico más largo de la
cuenta
at
quiniela.PartidoValidado.setPronosticoAsString(PartidoValidado.jav
a:31)
Para ello se usan las páginas de error, que se llaman en caso de que
se haya producido una excepción; es más o menos lógico que no se
traten las excepciones dentro de la misma página, porque, en algunos
casos, pueden producirse antes incluso de que el código haya sido
generado. Para usar la página de error, incluimos al principio del
fichero ( resultadosDynVal.jsp):
<%@ page errorPage="paginaError.jsp?debug=log" %>
<% request.setAttribute("paginaOrigen",
request.getRequestURI()); %>
Con esto se declara una página de error, y se asigna un atributo a la
petición, que almacenará el URI de la peticición, es decir, el camino
con el que se la ha llamado. El código de la página de error es el
siguiente ( paginaError.jsp):
<%@ page isErrorPage="true" %>
<html>
<head><title>Se ha producido un error</title></head>
<%@ include file ="cabecera.jsp" %>
<h1>Se ha producido un error</h1>
<p>Endeluego, que a ver si tenemos cuidaico, que se ha
producido el siguiente error:<br>
<%= exception.getMessage() %> en la página
<%=
request.getAttribute("paginaOrigen") %>
<%@ include file ="pie.jsp" %>
Lo más importante es la primera línea: la página se declara a sí
misma como una página que responde a los errores, lo cual permite
que se cree el objeto implícito exception. Ese objeto se usa más
adelante para imprimir el mensaje que se ha producido (aunque no
siempre funciona). También se recupera un atributo del objeto
implícito request, que había sido puesto por la página que ha producido
el error, para que se sepa de dónde procede el error. Cuando se
produzca alguna entrada errónea, por ejemplo, pronosticoAsString=123,
se producirá una excepción en el objeto PartidoValidado, que se
propagará al JSP que la contiene, que a su vez llamará a esta página
de error
.
Ejercicios 4
1. Cambiar la encuesta para que
tome los resultados de los
parámetros que se le pasen al JSP .
2. Cambiar la EncuestaBean para
que detecte errores (tales como una
respuesta incorrecta), y levante una
excepción; crear una página
de error que capture esa Contenido de esta sección
• Formularios
excepción y la muestre.
• Combinación
6 Procesamiento de de elementos
JSP
formularios • Ámbitos
Ya está bien de tanto objeto •Taglibs
implícito y tanta gaita, vamos a ir
directamente al turrón de procesar formularios como Dios manda.
Vamos a tratar de hacer una página JSP que cree y a la vez procese
el formulario; de esta forma es más fácil de mantener. El formulario
nos permitirá rellenar la quiniela sin hacer nada en concreto con ella,
sólo presentarla. En la práctica, habría probablemente que almacenar
los resultados en una base de datos, o por lo menos un fichero, pero
por lo pronto, lo dejaremos así. El formulario se implementa en el
código siguiente:(quiniela.jsp, que usa la clase Quiniela:)
Introducción
A medida que se han ido adoptando las JavaServer Pages (JSP) en la aplicaciones basadas en la
Web, muchos programadores y desarrolladores embarcados en el desarrollo y mantenimiento de
estas aplicaciones se encuentran con un dilema igual que el de muchos programadores Java,
"¿Cómo estructuramos el código JSP para que sea fácil de leer, de escribir y de mantener?
En este artículo, se propone un conjunto de convenciones estándar para escribir JSPs (versiones
1.1 y 1.2) que se deberían seguir en un proyecto típico de desarrollo de software que utiliza
componentes Web. Utiliza Code Conventions for the Java Programming Language (de las que
puedes encontrar una traducción en esta misma site, en
http://programacion.com/java/tutorial/convenciones/) como plantilla para identificar varios
elementos importantes que se deberían corregir en una especificación de convenciones de
codificación (relevante para JSP). En particular, corrige los nombres y la organización de los
ficheros, la identación, los comentarios, las directivas, las declaraciones, los scriptlets, las
expresiones, los espacios en blanco, las convenciones de nombres y las prácticas de
programación. Como este es el primer intento de de presentar un conjunto de convenciones de
codificación JSP, están muy interesados en recibir cualquier feedbak sobre estas
recomendaciones. Puedes escribirles a jsp-codeconv-comments@sun.com.
La especificación JavaServer Pages 2.0, aunque es totalmente compatible con la versión 1.2,
permite un estilo de programación libre de scripts (sin declaraciones, scriptles y expresiones) y
tiene varias nuevas características que esperamos que hagan evolucionar estas convenciones.
Siempre que ha sido posible este artículo ha elegido convenciones que permanecerán con las
nuevas características de JSP 2.0.
Finalmente, asumen que estás familiarizado con JSP, Java y las convenciones de codificación
Java.
¿Por qué tener Convenciones de Codificación?
Las convenciones de codificación son importantes y los desarrolladores de contenido Web por
varias razones:
1. Mejoran la legibilidad de los artefactos software.
2. Reducen el tiempo y el esfuerzo del entrenamiento
3. Lideran hacia la estandarización del comité de organización.
Nombres de Ficheros y sus Localizaciones
El nombrado de ficheros le da a los vendedores de herramientas y a los contenedores Web una
forma para determinar los tipos de ficheros e interpretarlos de la forma adecuada. La siguiente
tabla lista los sufijos de ficheros recomendados y sus localizaciones:
Tipo de Fichero Extensión Localización Recomendada
JSP .jsp <context root>/<subsystem path>/
Fragmento JSP .jsp <context root>/<subsystem path>/
Fragmento JSP .jspf <context root>/WEB-INF/jspf/<subsystem path>/
Cascading Style Sheet .css <context root>/css/
javascript .js <context root>/js/
página HTML .html <context root>/<subsystem path>/
fuente Web .gif, .jpg, etc. <context root>/images/
Tag Library Descriptor .tld <context root>/WEB-INF/tld/
Hay algunas cosas a observar en la tabla de arriba. Primero, <context root> es la raíz del contexto
de la aplicación Web (el directorio raíz dentro de un fichero .war). Segundo, se utiliza <subsystem
path> para proporcionar agrupación lógica refinada de contenidos estáticos y dinámicos de la
página Web. Para una pequeña aplicación Web, podría ser un string vacío.
Tercero, usamos el término fragmento JSP para referirnos a una JSP que se puede incluir en otra
JSP. Observa que en JSP 2.0, se utiliza el término "segmento JSP" en lugar de "fragmento JSP".
Los fragmento JSP pueden utiliza la extensión .jsp o .jspf, y deberían situarse en /WEB-INF/jspf o
con el resto del contenido estático, respectivamente. Los fragmentos JSP que no son páginas
completas siempre deberían utilizan la extensión .jspf y situarse en /WEB-INF/jspf. Cuatro, aunque
la especificación JSP recomienda .jspf y .jsp como extensiones posibles para fragmentos JSP,
recomendamos usar .jspf mientas .jsf se podría utilizar por la especificación JavaServer Faces_.
Finalmente, en general es una buena práctica situar los ficheros descriptores de librerías de
etiquetas y cualquier otro contenido no público bajo WEB-INF/ o un subdirectorio bajo éste. De esta
forma, el contenido será inaccesible e invisible para los clientes ya que el contenedor Web no
servirá ningún fichero bajo el directorio WEB-INF/.
Un nombre de fichero de bienvenida opcional, según se declara en el elemento welcome-file del
descriptor de despliegue (Web.xml), debería ser index.jsp si se va a producir contenidos dinámico,
o index.html si la página de bienvenida es opcional.
Cuando se internacionalizan ficheros JSP, recomendamos que agrupes las páginas en directorios
por su localidad. Por ejemplo, la versión US English de index.jsp aparecería bajo /en_US/index.jsp
mientras que la versión japonesa estará bajo /ja_JP/index.jsp.
Organización de Ficheros
Un fichero de código fuente bien estructurado no sólo es fácil de leer, también hace que la
información se pueda localizar más rápido dentro del fichero. En esta sección presentaremos las
estructuras para ficheros JSP y descriptores de librerías de etiquetas.
Ficheros JSP / Ficheros de Fragmento JSP
Un fichero JSP consta de las siguientes secciones en este orden:
1. Comentarios Iniciales
2. Directiva(s) JSP page
3. Directiva(s) tag library opcionales
4. Declaración(es) JSP opcionales
5. Código HTML y JSP
Comentarios Iniciales
Un fichero JSP o un fragmento de fichero empieza con un comentario del lado del servidor:
<%--
- Author(s):
- Date:
- Copyright Notice:
- @(#)
- Description:
--%>
Este comentario sólo es visible en el lado del servidor porque se elimina durante la traducción JSP.
Dentro de este comentario están los autores, la fecha, la nota de copyright de la revisión, un
identificador y una descripción sobre el JSP para los desarrolladores Web. La combinación de
caracteres "@(#) " es reconocida por ciertos programas para indicar el inicio de un identificador.
Aunque dichos programas se utilizan muy raramente, el uso de estos strings no hace nado.
Además, esta combinación algunas veces se le añade "$Id$" para que la información de
identificación se inserte automáticamente en el JSP por algunas versiones de programas de
control. La parte Description proporciona información concisa sobre los propósitos del JSP. No
debe ser mayor de un párrafo.
En algunas situaciones, se necesita retener los comentarios de inicio y propagarlos al lado del
cliente (visibles para los navegadores) para propósitos legales y de autenticidad. Esto se puede
conseguir dividiendo el bloque de comentarios en dos partes, primero el comentario del lado del
cliente:
<!--
- Author(s):
- Date:
- Copyright Notice:
-->
y luego un breve comentario del lado del servidor:
<%--
- @(#)
- Description:
--%>
Directiva(s) JSP Page
Una directiva page define atributos asociados con la página JSP en tiempo de traducción. La
especificación JSP no impone ninguna obligación sobre cuántas directivas page se pueden definir
en la misma página. Por eso los dos siguientes fragmentos de código son equivalentes (excepto en
que el primero de ello introduce dos líneas en blanco extras en la salida):
<%@ page session="false" %>
<%@ page import="java.util.*" %>
<%@ page errorPage="/common/errorPage.jsp" %>
Si la longitud de cualquier directiva, como una directiva page, excede de la anchura normal de una
página JSP (80 caracteres), se debe dividir en varias líneas:
<%@ page session="false"
import="java.util.*"
errorPage="/common/errorPage.jsp"
%>
En general, el segundo ejemplo es la opción preferida para definir la directiva page. Hay una
excepción cuando necesitamos importar varios paquetes Java en la página JSP, dejando un
atributo import muy largo:
<%@ page session="false"
import="java.util.*,java.text.*,
com.mycorp.myapp.taglib.*,
com.mycorp.myapp.sql.*, ..."
...
%>
En este escenario, se prefiere dividir la directiva page de esta forma:
<%-- all attributes except import ones --%>
<%@ page
...
%>
<%-- import attributes start here --%>
<%@ page import="java.util.*" %>
<%@ page import="java.text.*" %>
...
Observa que en general las sentencias import siguen las convenciones de codificación Java. Por
ejemplo, generalmente se podría aceptar que cuando se utilicen hasta tres clases del mismo
paquete, la sentencia import debería especificar las clases individualmente, en vez de su paquete.
Si son más de tres clases, es el desarrollador Web el que tiene que decidir si listar todas las clases
individualmente o utilizar la notación ".*". El primer caso, hace más fácil identificar una clase
externa, especialmente cuando intentamos localizar una clase o entender cómo el JSP interactúa
con el código Java. Por ejemplo, sin conocer los paquetes Java importados como se muestra
abajo, un desarrollador Web tendría que buscar en todos esos paquetes para localizar una clase
Customer:
<%@ page import="com.mycorp.bank.savings.*" %>
<%@ page import="com.thirdpartycorp.cashmanagement.*" %>
<%@ page import="com.mycorp.bank.foreignexchange.*" %>
...
En el último caso, es más difícil localizar las clases. En general, si una JSP tiene demasiada
sentencias import, es que contiene demasiado código Java. Una mejor opción sería usar más
etiquetas JSP.
Directiva(s) Tag Library Opcionales
Una directiva taglib declara las librerías de etiquetas usadas por el JSP. Un directiva corta se
declara en una sola línea. Si tenemos varias directivas taglib se deben almacenar juntas en la
misma localización dentro del cuerpo JSP:
<%@ taglib uri="URI1" prefix="tagPrefix1" %>
<%@ taglib uri="URI2" prefix="tagPrefix2" %>
...
Al igual que la directiva page, si la longitud de una directiva taglib excede la anchura de 80
caracteres, debemos dividirla en varias líneas
<%@ taglib
uri="URI2"
prefix="tagPrefix2"
%>
Sólo deberíamos importar librerías de etiquetas que realmente se van a utilizar en la página JSP.
Desde JSP 1.2, esta altamente recomendado utilizar la JSP Standard Tag Library en nuestra
aplicación Web para reducir la necesidad de scriptlets JSP en nuestras páginas. Las páginas que
usan JSTL son, en general, más fáciles de leer y de mantener.
Declaraciones JSP Opcionales
Las declaraciones JSP declaran métodos y variables pertenecientes a la JSP. Estos métodos y
variables no se diferencian de los declarados en el lenguaje Java, y por lo tanto se deberían seguir
las convenciones de codificación más importantes. Es preferible que las declaraciones estén n un
sólo bloque de declaración JSP <%! ... %>, para centralizar las declaraciones dentro de un área del
cuerpo JSP. Aquí tenemos un ejemplo:
Bloque de Declaraciones Disparatadas Bloque de Declaraciones Preferidas
<%!
<%! private int hitCount; %>
private int hitCount;
<%! private Date today; %>
private Date today;
...
<%! public int getHitCount() {
public int getHitCount() {
return hitCount;
return hitCount;
}
}
%>
%>
Código HTML y JSP
Esta sección contiene el cuerpo HTML del JSP y el propio código JSP, como expresiones JSP,
scriptlets e instrucciones Javabeans.
Descriptor de Librería de Etiquetas
Un descriptor de librería de etiquetas (TLD) debe empezar con la declaración XML apropiada y el
sentencia DTD correcta. Por ejemplo, un TLD JSP 1.2 debe empezar con:
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE taglib
PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN"
"http://java.sun.com/dtd/Web-jsptaglibrary_1_2.dtd">
Y debe ser inmediatamente seguido por un comentario del lado del servidor que liste el autor, la
fecha, el copyright, la información de identificación, y una breve descripción de la librería:
<!--
- Author(s):
- Date:
- Copyright Notice:
- @(#)
- Description:
-->
Las reglas y guías que rigen el uso de estos elementos son las las mismas que las definidas para
los ficheros JSP y los ficheros de fragmentos JSP.
El resto del fichero de la librería de etiquetas consta de los siguientes elementos y en este orden:
• Declaración opcional de un validador de la librería de etiquetas.
• Declaración opcional de los oyentes de eventos.
• Declaración de una o más etiquetas disponibles.
Se recomienda que siempre se añadan los siguientes sub-elementos opcionales para los
elementos de un TLD. Estos sub-elementos proporcionan espacio para que los diseñadores de
etiquetas documenten el comportamiento e información adicional sobre un TLD, y acercarlos a los
desarrolladores de componentes Web.
Sub-elemento Sub-elemento
Elemento TLD
JSP 1.2 Recomendado JSP 1.1 Recomendado
attribute (JSP 1.2) description
init-param (JSP 1.2) description
tag display-name, description, example name, info
taglib uri, display-name, description uri, info
validator (JSP 1.2) description
variable (JSP 1.2) description
Identación
Las identaciones se deberían rellenar con espacios en banco. Los "tabs" causan diferentes
interpretaciones en el espaciado de caracteres en diferentes editores y no se deberían utilizar para
identación dentro de una JSP. A menos que esté restringido por las herramientas IDE particulares,
una unidad de identación corresponde a 4 espacios. Aquí tenemos un ejemplo:
<myTagLib:forEach var="client" items="${clients}">
<myTagLib:mail value="${client}" />
</myTagLib:forEach>
Un continuación de identación alinea las líneas siguientes de un bloque con un punto apropiado de
la línea anterior. La continuación de identación es un múltiplo de las unidades normales de
identación (múltiples bloques de 4 espacios en blanco:
<%@ page attribute1="value1"
attribute2="value2"
...
attributeN="valueN"
%>
Identación de Elementos de Script
Cuando un elemento de Script JSP (como una declaración, un scriptlet o una expresión) no entran
en una sola línea, se aplican las convenciones de identación adoptadas del lenguaje de Script. el
cuerpo empieza en la misma línea de que el símbolo de apertura del elemento <%=, y desde una
nueva línea del símbolo de apertura <%=. Entonces el cuerpo se termina con un símbolo de cierre
del elemento (%>) en una línea separada. Por ejemplo:
<%= (Calendar.getInstance().get(Calendar.DAY_OF_WEEK)
= Calendar.SUNDAY) ?
"Sleep in" :
"Go to work"
%>
Las líneas dentro del cuerpo que no contienen ningún símbolo de apertura o de cierre se preceden
con una unidad de identación normal. Para hacer que el cuerpo se identificable del resto del JSP.
Identación Compuesta con JSP, HTML y Java
La identación compuesta, para elemento JSP mezclados con código Java y plantillas de texto
(HTML), es necesaria para reducir el esfuerzo para comprender una fichero fuente JSP. Este es
porque la identación normal podría hacer que visualizar un fichero fuente JSP fuera una tarea
ardua. Como regla general, se aplica una unidad extra de identación normal a todo elemento
introducido dentro d otro. Observa que esto altera las identaciones de la salida final producida por
el lado del cliente. Sin embargo el navegador normalmente ignora las identaciones adicionales y no
tienen efecto sobre la salida renderizada. Por ejemplo, añadir más de un espacio en blanco antes
de una etiqueta <TABLE> no cambia la posición de la tabla. Por eso, aplicar esta convención para
identación la hace parecer más bonita:
<table>
<% if ( tableHeaderRequired ) { %>
<tr>
<th>Last Name</th>
<th>First Name</th>
</tr>
<% } %>
<c:forEach var="customer" items="${customers}">
<tr>
<td><c:out value="${customer.lastName}"/></td>
<td><c:out value="${customer.firstName}"/></td>
</tr>
</c:forEach>
</table>
que esta:
<table>
<% if ( tableHeaderRequired ) { %>
<tr>
<th>Last Name</th>
<th>First Name</th>
</tr>
<% } %>
<c:forEach var="customer" items="${customers}">
<tr>
<td><c:out value="${customer.lastName}"/></td>
<td><c:out value="${customer.firstName}"/></td>
</tr>
</c:forEach>
</table>
comentarios
Los comentarios se utilizan para describir información adicional o los propósitos del código
cercano. Aquí tenemos dos tipos para los ficheros JSP: uno para JSP y otro para comentarios del
lado del cliente.
Comentarios
Los comentarios JSP (también conocidos como comentarios del lado del servidor) sólo son visibles
en el lado del servidor (es decir, no se propagan al lado del cliente. Se prefieren los comentarios
puros JSP sobre los comentarios JSP con comentarios de scripts, ya que los primeros son menos
dependientes del lenguaje de script subyacente, y será más fácil evolucionarlos a JSP 2.0. La
siguiente tabla ilustra esto:
Línea Scriptlet JSP con comentario del lenguaje de scripting Comentario JSP puro
<% /** ... */ %>
single <% /* ... */ %> <%-- ... --%>
<% // ... %>
múltiple <% <%--
/* -
*
... ...
* -
*/ -- %>
%>
<%
//
//
...
//
%>
Comentarios del Lado del Cliente
Los comentarios del lado del cliente (<!-- ... -->) se pueden utilizar para anotar respuestas enviadas
al cliente con información adicional sobre las respuestas. No deberían contener información sobre
el comportamiento y al estructura interna de la aplicación en el servidor o del código generado en
las respuestas.
Normalmente se desaconseja el uso de comentarios del lado del cliente, ya que el cliente/usuario
no necesita leer este tipo de comentarios directamente para poder interpretar las respuestas
recibidas. Hay una excepción para autentificación y propósitos legales como una información de
copyright. Otra excepción es para que los autores de HTML utilicen una pequeña cantidad de
comentarios HTML para guiar la estructura del documento HTML, por ejemplo:
<!-- toolbar section -->
...
<!-- left-hand side navigation bar -->
...
<!-- main body -->
...
<!-- footer -->
...
Bloques de Comentarios Multi-línea
Un bloque de comentario multi-línea, tanto JSP como del lado del cliente, se decora con el carácter
guión "-". En la especificación XML, el string doble-guión "--" no está permitido dentro de un bloque
de comentarios XML. Así, por compatibilidad y consistencia con esta especificación, no debemos
utilizar dobles-guiones para decorar líneas de comentarios dentro de un bloque de comentarios de
varias líneas. La siguiente tabla ilustra esta preferencia usando un bloque de comentarios del lado
del servidor:
Preferido No-Compatible con XML
<!-- <!--
- line 1 -- line 1
- line 2 -- line 2
... ...
--> -->
Declaraciones JSP
Al igual que en las convenciones de código Java, las declaraciones de variables de los mismos
tipos deberían ir en línea separadas:
No recomendado Recomendado
<%! private int x; %>
<%! private int x, y; %>
<%! private int y; %>
Los JavaBeans no se deberían declarar ni ejemplarizar usando declaraciones JSP, sino que se
debería utilizar la etiqueta <jsp:useBean>.
En general, se desaconsejan las declaraciones JSP para variables, ya que usan el lenguaje de
script para mezclar la lógica de negocio y el código Java en un JSP que está diseñado para
propósitos de presentación, y debido a la sobrecarga del manejo del ámbito de las variables.
Scriptlets JSP
Siempre que sea posible, debemos evitar usar scriptlets JSP mientras que las librerías de etiquetas
proporcionen una funcionalidad similar. Esto hace que las páginas JSP sean más fáciles de leer y
de mantener, ayuda a separar la lógica de negocios de la lógica de presentación, y hará que
nuestras páginas evoluciones más fácilmente al estilo JSP 2.0. (JSP 2,0 soporta, pero no favorece
el uso de scriptlets). En los siguientes ejemplos, por cada representación de tipo de datos del
cliente se debe escribir un scriptlet:
customers como un array de Customers:
<table>
<% for ( int i=0; i<customers.length; i++ ) { %>
<tr>
<td><%= customers[i].getLastName() %></td>
<td><%= customers[i].getFirstName() %></td>
</tr>
<% } %>
</table>
customers como una Enumeration:
<table>
<% for ( Enumeration e = customers.elements();
e.hasMoreElements(); ) {
Customer customer = (Customer)e.nextElement();
%>
<tr>
<td><%= customer.getLastName() %></td>
<td><%= customer.getFirstName() %></td>
</tr>
<% } %>
</table>
Sin embargo, si se utilizara una librería común, hay una alta flexibilidad al utilizar los distintos tipos
de customers. Por ejemplo, en la Librería de Etiquetas Estándar de JSO, el siguiente fragmento de
código JSP soportará las representaciones de array y de Enumeration de customers:
<table>
<c:forEach var="customer" items="${customers}">
<tr>
<td><c:out value="${customer.lastName}"/></td>
<td><c:out value="${customer.firstName}"/></td>
</tr>
</c:forEach>
</table>
En el espíritu de adoptar el modelo del patrón de diseño Modelo-Vista-Controlador (MVC) para
reducir el acoplamiento entre la capa de presentación de la lógica de negocio, no se debería usan
scriptlets JSP para escribir lógica de negocio. En vez de eso, usaremos los scriptlets si necesario
transformar datos (también llamados "objeto valor") devueltos desde el procesamiento de las
solicitudes del cliente en un formato listo para el cliente apropiado. Incluso entonces, esto se podría
hacer mejor desde un servlet controlador o desde una etiqueta personalizada. Por ejemplo, el
siguiente ejemplo recoge los nombres de los clientes desde una base de datos y los muestra
directamente en el cliente:
<%
// NOT RECOMMENDED TO BE DONE AS A SCRIPTLET!
menu bar
footnote
footer
De esta forma, este JSP compuesto se puede dividir en diferentes módulos, cada uno realizado en
un JSP separado. Los JSPs constituyente se puede situar en sus localizaciones apropiadas en el
JSP compuesto, usando etiquetas JSP include en tiempo de compilación o tiempo de solicitud. En
general, cuando se utiliza la directiva include estática para incluir una página que no va a ser
solicitada por sí misma, debemos recordar la utilización de la extensión .jspf y situar el fichero en el
directorio /WEB-INF/jspf/ de la aplicación Web. Por ejemplo:
<%@ include file="/WEB-INF/jspf/header.jspf" %>
...
<%@ include file="/WEB-INF/jspf/menuBar.jspf" %>
...
<jsp:include page="<%= currentBody %>" />
...
<%@ include file="/WEB-INF/jspf/footnote.jspf" %>
...
<%@ include file="/WEB-INF/jspf/footer.jspf" %>
...
Otras Recomendaciones
En este artículo se han presentado un conjunto de convenciones de codificación para producir
código JSP y artefactos Web más fáciles de mantener y más consistentes. Hay otras buenas
prácticas que podemos utilizar para conseguir mejorar este objetivo. Por ejemplo, la especificación
JSP 1.2 recomienda:
• Definir Nuevos Objetos Implícitos
• Acceder a Información Específica-de-Vendedor
• Personalizar una Librería de Etiquetas
Además, Java BluePrints ofrece mejores prácticas a mayor escala, como usar el patrón Model-
View-Controller
1.Elabore una ventana en Java que liste los autores con sus respectivos países.
2.Elabore una ventana en Java que liste los libros con su respectiva editorial. Incluya un menú
con una opción que permita abrir otra ventana que liste los autores del libro escogido.