Desarrollo de Aplicaciones Web con JSP y XML

La tecnolog�a JavaServer Pages (JSP) hace f�cil embeber trozos de c�digo Java (o scriptlets) en documento HTML. Sin embargo, esta soluci�n, podr�a no ser adecuada para todos los desarrolladores de contenido HTML, quiz�s porque no conocen Java o no les interesa aprender su s�ntaxis. Aunque los JavaBeans pueden usarse para encapsular mucho c�digo Java, us�ndolos en p�ginas JSP todav�a requieren que los desarrolladores de contenido tengan alg�n conocimiento sobre su s�ntaxis.

La tecnolog�a JSP nos permite introducir nuevas etiquetas personalizadas a trav�s de una librer�a de etiquetas. Como desarrollador Java, podemos ampliar las p�ginas JSP introduciendo etiquetas personalizadas que pueden ser desplegadas y usadas en una s�ntaxis al estilo HTML. Las etiquetas personalizadas tambi�n nos permiten proporcionar un mejor empaquetamiento, mejorando la separaci�n entre la l�gica del negocio y su representaci�n.

Est� p�gina presenta una breve introducci�n a las etiquetas personalizadas, presenta:

  • C�mo desarrollar y desplegar etiquetas sencillas.
  • C�mo desarrollar y desplegar etiquetas avanzadas: etiquetas parametrizadas y con cuerpo.
  • C�mo describir etiquetas con el "Tag Library Descriptor" (TLD)

Finalmente, se proporcionar�n algunas gu�as para la programaci�n.

.�Introducci�n a las Etiquetas

Si tenemos experiencia con HTML, ya conocemos algo sobre los tipos de etiquetas que se pueden usar. B�sicamente hay dos tipo de etiquetas, y �mbos pueden tener atributos (informaci�n sobre c�mo la etiqueta deber�a hacer su trabajo):

  • Etiquetas sin cuerpo: Una etiqueta sin cuerpo es una etiqueta que tiene una etiqueta de apertura pero no tiene su correspondiente etiqueta de cierre. Tiene la s�ntaxis:
    <tagName attributeName="value" anotherAttributeName="anotherValue"/>
    

    Las etiquetas sin cuerpo se usan para representar ciertas funciones, como la presentaci�n de un campo de entrada o para mostrar una imagen. Aqu� tenemos un ejemplo de una etiqueta sin cuerpo en HTML:

    <IMG SRC="./fig10.gif">

  • Etiquetas con cuerpo: Una etiqueta con cuerpo tiene una etiqueta de inicio y una etiqueta de fin. Tiene la s�ntaxis:
      
    <tagName attributeName="value" anotherAttributeName="anotherValue">
    ...tag body...
    </tagName>
    

    Las etiquetas con cuerpo se usan para realizar operaciones sobre el contenido del cuerpo, como formatearlo. Aqu� tenemos un ejemplo de una etiqueta con cuerpo en HTML:

    <H2>Custom Tags</H2>

.�Etiquetas JSP Personalizadas

Las etiquetas JSP personalizadas son simplemente clases Java que implementan unos interfaces especiales. Una vez que se han desarrollado y desplegado, sus acciones pueden ser llamadas desde nuestro HTML usando s�ntaxis XML. Tienen una etiqueta de apertura y otra de cierre. Y podr�an o no podr�an tener un cuerpo. Las etiquetas sin cuerpo pueden expresarse como:

<tagLibrary:tagName />

Y una etiqueta con cuerpo, podr�a expresarse de esta forma:

<tagLibrary:tagName>
   body
</tagLibrary:tagName>

De nuevo, ambos tipos podr�an tener atributos que sirven para personalizar el comportamiento de la etiqueta. La siguiente etiqueta tiene un atributo llamado name, que acepta un valor String obtenido valdiando la variable yourName:

<mylib:hello name="<%= yourName %>" /> 

O podr�a escribirse como una etiqueta con cuerpo:

<mylib:hello>
  <%= yourName %>
</mylib:hello>
Nota:

Cualquier dato que sea un simple String, o pueda ser generado evaluando una expresi�n simple, deber�a ser pasado como un atributo y no como contenido del cuerpo.

.�Beneficios de las Etiquetas Personalizadas

Algo muy importante a observar sobre las etiquetas JSP personalizadas es que no ofrecen m�s funcionalidad que los scriptles, simplemente proporcionan un mejor empaquetamiento, ayudandonos a mejorar la separaci�n entre la l�gica del negocio y su representaci�n. Algunos de sus beneficios son:

  • Pueden reducir o eliminar los scriptlets en nuestras aplicaciones JSP. Cualquier par�metro necesario para la etiqueta puede pasarse como atributo o contenido del cuerpo, por lo tanto, no se necesita c�digo Java para inicializar o seleccionar propiedades de componentes.
  • Tienen una s�ntaxis muy simple. Los scriptlets est�n escritos en Java, pero las etiquetas personalizadas pueden usar una s�ntaxis al estilo HTML.
  • Pueden mejorar la productividad de los desarrolladores de contenido que no son programadores, permiti�ndoles realizar tareas que no pueden hacer con HTML.
  • Son reutilizables. Ahorran tiempo de desarrollo y de prueba. Los Scritplets no son reusables, a menos que llamemos reutilizaci�n a "copiar-y-pegar".

En breve, podemos usar etiquetas personalizadas para realizar tareas complejas de la misma forma que utilizamos HTML para crear una representaci�n.

.�Definir una Etiqueta

Una etiqueta es una clase Java que implementa un interface especializado. Se usa para encapsular la funcionalidad desde una p�gina JSP. Como mencionamos anteriormente, una etiqueta puede o no tener cuerpo. Para definir una sencilla etiqueta sin cuerpo, nuestra clase debe implementar el interface Tag. El desarrollo de etiquetas con cuerpo se discute m�s adelante. El ejemplo 1 muestra el c�digo fuente del interface Tag que debemos implementar:

Ejemplo 1: Tag.java

public interface Tag {
   public final static int SKIP_BODY = 0;
   public final static int EVAL_BODY_INCLUDE = 1;
   public final static int SKIP_PAGE = 5;
   public final static int EVAL_PAGE = 6;

   void setPageContext(PageContext pageContext);
   void setParent(Tag parent);
   Tag getParent();
   int doStartTag() throws JspException;
   int doEndTag() throws JspException;
   void release();
}

Todas las etiquetas deben implementar el interface Tag (o uno de sus interfaces) como si definiera todos los m�todos que el motor de ejecuci�n JSP llama para ejecutar una etiqueta. La Tabla 1 proporciona una descripci�n de los m�todos del interface Tag:

M�todo Descripci�n
setPageContext(PageContext pc) A este m�todo lo llama el motor de ejecuci�n JSP antes de doStartTag, para seleccionar el contexto de la p�gina.
setParent(Tag parent) Invocado por el motor de ejecuci�n JSP antes de doStartTag, para pasar una referencia a un controlador de etiqueta a su etiqueta padre.
getParent Devuelve un ejemplar Tag que es el padre de esta etiqueta.
doStartTag Invocado por el motor de ejecuci�n JSP para pedir al controlador de etiqueta que procese el inicio de etiqueta de este ejemplar..
doEndTag Invocado por el motor de ejecucu�n JSP despu�s de retornar de doStartTag. El cuerpo de la acci�n podr�a no haber sido evaluado, dependiendo del valor de retorno de doStartTag.
release Invocada por el motor de ejecuci�n JSP para indicar al controlador de etiqueta que realice cualquier limpieza necesaria.

.�Mi Primera Etiqueta

Ahora, veamos una etiqueta de ejemplo que cuando se le invoca imprime un mensaje en el cliente.

Hay unos pocos pasos implicados en el desarrollo de una etiqueta personalizada. Estos pasos son los siguientes:

  1. Desarrollar el controlador de etiqueta
  2. Crear un descriptor de librer�a de etiqueta
  3. Probar la etiqueta

.�1. Desarrollar el Controlador de Etiqueta

Un controlador de etiqueta es un objeto llamado por el motor de ejecuci�n JSP para evaluar la etiqueta personalizada durante la ejecuci�n de una p�gina JSP que referencia la etiqueta. Los m�todos del controlador de etiqueta son llamados por la clase de implementaci�n en varios momentos durante la evaluaci�n de la etiqueta. Cada controlador de etiqueta debe implementar un interface especializado. En este ejemplo, la etiqueta implementa el interface Tag como se muestra en el ejemplo 2:

Ejemplo 2: HelloTag.java

package tags;

import java.io.*;
import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*;

public class HelloTag implements Tag {
   private PageContext pageContext;
   private Tag parent;

   public HelloTag() {
super();
   }

   public int doStartTag() throws JspException {
try {
   pageContext.getOut().print(
   "This is my first tag!");
} catch (IOException ioe) {
   throw new JspException("Error: 
   IOException while writing to client" 
   + ioe.getMessage());
}
return SKIP_BODY;
   }

   public int doEndTag() throws JspException {
return SKIP_PAGE;
   }

   public void release() {
   }

   public void setPageContext(PageContext 
   pageContext) {
this.pageContext = pageContext;
   }

   public void setParent(Tag parent) {
this.parent = parent;
   }

   public Tag getParent() {
return parent;
   }
}

Los dos m�todos importantes a observar en HelloTag son doStartTag y doEndTag. El primero es invocado cuando se encuentra la etiqueta de inicio. En este ejemplo, este m�todo devuelve SKIP_BODY porque es una simple etiqueta sin cuerpo. el m�todo doEndTag es invocado cuando se encuentra la etiqueta de cierre. En este ejemplo devuelve SKIP_PAGE porque no queremos evaluar el resto de la p�gina, de otro modo deber�a devolver EVAL_PAGE.

Para compilar la clase HelloTag, asumiendo que Tomcat est� instalado en c:\tomcat:

  • Creamos un nuevo subdirectorio llamando tags, que es el nombre del paquete que contiene la clase HelloTag. Este deber�a crearse en: c:\tomcat\webapps\examples\web-inf\classes.
  • Grabamos HelloTag.java en el subdirectorio tags.
  • Lo compilamos con el comando:
    c:\tomcat\webapps\examples\web-inf\classes\tags> 
    javac -classpath c:\tomcat\lib\servlet.jar 
    HelloTag.java
    

.�2. Crear el Descriptor de Librer�a de Etiquetas

El siguiente paso es especificar c�mo ejecutar� la etiqueta el motor de ejecuci�n JSP . Esto puede hacerse crerando un "Tag Library Descriptor" (TLD), que es un documento XML. El ejemplo 3 muestra un TLD de ejemplo:

Ejemplo 3: mytaglib.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-jsptaglibrary_1_1.dtd">

<!-- a tag library descriptor -->

<taglib>
   <tlibversion>1.0</tlibversion>
   <jspversion>1.1</jspversion>
   <shortname>first</shortname>
   <uri></uri>
   <info>A simple tab library for the 
   examples</info>

  <tag>
    <name>hello</name>
    <tagclass>tags.HelloTag</tagclass>
    <bodycontent>empty</bodycontent>
    <info>Say Hi</info>
  </tag>   
</taglib>

Primero especificamos la versi�n de la librer�a de etiquetas y la versi�n de JSP. La etiqueta <shortname> indica como se va a referencia la librer�a de etiquetas desde la p�gina JSP. La etiqueta <uri> puede usarse como un identificador �nico para nuestra librer�a de etiquetas.

En este TLD, s�lo tenemos una etiqueta llamanda hello cuya clase se especifica usando la etiqueta <tagclass>. Sin embargo, una librer�a de etiquetas puede tener tantas etiquetas como queramos. El <bodycontent> nos dice que esta etiqueta no tiene cuerpo; de otro modo se producir�a un error. Por otro lado, si queremos evaluar el cuerpo de la etiqueta, el valor deber�a ser:

  • tagdependent: lo que significa que cualquier cuerpo de la etiqueta ser�a manejado por la propia etiqueta, y puede estar vac�o.
  • JSP: lo que significa que el contenedor JSP evaluar�a cualquier cuerpo de la etiqueta, pero tambi�n podr�a estar vac�o.

Grabamos mytaglib.tld en el directorio: c:\tomcat\webapps\examples\web-inf\jsp.

.�3. Probar la Etiqueta

El paso final es probar la etiqueta que hemos desarrollado. Para usar la etiqueta, tenemos que referenciarla, y esto se puede hacer de tres formas:

  1. Referenciar el descriptor de la librer�a de etiquetas de una librer�a de etiquetas desempaquetada. Por ejemplo:
    <@ taglib uri="/WEB-INF/jsp/mytaglib.tld" prefix="first" %>
    
  2. Referenciar un fichero JAR que contiene una librer�a de etiquetas. Por ejemplo:
    <@ taglib uri="/WEB-INF/myJARfile.jar" prefix='first" %>
    
  3. Definir una referencia a un descriptor de la librer�a de etiquetas desde el descriptor de aplicaciones web (web.xml) y definir un nombre corto para referenciar la librer�a de etiquetas desde al JSP. Para hacer esto, abrimos el fichero: c:\tomcat\webapps\examples\web-inf\web.xml y a�adimos las siguientes l�neas antes de la �ltima l�nea, que es <web-app>:
        <taglib>
     <taglib-uri>mytags</taglib-uri>
     <taglib-location>/WEB-INF/jsp/
     mytaglib.tld</taglib-location>
        </taglib>
    

Ahora, escribimos un JSP y usamos la primera s�ntaxis. Lo podremos ver en el ejemplo 4:

Ejemplo 4: Hello.jsp

<%@ taglib uri="/WEB-INF/jsp/mytaglib.tld"
 prefix="first" %>
<HTML>
<HEAD>
<TITLE>Hello Tag</TITLE>
</HEAD>

<BODY bgcolor="#ffffcc">

<B>My first tag prints</B>:

<first:hello/>

</BODY>
</HTML>

El taglib se usa para decirle al motor de ejecuci�n JSP donde encontrar el descriptor para nuestra etiqueta, y el prefix especifica c�mo se referir� a las etiquetas de esta librer�a. Con esto correcto, el motor de ejecuci�n JSP reconocer� cualquier uso de nuestra etiqueta a lo largo del JSP, mientras que la precedamos con el prefijo first como en <first:hello/>.

Alternativamente, podemos usar la segunda opci�n de referencia creando un fichero JAR. O podemos usar la tercera opci�n simplemente reemplazando la primera l�nea del ejemplo 4 con la siguiente l�nea:

<%@ taglib uri="mytags" prefix="first" %>

B�sicamente, hemos usado el nombre mytags que se ha a�adido a web.xml, para referenciar a la librer�a de etiquetas. Para el resto de los ejemplos de esta p�gina utilizaremos este tipo de referencia.

Ahora, si solicitamos Hello.jsp desde nuestro navegador, ver�amos algo similar la la figura 1:


Figura 1: Primera Etiqueta Personalizada

La etiqueta personalizada desarrollada en el ejemplo es una etiqueta sencilla, el objetivo era s�lo ofrecernos uno poco del sabor del esfuerzo que implica el desarrollo de etiquetas personalizadas. Podr�amos haber observado que incluso est� simple etiqueta requiere que implementemmos un gran n�mero de m�todos, algunos de los cuales tienen implementaciones muy simples. Para minimizar el esfuerzo implicado, los dise�adores de JSP proporcionaron una plantilla a utilizar en la implementaci�n de etiquetas sencillas. La plantilla es la clase abstracta TagSupport. Es una clase de conveniencia que proporciona implementaciones por defecto para todos los m�todos del interface Tag.

Por lo tanto, la forma m�s f�cil de escribir etiquetas sencillas es extender la clase TagSupport en vez de implementar el interface Tag. Podemos pensar en la clase abstracta TagSupport como en un adaptador. Habiendo dicho esto, la clase HelloTag del ejemplo 4 podr�a implementarse m�s f�cilmente como se ve en el ejemplo 5.

Ejemplo 5: Extender la clase TagSupport

package tags;

import java.io.*;
import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*;

public class HelloTag extends TagSupport {

   public int doStartTag() throws JspException {
try {
   pageContext.getOut().print("This is my 
   first tag!");
} catch (IOException ioe) {
   throw new JspException("Error: 
   IOException while writing 
  to client" + ioe.getMessage());
}
return SKIP_BODY;
   }

   public int doEndTag() throws JspException {
return SKIP_PAGE;
   }
}

.�Etiquetas Parametrizadas

Hamos visto como desarrollar etiquetas sencillas. Ahora veamos c�mo desarrollar etiquetas parametrizadas--etiquetas que tienen atributos. Hay dos nuevas cosas que necesitamos a�adir al ejemplo anterior para manejar atributos:

  1. A�adir un m�todo set
  2. A�adir una nueva etiqueta a mytagslib.tld

A�adir un m�todo set y cambiar el mensaje de salida resulta en el Ejemplo 5:

Ejemplo 5: Una etiqueta con atributo

package tags;

import java.io.*;
import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*;

public class HelloTagParam extends TagSupport {
   private String name;

   
   public void setName(String name) {
this.name = name;
   }
   

   public int doStartTag() throws JspException {
try {
   pageContext.getOut().print("Welcome to 
   JSP Tag Programming, " +name);
} catch (IOException ioe) {
   throw new JspException("Error: 
   IOException 
   while writing to client");
}
return SKIP_BODY;
   }

   public int doEndTag() throws JspException {
return SKIP_PAGE;
   }
}

Lo siguiente que necesitamos hacer es a�adir una nueva etiqueta a mytaglib.tld. La nueva etiqueta se muestra en el ejemplo 6. Este fragmento de c�digo deber�a a�adirse a mytaglib.tldjusto antes de la l�nea, </taglib>:

Ejemplo 6: revisi�n de mytaglib.tld

<tag>
  <name>helloparam</name>
  <tagclass>tags.HelloTagParam</tagclass>
  <bodycontent>empty</bodycontent>
  <info>Tag with Parameter</info>
  <attribute>
     <name>name</name>
     <required>false</required>
     <rtexprvalue>false</rtexprvalue>
   </attribute>
</tag>

Hemos a�adido una nueva etiqueta llamada helloparam. Observa la nueva etiqueta <attribute>, que especifica que la etiqueta helloparam acepta un atributo cuyo nombre es name. La etiqueta <required> se selecciona a false, significando que el atributo es opcional; la etiqueta <rtexprvalue> se selecciona a false especificando que no se har� evaluaci�n en el momento de la ejecuci�n.

No necesitamos a�adir nada al fichero descriptor de aplicaci�n web web.xml porque estamos usando la misma librer�a de etiquetas: mytaglib.tld.

Ahora, podemos probar la nueva etiqueta. El c�digo fuente del ejemplo 7 muestra c�mo probarla usando un atributo name de "JavaDuke".

Ejemplo 7: HelloTagParam.jsp

<%@ taglib uri="mytags" prefix="first" %>
<HTML>
<HEAD>
<TITLE>Hello Tag with Parameter</TITLE>
</HEAD>

<BODY bgcolor="#ffffcc">
<B>My parameterized tag prints</B>:

<P>

<first:helloparam name="JavaDuke"/>

</BODY>
</HTML>

Si solicitamos HelloTagParam.jsp desde un navegador web, veremos una salida similar a la de la Figura 2:


Figura 2: Probando una etiqueta parametrizada.

.�Librer�as de Etiquetas

Una librer�a de etiquetas es una colecci�n de etiquetas personalizadas JSP. El Jakarta Taglibs Project proporciona varias l�brer�as de etiquetas �tiles para analizar XML, transformaciones, email, bases de datos, y otros usos. Peuden descargarse y usarse muy f�cilmente.

Aqu� desarrollamos nuestra librer�a de etiquetas. Como un ejemplo, desarrollamos una sencila librer�a matem�tica que proporciona dos etiquetas, una para sumar dos n�meros y la otra para restar un n�mero de otro. Cada etiqueta est� representada por una clase. El c�digo fuente de las dos clases, Add.java y Subtract.java, se muestra en el ejemplo 8.

Ejemplo 8: Add.java y Subtract.java

package tags;

import java.io.*;
import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*;

public class Add extends TagSupport {
   private int num1, num2;

   public void setNum1(int num1) {
this.num1 = num1;
   }
   
   public void setNum2(int num2) {
this.num2 = num2;
   }


   public int doStartTag() throws JspException {
try {
   pageContext.getOut().print("Welcome
   to First
    Grade Math! ");
   pageContext.getOut().print("The sum of: " +
   num1 + " and " + num2 + " is: " + (
   num1+num2));
} catch (IOException ioe) {
   throw new JspException("Error:
   IOException
    while writing to client");
}
return SKIP_BODY;
   }
}

// Subtract.java

package tags;

import java.io.*;
import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*;

public class Subtract extends TagSupport {
   private int num1, num2;

   public void setNum1(int num1) {
this.num1 = num1;
   }
   
   public void setNum2(int num2) {
this.num2 = num2;
   }


   public int doStartTag() throws JspException {
try {
   pageContext.getOut().print("Welcome to First
    Grade Math! ");
   pageContext.getOut().print("If you 
   subtract:
    " + num2 + " from " + num1 +
    ", you get: "+ (num1 - num2));
} catch (IOException ioe) {
   throw new JspException("Error:
    IOException 
   while writing to client");
}
return SKIP_BODY;
   }
}

El c�digo fuente es f�cil de entender. Observa una cosa que hemos repetido en Add.java y Subract.java es la llamada a pageContext.getOut.print. Una forma mejor de hacer esto ser�a obtener un objeto JspWriter y luego usarlo para imprimir hacia el cliente:

JspWriter out = pageContext.getOut();
out.print("first line");
out.print("second line");

El siguiente paso es revisar el fichero descriptor de librer�a de etiquetas, mytaglib.tld, y a�adimos las descripciones para las dos nuevas etiquetas. El ejemplo 9 muestra la descripci�n de las nuevas etiquetas. A�adimos el siguiente fragmento de XML a mytaglib.tld, justo antes de la �ltima l�nea.

Ejemplo 9: revisar mytaglib.tld

  <tag>
    <name>add</name>
    <tagclass>tags.Add</tagclass>
    <bodycontent>empty</bodycontent>
    <info>Tag with Parameter</info>
    <attribute>
 <name>num1</name>
 <required>true</required>
 <rtexprvalue>false</rtexprvalue>
    </attribute>
    <attribute>
<name>num2</name>
<required>true</required>
<rtexprvalue>false</rtexprvalue>
    </attribute>
  </tag>

  <tag>
    <name>sub</name>
    <tagclass>tags.Subtract</tagclass>
    <bodycontent>empty</bodycontent>
    <info>Tag with Parameter</info>
    <attribute>
 <name>num1</name>
 <required>true</required>
 <rtexprvalue>false</rtexprvalue>
    </attribute>
    <attribute>
<name>num2</name>
<required>true</required>
<rtexprvalue>false</rtexprvalue>
    </attribute>
  </tag>

Como podemos ver, cada etiqueta requiere dos atributos que deben llamarse num1 y num2.

Ahora podemos probar nuestra nueva librer�a de etiquetas matem�ticas usando el probador mostrado en el ejemplo 10.

Ejemplo 10: math.jsp

<%@ taglib uri="mytags" prefix="math" %>
<HTML>
<HEAD>
<TITLE>Hello Tag with Parameter</TITLE>
</HEAD>

<BODY bgcolor="#ffffcc">
<B>Calling first tag</B>
<P>
<math:add num1="1212" num2="121"/>
<P>
<B>Calling second tag</B>
<P>
<math:sub num1="2123" num2="3"/>

</BODY>
</HTML>

Si solicitamos math.jsp desde un navegador web, ver�amos una salida similar a la de la Figura 3:


Figura 3: Probando la librer�a de etiquetas matem�ticas.

.�Etiquetas con Cuerpo

Un manejador de etiquetas para una etiqueta con cuerpo se implementa de forma diferente dependiendeo de si se necesita evaluar el cuerpo s�lo una vez o varias veces.

  • Una Evaluaci�n: Si el cuerpo necesita evaluarse s�lo una vez, el controlador de etiqueta deber�a implementar el interface Tag, o extender la clase obstracta TagSupport; el m�todo doStartTag necesita devolver EVAL_BODY_INCLUDE, y si no necesita ser evaluado en absoluto deber�a devolver BODY_SKIP.
  • Multiple Evaluaci�n: Si el cuerpo necesita evaluarse varias veces, deber�a implementarse el interface BodyTag. Este interface extiende el interface Tag y define m�todos adicionales (setBodyContent, doInitBody, y doAfterBody) que le permiten al controlador inspeccionar y posiblemente cambiar su cuerpo. De forma alternativa, similarmente a la clase TagSupport, podemos extender la clase BodyTagSupport, que proporciona implementaciones por defecto para los m�todos del interface BodyTag. T�picamente, necesitaremos implementar los m�todos doInitBody y doAfterBody. doInitBody es llamado despu�s de que se haya seleccionado el contenido del cuerpo pero antes de que sea evaluado, y el doAfterBody es llamado despu�s de que el contenido del cuerpo sea evaluado.

.�Una Evaluaci�n

Aqu� tenemos un ejemplo de una s�la evaluaci�n donde hemos extendido la clase BodyTagSupport. Este ejemplo lee el contenido del cuerpo, lo convierte a min�sculas, y luego lo reescribe de vuelta hacia el cliente. El ejemplo 11 muestra el c�digo fuente. El contenido del cuerpo es recuperado como un String, convertido a min�sculas, y luego escrito de vuelta al cliente.

Ejemplo 11: ToLowerCaseTag.java

package tags;

import java.io.*;
import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*;

public class ToLowerCaseTag extends BodyTagSupport {

   public int doAfterBody() throws JspException {
try {
   BodyContent bc = getBodyContent();
   // get the bodycontent as string
   String body = bc.getString();
   // getJspWriter to output content
   JspWriter out = bc.getEnclosingWriter();
   if(body != null) {
out.print(body.toLowerCase());
   }
} catch(IOException ioe) {
   throw new JspException("Error:
    "+ioe.getMessage());   
}
return SKIP_BODY;
   }
}

El siguiente paso es a�adir una etiqueta al fichero descriptor de la librer�a de etiquetas, mytaglib.tld. El nuevo descriptor de etiqueta es:

<tag>
  <name>tolowercase</name>
  <tagclass>tags.ToLowerCaseTag</tagclass>
  <bodycontent>JSP</bodycontent>
  <info>To lower case tag</info>
</tag>

Observa que cuando escribimos una etiqueta con cuerpo, el valor de la etiqueta <bodycontent> debe ser JSP o jspcontent, como se explic� anteriormente.

En el ejemplo 12, podemos ver un probador para este ejemplo:

Ejemplo 12: lowercase.jsp

<%@ taglib uri="mytags" prefix="first" %>
<HTML>
<HEAD>
<TITLE>Body Tag</TITLE>
</HEAD>

<BODY bgcolor="#ffffcc">

<first:tolowercase>
Welcome to JSP Custom Tags Programming.
</first:tolowercase>

</BODY>
</HTML>

Si solictamos lowercase.jsp desde un navegador web, ver�amos algo similar a la figura 4:


Figura 4: Probar la etiqueta lowercase

.�Multiples Evaluaciones

Ahora veamos un ejemplo de un cuerpo de etiqueta evaluado m�tiples veces. El ejemplo acepta un string e imprime el string tantas veces como se indique en el JSP. El c�digo fuente se muestra en el ejemplo 13:

Ejemplo 13: LoopTag.java

package tags;

import java.io.*;
import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.*;

public class LoopTag extends BodyTagSupport {

   int times = 0;

   BodyContent bodyContent;

   public void setTimes(int times) {

this.times = times;
   }

   public int doStartTag() throws JspException {
if (times>0) {
  return EVAL_BODY_TAG;
} else {
   return SKIP_BODY;
}
   }

   public void setBodyContent(BodyContent 
   bodyContent) {
this.bodyContent = bodyContent;
   }

   public int doAfterBody() throws JspException {
if (times >1) {
  times--;
  return EVAL_BODY_TAG;
} else {
   return SKIP_BODY;
}
   }

   public int doEndTag() throws JspException {
try {
   if(bodyContent != null) {
     bodyContent.writeOut(
     bodyContent.getEnclosingWriter());
   }
} catch(IOException e) {
  throw new JspException(
  "Error: "+e.getMessage());
}
return EVAL_PAGE;
   }
}

En este ejemplo, los m�todos implementados juegan los siguientes papeles:

  • El m�todo doStartTag obtiene la llamada al inicio de la etiqueta. Chequea si se necesita realizar el bucle.
  • El m�todo setBodyContent es llamado por el contenedor JSP para chequear por m�s de un bucle.
  • El m�todo doAfterBody es llamado despu�s de cada evaluaci�n; el n�mero de veces que se necesite realizar el bucle es decrementado en uno, luego devuelve SKIP_BODY cuando el n�mero de veces no es mayor que uno.
  • El m�todo doEndTag es llamado al final de la etiqueta, y el contenido (si existe) se escribe en el writer encerrado.

Similarmente a los ejemplos anteriores, el siguiente paso es a�adir un nuevo descriptor de etiqueta a mytaglib.tld. Las siguientes l�neas meustran lo que necesitamos a�adir:

<tag>
  <name>loop</name>
  <tagclass>tags.LoopTag</tagclass>
  <bodycontent>JSP</bodycontent>
  <info>Tag with body and parameter</info>
  <attribute>
     <name>times</name>
     <required>true</required>
     <rtexprvalue>true</rtexprvalue>
  </attribute>
</tag>

Observa que la etiqueta <rtexprvalue> especifica que las evaluaciones se ejecutar�n en tiempo de ejecuci�n.

En el Ejemplo 14 podemos ver un JSP probador:

Ejemplo 14: loops.jsp

<%@ taglib uri="mytags" prefix="first" %>
<HTML>
<HEAD>
<TITLE>Body Tag</TITLE>
</HEAD>

<BODY bgcolor="#ffffcc">

<first:loop times="4">
Welcome to Custom Tags Programming.<BR>
</first:loop>

</BODY>
</HTML>

Finalmente, si solicitamos loops.jsp desde un navegador, ver�amos una salida similar a la de la Figura 5:


Figura 5: Probando loops.jsp

.�Gu�as de Programaci�n

Aqu� hay unas cuantas gu�as a tener en mente cuando desarrollemos librer�as de etiquetas JSP:

  • Mantenerla simple: si una etiqueta requiere muchos atributos, debemos intentar dividirla en varias etiquetas.
  • Hacerla utilizable: consultemos a los usuarios de las etiquetas (desarrolladores HTML) para conseguir un alto grado de utilizabilidad.
  • No inventemos un lenguaje de programaci�n en JSP: no desarrollemos etiquetas personalizadas que permitan a los usuarios escribir programas expl�citos.
  • Intentemos no re-inventar la rueda: ya existen varias librer�as de etiquetas JSP a nuestra disposici�n, como las del Jakarta Taglibs Project. Deberemos chequearlas para ver si ya existe alguna etiqueta que nos pueda servir y no tengamos que re-inventar la rueda.

.�Conclusi�n

En la p�gina anterior Parte III: JSP con XML en Mente, vimos como analizar documentos XML. Pero incluso el ojo desentrenado habr� observado que hemos embebido mucho c�digo de an�lisis (o l�gica) en JSP. Incluso aunque hemos usado JavaBeans para encapsular mucho c�digo Java, todav�a hemos terminado p�ginas JSP mezclando la l�gica de programaci�n con la presentaci�n.

Las etiquetas personalizadas nos ayudan a mejorar la separaci�n de la l�gica del programa (an�lisis e iteracci�n de la Parte II) de la presentaci�n. Los distintos ejemplos mostrados en esta p�gina muestran como desarrollar y desplegar etiquetas simples y avanzadas. Como ejercicio, podr�as querer reescribir los ejemplos SAX y DOM de la Parte II como librer�as de etiquetas. Tambi�n podr�as echar un vistazo a lo que tiene que ofrecer el Jakarta Taglibs Project sobre an�lisis de XML y transformaciones XSL. Tambi�n proporciona librer�as de etiquetas para otras cosas.

COMPARTE ESTE ARTÍCULO

COMPARTIR EN FACEBOOK
COMPARTIR EN TWITTER
COMPARTIR EN LINKEDIN
COMPARTIR EN WHATSAPP
ARTÍCULO ANTERIOR