19 septiembre, 2007

Custom TAGs

.
JSP permite definir TAGs. Si bien es una tarea un poco tediosa, en ciertos casos puede ser de gran ayuda para que nuestro código JSP sea más claro, legible y mantenible.

En este capítulo analizaremos algunos ejemplos bien simples con los cuales intentaremos cubrir varios de los casos se pueden presentar al momento de diseñar nuestra librería de Custom TAGs


Tipos de TAGs

Podríamos clasificar los custom tags en diferentes casos: tags con o sin atributos, con o sin cuerpo, etc. El siguiente código JSP ejemplifica de estos diferentes casos..
   1:
2:<!-- tag sin atributos ni cuerpo -->
3:<mitag />
4:
5:<!-- tag con atributos, sin cuerpo -->
6:<mitag nombre="Pablo" />
7:
8:<!-- tag con atributos tomados como expresion -->
9:<%
10: java.util.Date fec=new java.util.Date();
11:%>
12:<mitag fecha="<%=fec%>" />
13:
14:<!-- tag con cuerpo -->
15:<mitag>
16:Esto esta en el cuerpo de mi tag!
17:</mitag>
18:


Comenzando

Para programar un custom tag se necesitan dos partes: una clase Java que provee la implementación del tag en la que definimos lo que queremos que el tag haga y una entrada en un archivo XML (con extensión .tld) en donde definimos la estructura del tag.

Veamos una página JSP que utilize un custom tag y luego veremos como lo programamos.

testTags.jsp
   1:
2:<!-- tenemos que tener el archivo demo.tld -->
3:<!-- en el directorio /WEB-INF -->
4:<%@ taglib uri="/WEB-INF/demo.tld" prefix="sz" %>
5:
6:<html>
7:<body>
8: <!-- aqui llamanos a nuestro custom tag -->
9: <sz:holamundo />
10:</body>
11:</html>
12:

Los tags se definen (y se declaran) en archivos XML con extensión .tld (tag library descriptor). Para indicarle a la página JSP que vamos a utilizar tags definidos en una TLD específica se utiliza una directiva taglib en la que se indica un prefijo que se deberá anteponer cada vez que invoquemos tags de esta librería. En este caso el prefijo será "sz" (es una elección arbitraria).

Ahra tenemos que generar un archivo demo.tld en el directorio /WEB-INF de nuestra aplicación web.

demo.tld
   1:
2:<taglib>
3: <tlibversion>1.0</tlibversion>
4: <jspversion>1.0</jspversion>
5: <shortname>Ejemplos de Custom Tags</shortname>
6:
7: <!-- definicion del TAG holamundo -->
8: <tag>
9: <name>holamundo</name>
10: <tagclass>test.tags.HolaMundoTAG</tagclass>
11: <bodycontent>empty</bodycontent>
12: <info>Dice "Hola Mundo"</info>
13: </tag>
14:
15:</taglib>
16:

En el TLD definimos la estructura del tag holamundo. En este caso, como es el caso más simple, los únicos parámetros que configuramos son el nombre del tag y la clase que lo procesa: test.tags.HolaMundoTAG. Este tag no recibe atributos.

Veamos ahora la clase que procesa el tag.

HolaMundoTAG.java
   1:
2:package test.tags;
3:
4:import java.io.*;
5:import javax.servlet.jsp.*;
6:import javax.servlet.jsp.tagext.*;
7:
8:public class HolaMundoTAG extends TagSupport
9:{
10: public int doStartTag() throws JspException
11: {
12: try
13: {
14: // obtengo el stream para escribir
15: JspWriter out=pageContext.getOut();
16:
17: // escribo la salida del tag
18: out.print("Hola Mundo !!!");
19:
20: // este tag no tiene body...
21: return SKIP_BODY;
22: }
23: catch(IOException e)
24: {
25: e.printStackTrace();
26: throw new JspException(e);
27: }
28: }
29:
30: public int doEndTag() throws JspException
31: {
32: return EVAL_PAGE;
33: }
34:}
35:


Custom Tags con Atributos

Ahora veremos como programar un tag holamundopers que recibe como parámetro (o atributo) un nombre y escribe en la página la cadena: "Hola Mundo, nombre".

testTags.jsp (invoca un tag con atributos)
   1:
2:<%@ taglib uri="/WEB-INF/demo.tld" prefix="sz" %>
3:
4:<html>
5:<body>
6:
7: <sz:holamundopers nombre="Pablo" /> <br>
8:
9:</body>
10:</html>
11:

El siguiente paso será definir el tag holamundopers agregando la siguiente entrada en el archivo demo.tld.
   1:
2: <tag>
3: <name>holamundopers</name>
4: <tagclass>test.tags.HolaMundoPersTAG</tagclass>
5: <bodycontent>empty</bodycontent>
6: <info>Saludo con Nombre</info>
7: <attribute>
8: <name>nombre</name>
9: <required>true</required>
10: <rtexprvalue>false</rtexprvalue>
11: </attribute>
12: </tag>
13:

Ahora tenemos que programar la clase HolaMundoPersTAG.java. Es practicamente igual a la anterior solo que define un setter para cada atributo que el tag puede recibir.

HolaMundoPersTAG.java
   1:
2:package test.tags;
3:
4:import java.io.*;
5:import javax.servlet.jsp.*;
6:import javax.servlet.jsp.tagext.*;
7:
8:public class HolaMundoPersTAG extends TagSupport
9:{
10: // atributos
11: private String nombre;
12:
13: // setters para los atributos
14: public void setNombre(String n)
15: {
16: nombre=n;
17: }
18:
19: public int doStartTag() throws JspException
20: {
21: try
22: {
23: JspWriter out=pageContext.getOut();
24:
25: // escribe "Hola Mundo" seguido del valor
26: // del atributo
27: out.print("Hola Mundo, "+nombre);
28: return SKIP_BODY;
29: }
30: catch(IOException e)
31: {
32: e.printStackTrace();
33: throw new JspException(e);
34: }
35: }
36:
37: public int doEndTag() throws JspException
38: {
39: return EVAL_PAGE;
40: }
41:}
42:


Custom Tags con Cuerpo

Analizaremos un tag reversa que encierra una cadena (en su cuerpo) y la imprime en orden inverso.

testTags.jsp (invoca un custom tag con cuerpo)
   1:
2:<%@ taglib uri="/WEB-INF/demo.tld" prefix="sz" %>
3:
4:<html>
5:<body>
6:
7: <sz:reversa>
8: Aprendiendo CUSTOM TAGs en HolaMundo.java :O)
9: </sz:reversa>
10:
11:</body>
12:</html>
13:

El tag reversa enciera una cadena la cual va a imprimir en orden inverso. Veamos ahora la definición de este tag que tenemos que agregar en demo.tld.
   1:
2: <tag>
3: <name>reversa</name>
4: <tagclass>test.tags.ReversaTAG</tagclass>
5: <bodycontent>JSP</bodycontent>
6: <info>imprime la inversa de la cadena</info>
7: </tag>
8:

Y ahora veamos el código de la clase que lo implementa.

ReversaTAG.java
   1:
2:package test.tags;
3:
4:import java.io.*;
5:import javax.servlet.jsp.*;
6:import javax.servlet.jsp.tagext.*;
7:
8:public class ReversaTAG extends BodyTagSupport
9:{
10: // este metodo procesa el body
11: public int doAfterBody() throws JspException
12: {
13: try
14: {
15: BodyContent bc = getBodyContent();
16:
17: String cuerpo = bc.getString();
18: JspWriter out = bc.getEnclosingWriter();
19: if ( cuerpo != null )
20: {
21: for(int i=cuerpo.length()-1;i>=0;i--)
22: {
23: out.print(cuerpo.charAt(i));
24: }
25: }
26: }
27: catch(IOException ex)
28: {
29: ex.printStackTrace();
30: throw new JspException(ex);
31: }
32: return SKIP_BODY;
33: }
34:}
35:


Custom Tags con Expresiones <%= %>

Por último veremos un tag que recibe un atributo a través de una expresión de JSP. El ejemplo que vamos a desarrollar consiste en un tag que recibe una Collection (de Java) y la muestra.

testTags.jsp (define una Collection y se la pasa al custom tag)
   1:
2:<%@ page import="java.util.Collection" %>
3:<%@ page import="java.util.Vector" %>
4:
5:<%
6: Collection coll=new Vector();
7: coll.add("uno");
8: coll.add("dos");
9: coll.add("tres");
10:%>
11:
12:
13:<%@ taglib uri="/WEB-INF/demo.tld" prefix="sz" %>
14:
15:<html>
16:<body>
17:
18: <sz:mostrar data="<%=coll%>" />
19:
20:</body>
21:</html>
22:

Para definir este tag debemos agregar la siguiente entrada en demo.tld.
   1:
2: <tag>
3: <name>mostrar</name>
4: <tagclass>test.tags.MostrarTAG</tagclass>
5: <bodycontent>empty</bodycontent>
6: <info>Muestra una Collection</info>
7: <attribute>
8: <name>data</name>
9: <required>true</required>
10: <rtexprvalue>true</rtexprvalue>
11: </attribute>
12: </tag>
13:

Para que el tag soporte expresiones JSP definimos true el parámetro rtexprvalue.

MostrarTAG.java
   1:
2:package test.tags;
3:
4:import java.io.*;
5:import java.util.*;
6:import javax.servlet.jsp.*;
7:import javax.servlet.jsp.tagext.*;
8:
9:public class MostrarTAG extends TagSupport
10:{
11: private Collection data;
12:
13: public void setData(Collection c)
14: {
15: data=c;
16: }
17:
18: public int doStartTag() throws JspException
19: {
20: try
21: {
22: JspWriter out=pageContext.getOut();
23: Iterator it;
24: for( it=data.iterator(); it.hasNext(); )
25: {
26: out.print("<li>"
27: +it.next().toString()
28: +"</li>");
29: }
30: return SKIP_BODY;
31: }
32: catch(IOException e)
33: {
34: e.printStackTrace();
35: throw new JspException(e);
36: }
37: }
38:
39: public int doEndTag() throws JspException
40: {
41: return EVAL_PAGE;
42: }
43:}
44:

Vemos que simplemente recibimos un atributo de tipo Collection y luego iteramos para mostrar sus elementos.







.

9 comentarios:

Anónimo dijo...

Excelente mini tutorial de TAGs, muy claro y util, muchas gracias.

Nestor Gamaliel dijo...

Gracias, habia estado buscando informacion de tags por expresiones y no habia encontrado una tan bien explicada

Anónimo dijo...

Sencillamente Excelente tutorial!..
Se agradece!

kary dijo...

Excelente tutorial. He probado en paginas jsp puras me muestra Hola mundo, pero cuando llamo desde paginas ICEFACES no me da error ni nada pero no me muestra nada.
Ayuda por favor...

Alice dijo...

Gracias por la informacion. Muy Buena

Alice dijo...

Muy buenos Ejemplos, gracias por la informacion.

Alice dijo...

Muy buena información. Gracias.

Skuarch dijo...

muy bueno, gracias !!!!

Anónimo dijo...

Exelente!! luis9811