Programación en castellano
Inicio > Tutoriales > Lenguajes orientados a objeto > Java y XML > Desarrollo de Aplicaciones Web con JSP y XML
-Tutoriales

Desarrollo de Aplicaciones Web con JSP y XML


Parte III: Desarrollar Etiquetas JSP Personalizadas

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.

 
Patrocinados
 

Copyright © 1999-2007 Programación en castellano. Todos los derechos reservados.
Formulario de Contacto - Datos legales - Publicidad
Mantenida por: Claudio y Dani.

Hospedaje web y servidores dedicados linux por Ferca Network

red internet: jugar gratis | amor | navidad 2009 | registro de dominios | servidores dedicados
más internet: comprar | gratis | posicionamiento en buscadores | decoración libre | gifs animados