Uso de javabeans en JavaServer Pages

(Enero de 2005)

Los JavaBeans

En otro capítulo hemos visto lo que es un JavaBean. Existen diferentes tipos de JavaBean, la primera especificación (JavaBean gráfico) hacía referencia a componentes reusables para la construcción de interfaces gráficos de aplicaciones y applets. En la arquitectura J2EE este tipo de JavaBean no tiene sentido (por ahora) dentro de la capa Web (Servlets/JSP).

Pero existen otros tipos de JavaBeans que representan las entidades y reglas del negocio. No hay que verlas como un oscuro misterio de la tecnología J2EE, simplemente son clases Java reutilizables que representan elementos del dominio.

JavaBeans en JSP

Para instanciar las clases del API de Java no hay más que utilizar el viejo operador new. Pero las clases que representan entidades y reglas de negocio se llaman JavaBeans y exigen unas etiquetas específicas:

<jsp:usebean id="id_del_objeto" scope="page | request | session | application"  class="paquete...subpaquete.clase.class" beanName="nombre_del_bean"/>

El id es un nombre identificativo, seleccionado por el programador. Además debemos declarar su alcance o ámbito (scope). Un alcance "request" implica que el bean es accesible hasta otra JSP que haya sido invocada por medio de jsp:forwar o jsp:include. El beanName es opcional, sigue la lógica Java de paquete.subpaquete y se utiliza si se usa el método instantiate() de java.beans.Beans. En nuestro ejemplo:


	<jsp:useBean id="general" scope="page" class="docen_jsp.persona" />

De esta sencilla línea se puede deducir que al menos debemos definir en el JavaBean el constructor vacío, que es el que utiliza el motor JSP en la creación del objeto.

Existe una segunda sintaxis:

<jsp:usebean id="id_del_objeto" scope="page | request | session | application"  class="paquete...subpaquete.clase.class" beanName="nombre_del_bean">
Instrucciones
</jsp:useBean>

En este caso se ejecutan las instrucciones si el bean es instanciado. Dichas instrucciones pueden ser cualquier contenido JSP, aunque normalmente consiste en Scriptlets y acciones setProperty.

JavaBean de ejemplo

Los métodos setXXX() y getXXX() son puramente convencionales, podríamos haberlos llamado defXXX() y obtXXX(), sin embargo es conveniente usar los métodos setXXX() y getXXX() para propiciar la interoperabilidad e integración con software de otros fabricante. Además esto facilita el uso de acciones setProperty y getProperty, como luego veremos. En nuestro caso hemos puesto el bean en WEB-INF/classes:


public class persona {
   private String nombre;
   private int edad;

   public persona() { }
   public persona( String nombre, int edad ) {
      this.nombre = nombre;
      this.edad = edad;
   }
   public String getNombre() {              return nombre; }
   public int getEdad() {                   return edad; }
   public void setNombre( String nombre ) { this.nombre = nombre; }
   public void setEdad( int edad ) {        this.edad = edad; }
}

Aunque no ha sido necesario en este ejemplo, los JavaBean deben ser serializables (o heredar de una clase serializables), si es que queremos usar la serialización de objetos.

La primera página

La página es sencilla, instancia la clase en la línea jsp:usebean y luego la utiliza


	<html>
	...

		<jsp:useBean id="general" scope="page" class="docen_jsp.persona" />
		<%
			general.setNombre( "Fernando Gonzalez de Cordoba");
			general.setEdad( 37 );
		%>
	<p>Hemos creado una instancia del JavaBean. La clase se llama 
	<%=general.getClass().getName()%>.
	El nombre de la instancia es <%=general.getNombre()%> y la edad 
	es <%=general.getEdad()%> años.</p>
	...

Uso de setProperty y getProperty

En el ejemplo anterior se podían definir y obtener valores de atributos. Es un primer paso, pero tiene el inconveniente de tener que utilizar scriptlets para definir valores mediante setXXX(). A continuación veremos una forma más sencilla de realizar el mismo trabajo:  jsp:setProperty se usa en conjunción con jsp:useBean para definir valores de propiedades. Las etiquetas jsp:setProperty y jsp:getProperty nos evitan los scriptlets y se encargan de invocar a los métodos setXXX() y getXXX() del JavaBean.


	<jsp:setProperty name="id_del_objeto" property="nombre_propiedad"|"*"
		param="nombre_parametro_de_request" | value="valor" />

Esta acción puede aplicarse a una propiedad:


<jsp:setProperty name="general" property="nombre" value="<%=tuNombre%>" />

O a todas aquellas propiedades cuyo nombre coincide con parámetros de la petición (request), es decir, selecciona los parámetros que coinciden en nombre con las propiedades y copia los valores en sus correspondientes propiedades:


<jsp:setProperty name="general" property="*" />

Si queremos solamente extraer el valor de un parámetro (en el siguiente ejemplo es 'identificacion') y copiarlo a un atributo ('nombre'):


<jsp:setProperty name="general" property="nombre" param="identificacion" />

Con value podemos especificar un valor para la propiedad, pero esta etiqueta es incompatible con param.

En el siguiente ejemplo se obtiene el nombre de un formulario mediante request.getParameter() y se almacena en el Bean:


<%! String tuNombre; %>
<% tuNombre = request.getParameter( "nombre" ); %>
<jsp:setProperty name="general" property="nombre" value="<%=tuNombre%>" />

Como ya hemos visto, esto se puede hacer de forma más breve:


<jsp:setProperty name="general" property="nombre" param="nombre" />

Incluso se puede hacer durante la instanciación:


<jsp:useBean id="general" scope="page" class="docen_jsp.persona">
	<jsp:setProperty name="general" property="*" />
</jsp:useBean>

El ejemplo con getProperty():


Nombre del bean: <jsp:getProperty name="general" property="nombre" />

Evitando malentendidos

En ocasiones se cree que setProperty o getProperty pueden funcionar correctamente porque existen sus correspondientes atributos de clase bean. Esto no es cierto, funcionan porque existen sus correspondientes métodos getXXX() y setXXXX() en la clase bean. En el siguiente ejemplo los métodos getTipo() y getEsJoven() no tienen su correspondiente atributo de clase (simplemente porque en este caso no es necesario):


package paq_06_useBean_param;

public class Personaje {
	   private String nombre;
	   private int edad;

	   public Personaje() { }
	   public Personaje( String nombre, int edad ) {
	      this.nombre = nombre;
	      this.edad = edad;
	   }
	   public String getNombre() {              return nombre; }
	   public int getEdad() {                   return edad; }
	   public void setNombre( String nombre ) { this.nombre = nombre; }
	   public void setEdad( int edad ) {        this.edad = edad; }
	   public String getTipo() {
		   if (edad  < 40)
			   return "joven";
		   return "no joven";
	   }
	   public boolean getEsJoven() {
		   if (edad  < 40)
			   return true;
		   return false;
	   }
}

La página JSP recibe el nombre y la edad del personaje por medio de parámetros de la petición. Utiliza las propiedades 'tipo' y 'esJoven':


<jsp:useBean id="cientifico" scope="request" class="paq_06_useBean_param.Personaje">
	<jsp:setProperty name="cientifico" property="*"/>
</jsp:useBean>

<html>
  <head>
    <title>jsp:useBean</title>
  </head>
  <body>
    <h1>Uso de jsp:useBean coordinado con parámetros de la petición</h1>
	<p>El científico es <jsp:getProperty name="cientifico" property="nombre"/>. Su edad es 
	<jsp:getProperty name="cientifico" property="edad"/></p>.
	<p>A continuación usamos getProperty, sin que haya una propiedad de clase Bean 
	para soportar los métodos getTipo() y getEsJoven():</p>
	<ul>
		<li>Tipo: <jsp:getProperty name="cientifico" property="tipo"/></li>
		<li>¿Joven?: <jsp:getProperty name="cientifico" property="esJoven"/></li>
	</ul>

  </body>
</html>
Enlace al ejemplo. Le pasamos a la JSP los parámetros nombre y edad, para que instancie el JavaBean 'Personaje'.


Volver al índice