Llamar a métodos JavaBean desde páginas JSP 2.0

La nueva versión de JavaServer Pages (JSP) incorpora el lenguaje de expresión (EL) introducido por JSP Standard Tag Library (JSTL) para permitir que los diseñadores web produzcan páginas JSP sin script que no contienen código Java. Dado que JSP 2.0 proporciona compatibilidad con versiones anteriores de JSP 1.x, aún puede incluir fragmentos de Java en sus páginas, pero los controladores de etiquetas y los componentes JavaBean son lugares mucho mejores para la funcionalidad basada en Java.

JSP 2.0 proporciona nuevas funciones para los controladores de etiquetas, como atributos dinámicos, el Protocolo de invocación simple y .tagarchivos. Todavía utiliza las acciones estándar JSP 1.0 antiguas para crear instancias de JavaBean y establecer sus propiedades, pero ahora puede acceder a las propiedades del bean, los parámetros de solicitud y los atributos / variables JSP con el nuevo lenguaje de expresión.

Todas esas mejoras de la tecnología JSP le permiten lograr el objetivo de separar el marcado JSP / HTML del código Java. Sin embargo, falta una cosa. JSP 2.0 no tiene sintaxis para llamar a un método JavaBean público no estático desde una página JSP sin script. Este artículo resuelve ese problema al proporcionar una etiqueta simple JSP 2.0 con atributos dinámicos.

Nota: Puede descargar el código fuente de este artículo desde Recursos.

Se necesita lenguaje de expresión

Suponga que tiene una java.util.Listinstancia que debe presentar como una lista HTML. Aquí hay una solución rápida basada en JSP 1.x:

   

Las aplicaciones Web existentes basadas en JSP consisten en código Java mezclado con marcado HTML como el fragmento de código anterior. Mantener cientos de páginas como esa puede ser una pesadilla si tiene equipos separados de desarrollo de Java y diseño web. La solución es mover el código Java a bibliotecas de etiquetas para que los desarrolladores puedan hacer su trabajo sin pegar código Java dentro de las páginas web y los diseñadores puedan editar sus páginas web sin preocuparse por romper el código Java.

Sin embargo, JSP 1.x tiene varios problemas que no le permiten desarrollar fácilmente páginas JSP sin script. Hasta hace poco, no existía ningún método estándar para acceder a objetos Java desde una página JSP sin utilizar código Java. Además, la codificación de clases de controladores de etiquetas no fue tan simple como podría haber sido.

Las siguientes líneas de código se basan en JSTL 1.0, que se puede utilizar con JSP 1.2. La etiqueta itera sobre los elementos de lo dado listy exporta la elemvariable para cada elemento. En lugar de declararse elemcomo una variable local, la etiqueta crea un atributo de página con pageContext.setAttribute(). El valor de este atributo se imprime con la etiqueta de JSTL :

   

JSTL proporciona etiquetas estándar para procesar documentos XML y acceder a bases de datos relacionales junto con etiquetas de formato, etiquetas de internacionalización, etiquetas condicionales, etiquetas de iterador, etiquetas relacionadas con URL y otras etiquetas de uso general. JSTL ha resuelto muchos de los problemas de JSP 1.x con la ayuda de un lenguaje de expresión que le permite acceder a objetos Java desde páginas JSP sin usar código Java. Por ejemplo, en lugar de buscar un atributo o acceder a un parámetro de solicitud con:


  

ahora puede usar:

$ {a} $ {param.p} 

Puede acceder a los objetos de contexto de la página JSP, los atributos de página / solicitud / sesión / aplicación (también conocidos como variables JSP), propiedades de JavaBean, elementos de colección, parámetros de solicitud, parámetros de inicialización, cookies y encabezados HTTP.

Con JSP 1.2, el lenguaje de expresión está disponible solo para aplicaciones basadas en JSTL y bibliotecas de etiquetas. JSP 2.0 hace que EL esté disponible para todas las aplicaciones JSP y todas las bibliotecas de etiquetas (incluidos los antiguos taglibs diseñados para JSP 1.x). JSP 2.0 también simplifica el desarrollo de la biblioteca de etiquetas, como verá más adelante en este artículo.

Desde su primera versión, JSP ha proporcionado etiquetas estándar para usar JavaBeans en páginas JSP. Puede crear o buscar instancias de JavaBean con , y luego puede obtener y establecer sus propiedades con y . Con JSP 2.0, también puede obtener el valor de una propiedad con:

$ {bean.property} 

Además de las propiedades, los componentes JavaBean tienen métodos públicos que a menudo deben llamarse desde páginas JSP. El resto de este artículo presentará tres formas de llamar a métodos JavaBean sin usar código Java. Uno se basa en el soporte de JSP 2.0 para funciones, que son construcciones EL que le permiten llamar a los métodos estáticos de las clases Java. Otra solución utiliza etiquetas personalizadas que obtienen los parámetros del método como atributos de etiqueta. La tercera forma se basa en una etiqueta genérica que le permite llamar a cualquier método público de cualquier clase JavaBean desde una página JSP.

Funciones de uso

El JSTL 1.0 EL inicial carecía de soporte para funciones. JSP 2.0 EL le permite llamar al método estático público de una clase Java utilizando la siguiente sintaxis:

$ {prefijo: nombreMétodo (param1, param2, ...)} 

La función JSP debe declararse en un descriptor de biblioteca de etiquetas (TLD):

 MethodName className returnType nombreMétodo (param1Type, param2Type, ...)   

La clase Java no tiene que implementar ninguna interfaz especial. El único requisito es hacer público y estático el método Java.

La clase TestBean

La TestBeanclase tiene un método público llamado testMethod(), que se llama desde las páginas JSP que se presentan en las siguientes secciones. El JavaBean tiene tres propiedades con nombre text, numbery logic. Estas propiedades son modificadas por testMethod(), que devuelve una cadena que contiene los valores modificados de las tres propiedades:

package com.devsphere.articles.calltag; TestBean de clase pública {texto de cadena privado; número int privado; lógica booleana privada; public TestBean () {text = ""; número = 0; lógica = falso; } public String getText () {texto de retorno; } public void setText (String text) {this.text = texto; } public int getNumber () {número de retorno; } public void setNumber (int número) {this.number = number; } public boolean getLogic () {lógica de retorno; } public void setLogic (lógica booleana) {this.logic = lógica; } public String testMethod (String text, int número, lógica booleana) setText (getText () + text); setNumber (getNumber () + número); setLogic (getLogic ()}

La clase TestFunction

Debido a que JSP 2.0 EL solo permite llamadas a métodos estáticos, TestBeanlos de testMethod()deben estar envueltos en un método estático. La TestFunctionclase proporciona un contenedor estático que toma los mismos parámetros que el método bean más el objeto bean cuyo método debe llamarse:

package com.devsphere.articles.calltag; clase pública TestFunction {String testMethod estático público (objeto TestBean, String text, int número, lógica booleana) {return object.testMethod (texto, número, lógica); }}

El TestFunction.classarchivo compilado debe colocarse junto con TestBean.classen el /WEB-INF/classesdirectorio de la aplicación web . Como alternativa, los dos archivos de clase se pueden empaquetar en un archivo jar y almacenar en /WEB-INF/lib.

La JSP TestFunction

Before calling the testMethod() function, the TestFunction.jsp page must specify the function's prefix and the library's Uniform Resource Identifier (URI):


  

The tag creates an instance of the TestBean class:


  

The testMethod() function is called twice. The first call gets some constant parameters, while the second call gets the values of the bean properties as parameters:

  ${tf:testMethod(obj, "abc", 123, true)} 
   
${tf:testMethod(obj, obj.text, obj.number, obj.logic)}

The TestFunction.jsp page produces the following HTML output:

  abc 123 true 
   
abcabc 246 true

The TestFunction TLD

As mentioned earlier, the JSP function must be declared in a tag library descriptor. The TestFunction.tld file defines some version number, the tf short name used in JSP pages as prefix for testMethod(), the library's URI, the function's name, the name of the class containing the static method, and the method's signature. The URI doesn't have to point to an existing Web resource, but it must be unique. You may not use the same URI for two different tag libraries.

Here is the TestFunction.tld file's content:

  1.0 tf //devsphere.com/articles/calltag/TestFunction.tld  testMethod  com.devsphere.articles.calltag.TestFunction   java.lang.String testMethod( com.devsphere.articles.calltag.TestBean, java.lang.String, int, boolean)    

The TestFunction.tld file must be placed into the Web application's /WEB-INF directory. The same directory also contains the web.xml application descriptor, which declares the library within a element. The URI that identifies the library in JSP pages and the TLD file's location are specified within two separate XML elements, and :

  //devsphere.com/articles/calltag/TestFunction.tld   /WEB-INF/TestFunction.tld   

Use custom tags

Tag libraries were introduced by JSP 1.1, which defined the Tag and BodyTag interfaces. JSP 1.2 added IterationTag and support for catching exceptions. These interfaces have handler methods such as doStartTag(), doInitBody(), doAfterBody(), and doEndTag(). Once you understand how these methods should be implemented, it's easy to build tag libraries. However, many developers viewed JSP 1.x's tag-handling mechanism as unnecessarily complex.

JSP 2.0 introduced a much simpler tag-handling protocol. If you extend the SimpleTagSupport class, you just have to implement the doTag() method for handling a JSP tag.

The TestMethodTag class

The TestMethodTag.jsp page calls the testMethod() JavaBean method using the following syntax:


  

When the application server translates the JSP page into a servlet, the above tag is replaced with a Java code fragment that calls the methods of a TestMethodTag instance created for handling the tag.

The tag handler extends the JSP 2.0 API's SimpleTagSupport class and defines one field for each attribute. These fields will maintain the tag attributes' values:

package com.devsphere.articles.calltag; import javax.servlet.jsp.JspException; import javax.servlet.jsp.JspWriter; import javax.servlet.jsp.tagext.SimpleTagSupport; import java.io.IOException; public class TestMethodTag extends SimpleTagSupport { private TestBean object; private String text; private int number; private boolean logic; 

For each tag attribute, there must be a set method, which gets the attribute value and stores it in a field so that the tag handler can use it later:

 public void setObject(TestBean object) { this.object = object; } public void setText(String text) { this.text = text; } public void setNumber(int number) { this.number = number; } public void setLogic(boolean logic) { this.logic = logic; } 

After setting the tag handler's attributes, the Java fragment (resulting from the JSP tag) invokes the tag handler's doTag() method, which calls the bean method. The doTag() method prints the string value returned by testMethod(). Therefore, the JSP output contains the returned value:

public void doTag () lanza JspException, IOException {String ret = object.testMethod (texto, número, lógica); JspWriter out = getJspContext (). GetOut (); out.println (ret); }}

La clase TestMethodTag2

Suponga que desea utilizar el valor devuelto por el método bean en una JSP. Por ejemplo, puede que tenga que pasarlo como valor de atributo a otra etiqueta. O puede que desee controlar su salida en la página JSP:

 ... $ {ret} ...