Estructura de las Páginas JSP
- Variables Scripting

En la sección anterior se vio la construcción de etiquetas personalizadas, y vimos que que las etiquetas JSP son clases Java que deben implementar el interface Tag o BodyTag. En esta sección veremos las variables scripting (scripting variables) y como utilizarlas en las etiquetas JSP.


1. Variables Scripting

Las variables scripting (en el contexto de páginas JSP), se refieren a las variables a nivel página declaradas por etiquetas JSP.

Por ejemplo:

<xgms:mitag2>
  <p>
    Fecha y hora obtenida de una etiqueta JSP:
    <%= fchra %>
  </p>
</xgms:mitag2>

El código anterior muestra una etiqueta JSP cuyo cuerpo contiene etiquetas HTML junto con una variable scripting: fchra. Como puede verse, estamos haciendo uso -dentro de un script- de una variable que fue definida en una etiqueta JSP. Esta variable podemos utilizarla en cualquier lugar dentro de la página.

La etiqueta que vamos a construir es una etiqueta sencilla llamada mitag2, la cual va a tener una sola variable scripting llamada fchra. La clase principal se va a llamar p131_ScripVars.

1.a. Construcción Paso a Paso

Lo primero es definir el paquete al que pertenece:

package pkgs.pq04;

Lo siguiente es importar las clases requeridas:

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

Luego hacemos la declaración de la clase. Esta clase implementa el interface Tag (escojemos implementar el interface Tag, y no el interface BodyTag, ya que el primero es más sencillo y cumple con lo que requerimos).

Nota:  En esta declaración hay que notar que vamos a usar la palabra reservada final. Ésta no se requiere para crear etiquetas JSP, sin embargo, una clase final es más eficiente que una no final.

public final class p131_ScripVars implements Tag
{

Declaramos la única variable a nivel clase para nuestra clase Java:

  private PageContext pc = null;

Y tenemos que implementar todos los seis métodos del interface Tag:

  1. setPageContext( PageContext p )
  2. setParent( Tag t )
  3. getParent()
  4. doStartTag()
  5. doEndTag()
  6. release()

El método setPageContext() es bastante sencillo, simplemente inicializa la variable privada con el objeto PageContext enviado.

El objeto PageContext está provisto por la etiqueta JSP y este método es el primero método llamado por la página JSP, por lo que el objeto PageContext queda disponible para los siguientes métodos:

  public void setPageContext( PageContext p )
  {
    pc = p;
  }

Los métodos setParent() y getParent() se utilizan para definir y obtener la referencia a la etiqueta parent (padre). Una etiqueta padre es una etiqueta JSP que encierra (o contiene) a la etiqueta actual. Debido a que en la clase que vamos a construir, no hay ninguna etiqueta padre conteniéndola, estos métodos no nos preocupan mayormente, por lo que implementamos sólo el mínimo:

  public void setParent( Tag t ) {}

  public Tag getParent() { return null; }

El método doStartTag() es un método realmente útil. Este método es invocado cuando el objeto PageContext y la etiqueta parent han sido definidos. Puesto que el objetivo de esta sección es la declaración de variables scripting desde una etiqueta JSP, declararemos una variable scripting llamada fchra.

Para ello, crearemos una instancia del objeto Calendar y utilizaremos el método getTime() para obtener un objeto Date. Invocar el método toString() del objeto Date nos regresará la fecha y hora actuales, las cuales serán el valor de nuestra variable scripting fchra.

Para que nuestra variable scripting quede disponible para la página JSP, tenemos que hacer uso del método setAttribute() del objeto PageContext. Puesto que ya disponemos de una referencia al objeto PageContext para la página JSP actual, utilizaremos su método setAttribute() para definir el valor de la variable fchra.

Una vez hecho eso, regresaremos la constante EVAL_BODY_INCLUDE para indicarle a la página JSP que debe mostrar el contenido del cuerpo de la etiqueta JSP.

Nota:  Otro posible valor que puede regresarse, es SKIP_BODY, que hace que la página JSP ignore el contenido del cuerpo de la etiqueta (el código presente entre las etiquetas de apertura y cierre), esto es, el contenido del cuerpo no será mostrado al usuario.

  public int doStartTag() throws JspException
  {
    Calendar cal = Calendar.getInstance();

    pc.setAttribute( "fchra", cal.getTime().toString() );

    return EVAL_BODY_INCLUDE;
  }

Nota:  Con referencia a la sección anterior, podemos ver que hasta este punto, lo único que ha cambiado es que para declarar variables scripting en una etiqueta JSP es haber colocado la siguiente línea en el método doStartTag() de nuestra clase principal:

  pc.setAttribute( "fchra", cal.getTime().toString() );

El siguiente método a implementar del interface Tag es el método doEndTag(). En nuestro caso, no hay mucho por hacer en él, así que simplemente regresamos la constante EVAL_PAGE, para indicarle al servidor de aplicaciones que continue evaluando la página JSP.

Nota:  Otro posible valor es SKIP_PAGE, el cual ocasiona que se ignore el procesamiento del resto de la página JSP.

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

Y por último viene el método release(). Lo único que hacemos en él es liberar recursos, así que liberamos la referencia al objeto PageContext.

  public void release()
  {
    pc = null;
  }

Para este ejercicio vamos a crear un nuevo paquete. Bajo dir_code/src/pkgs creamos el directorio pq04:


  D:\Dev
     |
     +-- curso_jsp
         |
         +-- src
             |
             +-- pkgs
                 :
                 |
                 +-- pq04

El código completo para esta clase es el siguiente:

package pkgs.pq04;

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

public final class p131_ScripVars implements Tag
{
  private PageContext pc = null;

  public void setPageContext( PageContext p )
  {
    pc = p;
  }

  public void setParent( Tag t ) {}

  public Tag getParent() { return null; }

  public int doStartTag() throws JspException
  {
    Calendar cal = Calendar.getInstance();

    pc.setAttribute( "fchra", cal.getTime().toString() );

    return EVAL_BODY_INCLUDE;
  }

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

  public void release()
  {
    pc = null;
  }
}

• Archivo: p131_ScripVars.java

Salvamos el código en dir_code/src/pkgs/pq04.

2. La Clase TagExtraInfo

Lo último por hacer para declarar variables scripting desde una etiqueta JSP es crear una nueva clase Java que extienda la clase TagExtraInfo y que sobreescriba su método getVariableInfo().

La clase TagExtraInfo (como el nombre lo sugiere), es una clase de información adicional que es requerida al declarar variables scripting desde etiquetas JSP.

La siguiente clase que vamos a construir se va a llamar p132_InfoAdic.

2.a. Construcción Paso a Paso

Nuestra clase p132_InfoAdic va a extender la clase TagExtraInfo y va sobreescribir el método getVariableInfo().

Del método getVariableInfo() regresaremos un vector de clases VariableInfo. Puesto que sólo tenemos una sola variable scripting (fchra) a declarar, entonces solo hay una clase VariableInfo regresada en el vector.

public VariableInfo[] getVariableInfo( TagData data )
{
  return new VariableInfo[]
  {
    new VariableInfo(
      "fchra", "java.lang.String", true, VariableInfo.NESTED )
  };
}

Como puede apreciarse, existen cuatro argumentos en el constructor VariableInfo:

  1. El nombre de la variable scripting que se desea hacer disponible a la página JSP: fchra.
  2. El tipo de variable: String.
  3. Un valor booleano indicando si la variable scripting requiere ser declarada: true.
  4. El argumento de alcance. Este argumento de alcance puede ser alguno de los siguientes:

    • VariableInfo.AT_BEGIN

      La variable es visible después de la etiqueta de apertura.

    • VariableInfo.AT_END

      La variable es visible después de la etiqueta de cierre.

    • VariableInfo.NESTED

      La variable es visible entre las etiquetas de apertura y cierre.

El código completo de la clase p132_InfoAdic es el siguiente:

package pkgs.pq04;

import javax.servlet.jsp.tagext.*;

public class p132_InfoAdic extends TagExtraInfo
{
  public VariableInfo[] getVariableInfo( TagData data )
  {
    return new VariableInfo[]
    {
      new VariableInfo(
        "fchra", "java.lang.String", true, VariableInfo.NESTED )
    };
  }
}

• Archivo: p132_InfoAdic.java

Salvamos la clase en dir_code/src/pkgs/pq04 y con esto terminamos nuestras clases Java requeridas.

3. El Descriptor de la Biblioteca de Etiquetas

En la sección anterior creamos un descriptor de biblioteca de etiquetas (MisTags.tld). Entonces, en lugar de crear un nuevo archivo TLD, actualizaremos el ya existente para incluir nuestra nueva etiqueta (ya que un archivo .TLD puede contener más de una definición de etiqueta).

Abrimos el archivo dir_code/web/WEB-INF/tlds/MisTags.tld y agregamos la definición de la nueva etiqueta:

<?xml version="1.0" encoding="utf-8" ?>

<!DOCTYPE taglib PUBLIC
  "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN"
  "http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd">

<taglib>
  <tlib-version>1.0</tlib-version>
  <jsp-version>1.2</jsp-version>
  <short-name>MisTags</short-name>
  <uri></uri>
  <description>Mi Biblioteca de Etiquetas</description>

  <tag>
    <name>mitag1</name>
    <tag-class>pkgs.pq03.p121_TagSimple</tag-class>
    <body-content>empty</body-content>
    <description>Mi primer etiqueta JSP</description>

    <attribute>
      <name>nombre</name>
      <required>false</required>
    </attribute>
  </tag>

  <tag>
    <name>mitag2</name>
    <tag-class>pkgs.pq04.p131_ScripVars</tag-class>
    <tei-class>pkgs.pq04.p132_InfoAdic</tei-class>
    <body-content>JSP</body-content>
    <description>Mi segunda etiqueta JSP</description>
  </tag>
</taglib>

• Archivo: MisTags.tld

Como puede apreciarse, en la definición de mitag2 aparece la etiqueta <tei-class />. Esta etiqueta es requerida al declarar variables scripting y define la subclase de javax.servlet.jsp.tagext.TagExtraInfo implementada, esto es, contiene la dirección completa a la clase que extiende la clase TagExtraInfo (nuestra clase p132_InfoAdic).

4. La Página JSP

Para la página JSP que va a utilizar esta nueva clase etiqueta JSP, usamos (como ya vimos antes) la directiva JSP taglib para importar el archivo de biblioteca de etiquetas (MisTags.tld) a la página. El valor del atributo uri es la dirección al archivo TLD, y el valor del atributo prefix es xgms (puede ser lo que uno desee):

<%@ taglib uri="WEB-INF/tlds/MisTags.tld" prefix="xgms" %>

Escribimos algo de texto HTML entre las etiquetas xgms:mitag2 y también escribimos el valor de la variable scripting fchra:

<xgms:mitag2>
  <p>
    Fecha y hora obtenida de una etiqueta JSP:
    <%= fchra %>
  </p>
</xgms:mitag2>

Nota:  Como puede verse, no se ha declarado ni inicializado la variable scripting fchra en la página! La declaración e inicialización la realizó la etiqueta JSP (y que también le asignó como valor, la fecha y hora actual).

El código completo de la página JSP p133_ScripVars, es el siguiente:

<html>

<head>
<title>
Variable Scripting
</title>
</head>

<body bgcolor="#ffeada">

<%@ taglib uri="WEB-INF/tlds/MisTags.tld" prefix="xgms" %>

<xgms:mitag2>
  <p>
  Fecha y hora del servidor (obtenida de una etiqueta JSP):
  <%= fchra %>
  </p>
</xgms:mitag2>

</body>
</html>

• Archivo: p133_ScripVars.jsp

Salvamos la página en dir_code/web, ejecutamos el Ant y la accesamos con el URL: http://localhost/curso/p133_ScripVars.jsp.

En resumen, vimos que las variables scripting son variables a nivel página que se declaran e instancian en etiquetas JSP.